Skip to content

Commit

Permalink
fix(ewt-582): fixed OneOfJsonConverter for json deserialisation with …
Browse files Browse the repository at this point in the history
…both status and type fields (#201)
  • Loading branch information
tl-mauro-franchi authored Jun 18, 2024
2 parents 30f0295 + 42638b4 commit 433ecea
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 29 deletions.
38 changes: 23 additions & 15 deletions src/TrueLayer/Serialization/OneOfJsonConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,30 +27,38 @@ public OneOfJsonConverter(OneOfTypeDescriptor descriptor, string discriminatorFi

var doc = JsonDocument.ParseValue(ref reader);

if (!doc.RootElement.TryGetProperty(_discriminatorFieldName, out var discriminator)
&& !doc.RootElement.TryGetProperty("status", out discriminator)) // Hack until payment response uses a `type` field
if (doc.RootElement.TryGetProperty(_discriminatorFieldName, out var discriminator)
&& (_descriptor.TypeFactories.TryGetValue(discriminator.GetString()!, out var typeFactory)))
{
throw new JsonException();
return InokeDiscriminatorFactory(options, readerClone, typeFactory);
}

if (_descriptor.TypeFactories.TryGetValue(discriminator.GetString()!, out var typeFactory))
// Fallback to status field
if (doc.RootElement.TryGetProperty("status", out discriminator)
&& (_descriptor.TypeFactories.TryGetValue(discriminator.GetString()!, out typeFactory)))
{
object? deserializedObject = JsonSerializer.Deserialize(ref readerClone, typeFactory.FieldType, options);
return InokeDiscriminatorFactory(options, readerClone, typeFactory);
}

throw new JsonException($"Unknown discriminator {discriminator}");
}

if (deserializedObject is null)
{
throw new ArgumentNullException(nameof(deserializedObject));
}
private static T? InokeDiscriminatorFactory(JsonSerializerOptions options, Utf8JsonReader readerClone,
(Type FieldType, Delegate Factory) typeFactory)
{
object? deserializedObject = JsonSerializer.Deserialize(ref readerClone, typeFactory.FieldType, options);

if (typeFactory.Factory is Func<object, T> factory)
{
return factory.Invoke(deserializedObject);
}
if (deserializedObject is null)
{
throw new ArgumentNullException(nameof(deserializedObject));
}

throw new JsonException($"Unable to execute OneOf factory for type {typeFactory.FieldType.FullName}");
if (typeFactory.Factory is Func<object, T> factory)
{
return factory.Invoke(deserializedObject);
}

throw new JsonException($"Unknown discriminator {discriminator}");
throw new JsonException($"Unable to execute OneOf factory for type {typeFactory.FieldType.FullName}");
}

public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
Expand Down
22 changes: 8 additions & 14 deletions test/TrueLayer.AcceptanceTests/ApiTestFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,14 @@ public ApiTestFixture()
IConfiguration configuration = LoadConfiguration();

ServiceProvider = new ServiceCollection()
.AddTrueLayer(configuration)
.AddSingleton<IConfigureOptions<TrueLayerOptions>, ConfigureTrueLayerOptions>()
.AddTrueLayer(configuration, options =>
{
string privateKey = File.ReadAllText("ec512-private-key.pem");
if (options.Payments?.SigningKey != null)
{
options.Payments.SigningKey.PrivateKey = privateKey;
}
})
.BuildServiceProvider();

Client = ServiceProvider.GetRequiredService<ITrueLayerClient>();
Expand All @@ -32,16 +38,4 @@ private static IConfiguration LoadConfiguration()
.AddEnvironmentVariables()
.Build();
}

public class ConfigureTrueLayerOptions : IConfigureOptions<TrueLayerOptions>
{
public void Configure(TrueLayerOptions options)
{
string privateKey = File.ReadAllText("ec512-private-key.pem");
if (options.Payments?.SigningKey != null)
{
options.Payments.SigningKey.PrivateKey = privateKey;
}
}
}
}

0 comments on commit 433ecea

Please sign in to comment.