Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test operation with enum member #30

Open
MateuszGert opened this issue Jun 26, 2024 · 3 comments
Open

Test operation with enum member #30

MateuszGert opened this issue Jun 26, 2024 · 3 comments
Labels
question Further information is requested

Comments

@MateuszGert
Copy link

I have model class with enum member annotated by LowerCaseJsonStringEnumConverter.
[JsonPropertyName("urlBuilder")] [JsonConverter(typeof(LowerCaseJsonStringEnumConverter))] [Required] public UrlBuilderMode? UrlBuilder { set; get; }
During executing test operation I got JsonPatchTestOperationException.

The problem is in controller I have JsonPatchDocument where value is string.
In TObj there is UrlBuilderMode type.
If I replace value from string to UrlBuilderMode then everything works.
Solution for that is to deserialize to proper enum value (because TObj is tagged with JsonConverter) or to support in test function operation with value string with enum member.

@Havunen
Copy link
Owner

Havunen commented Jun 27, 2024

Can you provide full example what you mean, or a failing test case please

@Havunen Havunen added the question Further information is requested label Jun 27, 2024
@MateuszGert
Copy link
Author

Scenarios occurs when I have JsonPatchDocument in REST controller.

[TestCase]
public void TestOperationWithEnumTest()
{
    var patchDocument = JsonSerializer.Deserialize<JsonPatchDocument<WithEnumModel>>("[{\"op\": \"test\", \"path\": \"/EnumProperty\", \"value\": \"two\" }]")!;
    WithEnumModel target = new WithEnumModel()
    {
        EnumProperty = ValueEnum.Two
    };
    Assert.DoesNotThrow(() => patchDocument.ApplyTo(target));
}

[TestCase]
public void ReplaceOperationWithEnumTest()
{
    var patchDocument = JsonSerializer.Deserialize<JsonPatchDocument<WithEnumModel>>("[{\"op\": \"replace\", \"path\": \"/EnumProperty\", \"value\": \"two\" }]")!;
    WithEnumModel target = new WithEnumModel()
    {
        EnumProperty = ValueEnum.One
    };
    Assert.DoesNotThrow(() => patchDocument.ApplyTo(target));
    Assert.That(target, Has.Property(nameof(WithEnumModel.EnumProperty)).EqualTo(ValueEnum.Two));
}

[TestCase]
public void ReplaceWithoutDeserializationOperationWithEnumTest()
{
    var patchDocument = new JsonPatchDocument<WithEnumModel>();
    patchDocument.Operations.Add(new Operation<WithEnumModel>(op: "replace", path: "/EnumProperty", from: null, value: ValueEnum.Two ));
    WithEnumModel target = new WithEnumModel()
    {
        EnumProperty = ValueEnum.One
    };
    Assert.DoesNotThrow(() => patchDocument.ApplyTo(target));
    Assert.That(target, Has.Property(nameof(WithEnumModel.EnumProperty)).EqualTo(ValueEnum.Two));
}

[TestCase]
public void PatchSerializationTest()
{
    var patchDocument = new JsonPatchDocument<WithEnumModel>();
    patchDocument.Operations.Add(new Operation<WithEnumModel>(op: "replace", path: "/EnumProperty", from: null, value: ValueEnum.Two));
    string patchString = JsonSerializer.Serialize(patchDocument);
    JsonPatchDocument<WithEnumModel> recreated = JsonSerializer.Deserialize<JsonPatchDocument<WithEnumModel>>(patchString)!;
    Assert.That(recreated.Operations.Count, Is.EqualTo(patchDocument.Operations.Count));
    Assert.That(recreated.Operations[0].Path, Is.EqualTo(patchDocument.Operations[0].Path));
    Assert.That(recreated.Operations[0].Op, Is.EqualTo(patchDocument.Operations[0].Op));
    Assert.That(recreated.Operations[0].Value, Is.EqualTo(patchDocument.Operations[0].Value));
}

[TestCase]
public void PatchSerializationWithConverterTest()
{
    var patchDocument = new JsonPatchDocument<WithEnumModel>();
    patchDocument.Operations.Add(new Operation<WithEnumModel>(op: "replace", path: "/EnumProperty", from: null, value: ValueEnum.Two));
    var options = new JsonSerializerOptions();
    options.Converters.Add(new LowerCaseJsonStringEnumConverter());
    string patchString = JsonSerializer.Serialize(patchDocument, options);
    JsonPatchDocument<WithEnumModel> recreated = JsonSerializer.Deserialize<JsonPatchDocument<WithEnumModel>>(patchString, options)!;
    Assert.That(recreated.Operations.Count, Is.EqualTo(patchDocument.Operations.Count));
    Assert.That(recreated.Operations[0].Path, Is.EqualTo(patchDocument.Operations[0].Path));
    Assert.That(recreated.Operations[0].Op, Is.EqualTo(patchDocument.Operations[0].Op));
    Assert.That(recreated.Operations[0].Value, Is.EqualTo(patchDocument.Operations[0].Value));
}

public enum ValueEnum
{
    One,
    Two
}

public class WithEnumModel
{
    [JsonConverter(typeof(LowerCaseJsonStringEnumConverter))]
    public ValueEnum? EnumProperty
    {
        set;
        get;
    }
}

public class LowerCaseJsonStringEnumConverter : JsonStringEnumConverter
{
    public LowerCaseJsonStringEnumConverter()
        : base(namingPolicy: System.Text.Json.JsonNamingPolicy.CamelCase)
    {
    }
}

One issue is connected with non transient serialization<->deserialization.
I would expect that I have exception on serialization, but while enum serialization is supported, then deserialization should be supported too.

@Havunen
Copy link
Owner

Havunen commented Oct 18, 2024

related: #24

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants