/* SPDX-License-Identifier: Apache-2.0 * * The OpenSearch Contributors require contributions made to * this file be licensed under the Apache-2.0 license or a * compatible open source license. */ /* * Modifications Copyright OpenSearch Contributors. See * GitHub history for details. * * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Elasticsearch B.V. licenses this file to you under * the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using OpenSearch.OpenSearch.Xunit.XunitPlumbing; using OpenSearch.Net; using FluentAssertions; using OpenSearch.Client; using Tests.Core.Serialization; namespace Tests.Framework.SerializationTests { /// /// implementations do not use /// /// so keys are camel cased on serialization, in line with OSC conventions /// public class IsADictionarySerializationTests { protected object ExpectJson => new { key1 = "value1", key2 = "value2", }; [U] public void CanSerializeIsADictionary() { var isADictionary = new MyIsADictionary(new Dictionary { { "Key1", "value1" }, { "Key2", "value2" }, }); SerializationTestHelper.Object(isADictionary).RoundTrips(ExpectJson); } [U] public void SerializesIsADictionaryNullValues() { var isADictionary = new MyIsADictionary(new Dictionary { { "Key1", null }, { "Key2", "value2" }, }); var client = new OpenSearchClient(); client.RequestResponseSerializer.SerializeToString(isADictionary).Should().Be("{\"key1\":null,\"key2\":\"value2\"}"); } [U] public void SerializesIsADictionaryRespectsDefaultFieldNameInferrer() { var isADictionary = new MyIsADictionary(new Dictionary { { "Key1", "value1" } }); var client = new OpenSearchClient(new ConnectionSettings().DefaultFieldNameInferrer(f => f.ToUpperInvariant())); client.RequestResponseSerializer.SerializeToString(isADictionary).Should().Be("{\"KEY1\":\"value1\"}"); } private class MyIsADictionary : IsADictionaryBase { public MyIsADictionary(IDictionary backingDictionary) : base(backingDictionary) { } } } public class DictionarySerializationTests { protected object ExpectJson => new { Key1 = "value1", Key2 = "value2", }; [U] public void CanSerializeCustomGenericDictionary() { var dictionary = new MyGenericDictionary { { "Key1", "value1" }, { "Key2", "value2" }, }; SerializationTestHelper.Object(dictionary).RoundTrips(ExpectJson); } [U] public void CanSerializeGenericDictionary() { var dictionary = new Dictionary { { "Key1", "value1" }, { "Key2", "value2" }, }; SerializationTestHelper.Object(dictionary).RoundTrips(ExpectJson); } [U] public void CanSerializeIgnoresDefaultFieldNameInferrer() { var dictionary = new Dictionary { { "Key1", "value1" }, { "Key2", "value2" }, }; var client = new OpenSearchClient(new ConnectionSettings().DefaultFieldNameInferrer(f => f.ToUpperInvariant())); client.RequestResponseSerializer.SerializeToString(dictionary).Should().Be("{\"Key1\":\"value1\",\"Key2\":\"value2\"}"); } [U] public void CanSerializeGenericReadOnlyDictionary() { var dictionary = new ReadOnlyDictionary( new Dictionary { { "Key1", "value1" }, { "Key2", "value2" }, }); SerializationTestHelper.Object(dictionary).RoundTrips(ExpectJson); } [U] public void CanSerializeCustomGenericIDictionary() { var dictionary = new MyGenericIDictionary { { "Key1", "value1" }, { "Key2", "value2" }, }; SerializationTestHelper.Object(dictionary).RoundTrips(ExpectJson); } [U] public void CanSerializeCustomGenericIReadOnlyDictionary() { var dictionary = new MyGenericIReadOnlyDictionary(new Dictionary { { "Key1", "value1" }, { "Key2", "value2" }, }); SerializationTestHelper.Object(dictionary).RoundTrips(ExpectJson); } [U] public void CanSerializeCustomDictionary() { var hashTable = new MyDictionary { { "Key1", "value1" }, { "Key2", "value2" }, }; SerializationTestHelper.Object(hashTable).RoundTrips(ExpectJson); } [U] public void CanSerializeHashTable() { var hashTable = new Hashtable { { "Key1", "value1" }, { "Key2", "value2" }, }; SerializationTestHelper.Object(hashTable).RoundTrips(ExpectJson); } [U] public void DoesNotSerializeDictionaryNullValues() { var dictionary = new Dictionary { { "Key1", null }, { "Key2", "value2" }, }; SerializationTestHelper.Object(dictionary) .PreserveNull() .RoundTrips(new { Key1 = (object)null, Key2 = "value2" }); } [U] public void DoesSerializeIDictionaryNullValues() { IDictionary dictionary = new Dictionary { { "Key1", null }, { "Key2", "value2" }, }; SerializationTestHelper.Object(dictionary) .PreserveNull() .RoundTrips(new { Key1 = (object)null, Key2 = "value2" }); } [U] public void DoesSerializeReadOnlyDictionaryNullValues() { var dictionary = new ReadOnlyDictionary(new Dictionary { { "Key1", null }, { "Key2", "value2" }, }); SerializationTestHelper.Object(dictionary) .PreserveNull() .RoundTrips(new { Key1 = (object)null, Key2 = "value2" }); } [U] public void DoesSerializeIReadOnlyDictionaryNullValues() { IReadOnlyDictionary dictionary = new ReadOnlyDictionary(new Dictionary { { "Key1", null }, { "Key2", "value2" }, }); SerializationTestHelper.Object(dictionary) .PreserveNull() .RoundTrips(new { Key1 = (object)null, Key2 = "value2" }); } private class MyDictionary : IDictionary { private readonly IDictionary _dictionary = new Hashtable(); public int Count => _dictionary.Count; public bool IsFixedSize => _dictionary.IsFixedSize; public bool IsReadOnly => _dictionary.IsReadOnly; public bool IsSynchronized => _dictionary.IsSynchronized; public object this[object key] { get => _dictionary[key]; set => _dictionary[key] = value; } public ICollection Keys => _dictionary.Keys; public object SyncRoot => _dictionary.SyncRoot; public ICollection Values => _dictionary.Values; public void CopyTo(Array array, int index) => _dictionary.CopyTo(array, index); public void Add(object key, object value) => _dictionary.Add(key, value); public void Clear() => _dictionary.Clear(); public bool Contains(object key) => _dictionary.Contains(key); public IDictionaryEnumerator GetEnumerator() => _dictionary.GetEnumerator(); public void Remove(object key) => _dictionary.Remove(key); IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)_dictionary).GetEnumerator(); } private class MyGenericDictionary : Dictionary { } private class MyGenericIReadOnlyDictionary : IReadOnlyDictionary { private readonly IDictionary _backingDictionary; public MyGenericIReadOnlyDictionary(IDictionary dictionary) => _backingDictionary = dictionary ?? new Dictionary(); public int Count => _backingDictionary.Count; public object this[object key] => _backingDictionary[key]; public IEnumerable Keys => _backingDictionary.Keys; public IEnumerable Values => _backingDictionary.Values; IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); public IEnumerator> GetEnumerator() => _backingDictionary.GetEnumerator(); public bool ContainsKey(object key) => _backingDictionary.ContainsKey(key); public bool TryGetValue(object key, out object value) => _backingDictionary.TryGetValue(key, out value); } private class MyGenericIDictionary : IDictionary { private readonly IDictionary _backingDictionary = new Dictionary(); public int Count => _backingDictionary.Count; public bool IsReadOnly => _backingDictionary.IsReadOnly; public object this[object key] { get => _backingDictionary[key]; set => _backingDictionary[key] = value; } public ICollection Keys => _backingDictionary.Keys; public ICollection Values => _backingDictionary.Values; public void Add(KeyValuePair item) => _backingDictionary.Add(item); public void Clear() => _backingDictionary.Clear(); public bool Contains(KeyValuePair item) => _backingDictionary.Contains(item); public void CopyTo(KeyValuePair[] array, int arrayIndex) => _backingDictionary.CopyTo(array, arrayIndex); public bool Remove(KeyValuePair item) => _backingDictionary.Remove(item); public void Add(object key, object value) => _backingDictionary.Add(key, value); public bool ContainsKey(object key) => _backingDictionary.ContainsKey(key); public bool Remove(object key) => _backingDictionary.Remove(key); public bool TryGetValue(object key, out object value) => _backingDictionary.TryGetValue(key, out value); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); public IEnumerator> GetEnumerator() => _backingDictionary.GetEnumerator(); } } }