Fixes Sentry LIDARR-106 Fixes Sentry LIDARR-10Bpull/1689/head
parent
2a4b3d79b8
commit
0f5531af4d
@ -0,0 +1,47 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data.SQLite;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using NzbDrone.Core.Datastore.Converters;
|
||||||
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Test.Datastore.Converters
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class KeyValuePairConverterFixture : CoreTest<EmbeddedDocumentConverter<List<KeyValuePair<string, int>>>>
|
||||||
|
{
|
||||||
|
private SQLiteParameter _param;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_param = new SQLiteParameter();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_serialize_in_camel_case()
|
||||||
|
{
|
||||||
|
var items = new List<KeyValuePair<string, int>>
|
||||||
|
{
|
||||||
|
new KeyValuePair<string, int>("word", 1)
|
||||||
|
};
|
||||||
|
|
||||||
|
Subject.SetValue(_param, items);
|
||||||
|
|
||||||
|
var result = (string)_param.Value;
|
||||||
|
result.Should().Be(@"[
|
||||||
|
{
|
||||||
|
""key"": ""word"",
|
||||||
|
""value"": 1
|
||||||
|
}
|
||||||
|
]");
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase(@"[{""key"": ""deluxe"", ""value"": 10 }]")]
|
||||||
|
[TestCase(@"[{""Key"": ""deluxe"", ""Value"": 10 }]")]
|
||||||
|
public void should_deserialize_case_insensitive(string input)
|
||||||
|
{
|
||||||
|
Subject.Parse(input).Should().BeEquivalentTo(new List<KeyValuePair<string, int>> { new KeyValuePair<string, int>("deluxe", 10) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,149 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Converters
|
||||||
|
{
|
||||||
|
/* See https://github.com/dotnet/runtime/issues/1197
|
||||||
|
Can be removed once we switch to .NET 5
|
||||||
|
Based on https://github.com/layomia/dotnet_runtime/blob/master/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/KeyValuePairConverter.cs
|
||||||
|
and https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-converters-how-to
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class KeyValuePairConverter : JsonConverterFactory
|
||||||
|
{
|
||||||
|
public override bool CanConvert(Type typeToConvert)
|
||||||
|
{
|
||||||
|
if (!typeToConvert.IsGenericType)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeToConvert.GetGenericTypeDefinition() != typeof(KeyValuePair<,>))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override JsonConverter CreateConverter(
|
||||||
|
Type type,
|
||||||
|
JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
var keyType = type.GetGenericArguments()[0];
|
||||||
|
var valueType = type.GetGenericArguments()[1];
|
||||||
|
|
||||||
|
var converter = (JsonConverter)Activator.CreateInstance(
|
||||||
|
typeof(KeyValuePairConverterInner<,>).MakeGenericType(
|
||||||
|
new Type[] { keyType, valueType }),
|
||||||
|
BindingFlags.Instance | BindingFlags.Public,
|
||||||
|
binder: null,
|
||||||
|
args: null,
|
||||||
|
culture: null);
|
||||||
|
|
||||||
|
return converter;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class KeyValuePairConverterInner<TKey, TValue> :
|
||||||
|
JsonConverter<KeyValuePair<TKey, TValue>>
|
||||||
|
{
|
||||||
|
public KeyValuePairConverterInner()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override KeyValuePair<TKey, TValue> Read(
|
||||||
|
ref Utf8JsonReader reader,
|
||||||
|
Type typeToConvert,
|
||||||
|
JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
if (reader.TokenType != JsonTokenType.StartObject)
|
||||||
|
{
|
||||||
|
throw new JsonException();
|
||||||
|
}
|
||||||
|
|
||||||
|
TKey k = default;
|
||||||
|
var keySet = false;
|
||||||
|
|
||||||
|
TValue v = default;
|
||||||
|
var valueSet = false;
|
||||||
|
|
||||||
|
reader.Read();
|
||||||
|
|
||||||
|
// Get the first property.
|
||||||
|
if (reader.TokenType != JsonTokenType.PropertyName)
|
||||||
|
{
|
||||||
|
throw new JsonException();
|
||||||
|
}
|
||||||
|
|
||||||
|
var propertyName = reader.GetString();
|
||||||
|
if (string.Equals(propertyName, "Key", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
reader.Read();
|
||||||
|
k = JsonSerializer.Deserialize<TKey>(ref reader, options);
|
||||||
|
keySet = true;
|
||||||
|
}
|
||||||
|
else if (string.Equals(propertyName, "Value", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
reader.Read();
|
||||||
|
v = JsonSerializer.Deserialize<TValue>(ref reader, options);
|
||||||
|
valueSet = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new JsonException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the second property.
|
||||||
|
reader.Read();
|
||||||
|
if (reader.TokenType != JsonTokenType.PropertyName)
|
||||||
|
{
|
||||||
|
throw new JsonException();
|
||||||
|
}
|
||||||
|
|
||||||
|
propertyName = reader.GetString();
|
||||||
|
if (!keySet && string.Equals(propertyName, "Key", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
reader.Read();
|
||||||
|
k = JsonSerializer.Deserialize<TKey>(ref reader, options);
|
||||||
|
}
|
||||||
|
else if (!valueSet && string.Equals(propertyName, "Value", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
reader.Read();
|
||||||
|
v = JsonSerializer.Deserialize<TValue>(ref reader, options);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new JsonException();
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.Read();
|
||||||
|
|
||||||
|
if (reader.TokenType != JsonTokenType.EndObject)
|
||||||
|
{
|
||||||
|
throw new JsonException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new KeyValuePair<TKey, TValue>(k, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(
|
||||||
|
Utf8JsonWriter writer,
|
||||||
|
KeyValuePair<TKey, TValue> kvp,
|
||||||
|
JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
writer.WriteStartObject();
|
||||||
|
|
||||||
|
writer.WritePropertyName("key");
|
||||||
|
JsonSerializer.Serialize(writer, kvp.Key, options);
|
||||||
|
|
||||||
|
writer.WritePropertyName("value");
|
||||||
|
JsonSerializer.Serialize(writer, kvp.Value, options);
|
||||||
|
|
||||||
|
writer.WriteEndObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue