diff --git a/src/CommunityToolkit.Datasync.Client/Serialization/DateTimeConverter.cs b/src/CommunityToolkit.Datasync.Client/Serialization/DateTimeConverter.cs index 79165843..da03fb5e 100644 --- a/src/CommunityToolkit.Datasync.Client/Serialization/DateTimeConverter.cs +++ b/src/CommunityToolkit.Datasync.Client/Serialization/DateTimeConverter.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Globalization; using System.Text.Json; using System.Text.Json.Serialization; @@ -31,5 +32,5 @@ public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, Jso /// public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) - => writer.WriteStringValue(value.ToUniversalTime().ToString(format)); + => writer.WriteStringValue(value.ToUniversalTime().ToString(format, CultureInfo.InvariantCulture)); } diff --git a/src/CommunityToolkit.Datasync.Client/Serialization/DateTimeOffsetConverter.cs b/src/CommunityToolkit.Datasync.Client/Serialization/DateTimeOffsetConverter.cs index e5132446..7b25efeb 100644 --- a/src/CommunityToolkit.Datasync.Client/Serialization/DateTimeOffsetConverter.cs +++ b/src/CommunityToolkit.Datasync.Client/Serialization/DateTimeOffsetConverter.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Globalization; using System.Text.Json; using System.Text.Json.Serialization; @@ -31,5 +32,5 @@ public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConver /// public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options) - => writer.WriteStringValue(value.ToUniversalTime().UtcDateTime.ToString(format)); + => writer.WriteStringValue(value.ToUniversalTime().UtcDateTime.ToString(format, CultureInfo.InvariantCulture)); } diff --git a/src/CommunityToolkit.Datasync.Client/Serialization/TimeOnlyConverter.cs b/src/CommunityToolkit.Datasync.Client/Serialization/TimeOnlyConverter.cs index 6dafd78b..22a1396d 100644 --- a/src/CommunityToolkit.Datasync.Client/Serialization/TimeOnlyConverter.cs +++ b/src/CommunityToolkit.Datasync.Client/Serialization/TimeOnlyConverter.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Globalization; using System.Text.Json; using System.Text.Json.Serialization; @@ -31,5 +32,5 @@ public override TimeOnly Read(ref Utf8JsonReader reader, Type typeToConvert, Jso /// public override void Write(Utf8JsonWriter writer, TimeOnly value, JsonSerializerOptions options) - => writer.WriteStringValue(value.ToString(format)); + => writer.WriteStringValue(value.ToString(format, CultureInfo.InvariantCulture)); } diff --git a/src/CommunityToolkit.Datasync.Server.Abstractions/Json/DateTimeConverter.cs b/src/CommunityToolkit.Datasync.Server.Abstractions/Json/DateTimeConverter.cs index a33327a1..a61d41e7 100644 --- a/src/CommunityToolkit.Datasync.Server.Abstractions/Json/DateTimeConverter.cs +++ b/src/CommunityToolkit.Datasync.Server.Abstractions/Json/DateTimeConverter.cs @@ -15,7 +15,6 @@ namespace CommunityToolkit.Datasync.Server.Abstractions.Json; public class DateTimeConverter : JsonConverter { private const string format = "yyyy-MM-dd'T'HH:mm:ss.fffK"; - private static readonly CultureInfo culture = new("en-US"); /// public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) @@ -23,5 +22,5 @@ public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, Jso /// public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) - => writer.WriteStringValue(value.ToUniversalTime().ToString(format, culture)); + => writer.WriteStringValue(value.ToUniversalTime().ToString(format, CultureInfo.InvariantCulture)); } diff --git a/src/CommunityToolkit.Datasync.Server.Abstractions/Json/DateTimeOffsetConverter.cs b/src/CommunityToolkit.Datasync.Server.Abstractions/Json/DateTimeOffsetConverter.cs index 08ea9564..5bf210bd 100644 --- a/src/CommunityToolkit.Datasync.Server.Abstractions/Json/DateTimeOffsetConverter.cs +++ b/src/CommunityToolkit.Datasync.Server.Abstractions/Json/DateTimeOffsetConverter.cs @@ -15,7 +15,6 @@ namespace CommunityToolkit.Datasync.Server.Abstractions.Json; public class DateTimeOffsetConverter : JsonConverter { private const string format = "yyyy-MM-dd'T'HH:mm:ss.fffK"; - private static readonly CultureInfo culture = new("en-US"); /// public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) @@ -23,5 +22,5 @@ public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConver /// public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options) - => writer.WriteStringValue(value.ToUniversalTime().UtcDateTime.ToString(format, culture)); + => writer.WriteStringValue(value.ToUniversalTime().UtcDateTime.ToString(format, CultureInfo.InvariantCulture)); } diff --git a/src/CommunityToolkit.Datasync.Server.Abstractions/Json/JsonExtensions.cs b/src/CommunityToolkit.Datasync.Server.Abstractions/Json/JsonExtensions.cs index abc33dd8..8b96f82d 100644 --- a/src/CommunityToolkit.Datasync.Server.Abstractions/Json/JsonExtensions.cs +++ b/src/CommunityToolkit.Datasync.Server.Abstractions/Json/JsonExtensions.cs @@ -17,7 +17,7 @@ internal static class JsonExtensions /// The to assert. /// The expected of the current token. /// The current token did not match the . - public static void Expect(in this Utf8JsonReader reader, JsonTokenType expectedTokenType) + public static void Expect(this Utf8JsonReader reader, JsonTokenType expectedTokenType) { if (reader.TokenType != expectedTokenType) { diff --git a/src/CommunityToolkit.Datasync.Server.Abstractions/Json/TimeOnlyConverter.cs b/src/CommunityToolkit.Datasync.Server.Abstractions/Json/TimeOnlyConverter.cs index 2124e666..b7218782 100644 --- a/src/CommunityToolkit.Datasync.Server.Abstractions/Json/TimeOnlyConverter.cs +++ b/src/CommunityToolkit.Datasync.Server.Abstractions/Json/TimeOnlyConverter.cs @@ -15,7 +15,6 @@ namespace CommunityToolkit.Datasync.Server.Abstractions.Json; public class TimeOnlyConverter : JsonConverter { private const string format = "HH:mm:ss.fff"; - private static readonly CultureInfo culture = new("en-US"); /// public override TimeOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) @@ -23,5 +22,5 @@ public override TimeOnly Read(ref Utf8JsonReader reader, Type typeToConvert, Jso /// public override void Write(Utf8JsonWriter writer, TimeOnly value, JsonSerializerOptions options) - => writer.WriteStringValue(value.ToString(format, culture)); + => writer.WriteStringValue(value.ToString(format, CultureInfo.InvariantCulture)); } diff --git a/src/CommunityToolkit.Datasync.Server.Swashbuckle/DatasyncDocumentFilter.cs b/src/CommunityToolkit.Datasync.Server.Swashbuckle/DatasyncDocumentFilter.cs index f24193de..0d4f9561 100644 --- a/src/CommunityToolkit.Datasync.Server.Swashbuckle/DatasyncDocumentFilter.cs +++ b/src/CommunityToolkit.Datasync.Server.Swashbuckle/DatasyncDocumentFilter.cs @@ -112,6 +112,7 @@ internal void ProcessController(Type entityType, string routePath, OpenApiDocume case OpType.Create: // Request Edits operation.Value.AddConditionalHeader(true); + operation.Value.AddRequestWithContent(context.SchemaRepository.Schemas[entityType.Name]); // Response Edits operation.Value.AddResponseWithContent("201", "Created", context.SchemaRepository.Schemas[entityType.Name]); @@ -152,6 +153,7 @@ internal void ProcessController(Type entityType, string routePath, OpenApiDocume case OpType.Replace: // Request Edits operation.Value.AddConditionalHeader(); + operation.Value.AddRequestWithContent(context.SchemaRepository.Schemas[entityType.Name]); // Response Edits operation.Value.AddResponseWithContent("200", "OK", context.SchemaRepository.Schemas[entityType.Name]); diff --git a/src/CommunityToolkit.Datasync.Server.Swashbuckle/DatasyncOperationExtensions.cs b/src/CommunityToolkit.Datasync.Server.Swashbuckle/DatasyncOperationExtensions.cs index e6dcbc4b..caed0448 100644 --- a/src/CommunityToolkit.Datasync.Server.Swashbuckle/DatasyncOperationExtensions.cs +++ b/src/CommunityToolkit.Datasync.Server.Swashbuckle/DatasyncOperationExtensions.cs @@ -95,6 +95,24 @@ internal static void AddResponseWithContent(this OpenApiOperation operation, str }); operation.Responses[statusCode] = response; } + /// + /// Adds the content type and schema to the request body. + /// + /// The to modify. + /// The schema of the entity in the request. + internal static void AddRequestWithContent(this OpenApiOperation operation, OpenApiSchema schema) + { + operation.RequestBody = new OpenApiRequestBody + { + Content = new Dictionary + { + [JsonMediaType] = new OpenApiMediaType() + { + Schema = schema + } + } + }; + } /// /// Adds or replaces the 409/412 Conflict/Precondition Failed response. diff --git a/tests/CommunityToolkit.Datasync.Client.Test/Serialization/DateTimeConverter_Tests.cs b/tests/CommunityToolkit.Datasync.Client.Test/Serialization/DateTimeConverter_Tests.cs index bd185225..213ed3a9 100644 --- a/tests/CommunityToolkit.Datasync.Client.Test/Serialization/DateTimeConverter_Tests.cs +++ b/tests/CommunityToolkit.Datasync.Client.Test/Serialization/DateTimeConverter_Tests.cs @@ -2,40 +2,84 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using CommunityToolkit.Datasync.Client.Serialization; using System.Text.Json; namespace CommunityToolkit.Datasync.Client.Test.Serialization; [ExcludeFromCodeCoverage] -public class DateTimeConverter_Tests +public class DateTimeConverter_Tests : SerializerTests { - private readonly JsonSerializerOptions serializerOptions; + [Theory] + [MemberData(nameof(Locales))] + public void Converter_ReadsJson(string culture) + { + const string json = """{"updatedAt":"2021-08-21T12:30:15.123+00:00"}"""; + DateTime value = new(2021, 8, 21, 12, 30, 15, 123, DateTimeKind.Utc); + + TestWithCulture(culture, () => + { + Entity entity = JsonSerializer.Deserialize(json, SerializerOptions); + // Use FileTime comparison because no FluentAssertions support for DateTime ignoring zone info. + entity.UpdatedAt.ToFileTime().Should().Be(value.ToFileTime()); + }); + } - public DateTimeConverter_Tests() + [Theory] + [MemberData(nameof(Locales))] + public void Converter_WritesJson(string culture) { - this.serializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web); - this.serializerOptions.Converters.Add(new DateTimeConverter()); + const string json = """{"updatedAt":"2021-08-21T12:30:15.123Z"}"""; + DateTime value = new(2021, 8, 21, 12, 30, 15, 123, 456, DateTimeKind.Utc); + + TestWithCulture(culture, () => + { + Entity entity = new() { UpdatedAt = value }; + string actual = JsonSerializer.Serialize(entity, SerializerOptions); + Assert.Equal(json, actual); + }); } - [Fact] - public void Read_Null_Works() + [Theory] + [MemberData(nameof(Locales))] + public void Converter_WritesJson_WithTimeZone(string culture) { - string json = """{"dt":null}"""; - SUT actual = JsonSerializer.Deserialize(json, this.serializerOptions); - actual.dt.Should().Be(DateTime.MinValue); + const string json = """{"updatedAt":"2021-08-21T12:30:15.123Z"}"""; + DateTime value = DateTime.Parse("2021-08-21T20:30:15.1234567+08:00"); + + TestWithCulture(culture, () => + { + Entity entity = new() { UpdatedAt = value }; + string actual = JsonSerializer.Serialize(entity, SerializerOptions); + Assert.Equal(json, actual); + }); } [Fact] - public void Read_Int_Throws() + public void Converter_ThrowsOnBadDateInInput() { - string json = """{"dt":42}"""; - Action act = () => _ = JsonSerializer.Deserialize(json, this.serializerOptions); - act.Should().Throw(); + const string json = """{"updatedAt":"foo"}"""; + Action act = () => _ = JsonSerializer.Deserialize(json, SerializerOptions); + act.Should().Throw(); + } + + [Theory] + [MemberData(nameof(Locales))] + public void Converter_HandlesNullDateInInput(string culture) + { + const string json = """{"updatedAt":null}"""; + DateTime value = DateTime.MinValue; + + TestWithCulture(culture, () => + { + Entity entity = JsonSerializer.Deserialize(json, SerializerOptions); + entity.UpdatedAt.Should().Be(value); + }); } - class SUT + #region Models + public class Entity { - public DateTime dt { get; set; } + public DateTime UpdatedAt { get; set; } } + #endregion } diff --git a/tests/CommunityToolkit.Datasync.Client.Test/Serialization/DateTimeOffsetConverter_Tests.cs b/tests/CommunityToolkit.Datasync.Client.Test/Serialization/DateTimeOffsetConverter_Tests.cs index 81172977..71881f99 100644 --- a/tests/CommunityToolkit.Datasync.Client.Test/Serialization/DateTimeOffsetConverter_Tests.cs +++ b/tests/CommunityToolkit.Datasync.Client.Test/Serialization/DateTimeOffsetConverter_Tests.cs @@ -2,40 +2,84 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using CommunityToolkit.Datasync.Client.Serialization; using System.Text.Json; +using System.Text.RegularExpressions; namespace CommunityToolkit.Datasync.Client.Test.Serialization; [ExcludeFromCodeCoverage] -public class DateTimeOffsetConverter_Tests +public class DateTimeOffsetConverter_Tests : SerializerTests { - private readonly JsonSerializerOptions serializerOptions; + [Theory] + [MemberData(nameof(Locales))] + public void Converter_ReadsJson(string culture) + { + const string json = "{\"updatedAt\":\"2021-08-21T12:30:15.123+00:00\"}"; + DateTimeOffset value = new(2021, 8, 21, 12, 30, 15, 123, TimeSpan.Zero); + + TestWithCulture(culture, () => + { + Entity entity = JsonSerializer.Deserialize(json, SerializerOptions); + entity.UpdatedAt.Should().Be(value); + }); + } - public DateTimeOffsetConverter_Tests() + [Theory] + [MemberData(nameof(Locales))] + public void Converter_WritesJson(string culture) { - this.serializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web); - this.serializerOptions.Converters.Add(new DateTimeOffsetConverter()); + const string json = "{\"updatedAt\":\"2021-08-21T12:30:15.123Z\"}"; + DateTimeOffset value = new(2021, 8, 21, 12, 30, 15, 123, 456, TimeSpan.Zero); + + TestWithCulture(culture, () => + { + Entity entity = new() { UpdatedAt = value }; + string actual = JsonSerializer.Serialize(entity, SerializerOptions); + Assert.Equal(json, actual); + }); } - [Fact] - public void Read_Null_Works() + [Theory] + [MemberData(nameof(Locales))] + public void Converter_WritesJson_WithTimeZone(string culture) { - string json = """{"dt":null}"""; - SUT actual = JsonSerializer.Deserialize(json, this.serializerOptions); - actual.dt.Should().Be(DateTimeOffset.MinValue); + const string json = "{\"updatedAt\":\"2021-08-21T12:30:15.123Z\"}"; + DateTimeOffset value = new(2021, 8, 21, 20, 30, 15, 123, 456, TimeSpan.FromHours(8)); + + TestWithCulture(culture, () => + { + Entity entity = new() { UpdatedAt = value }; + string actual = JsonSerializer.Serialize(entity, SerializerOptions); + Assert.Equal(json, actual); + }); } [Fact] - public void Read_Int_Throws() + public void Converter_ThrowsOnBadDateInInput() { - string json = """{"dt":42}"""; - Action act = () => _ = JsonSerializer.Deserialize(json, this.serializerOptions); - act.Should().Throw(); + const string json = "{\"updatedAt\":\"foo\"}"; + Action act = () => _ = JsonSerializer.Deserialize(json, SerializerOptions); + act.Should().Throw(); + } + + [Theory] + [MemberData(nameof(Locales))] + public void Converter_HandlesNullDateInInput(string culture) + { + const string json = """{"updatedAt":null}"""; + DateTimeOffset value = DateTimeOffset.MinValue; + + TestWithCulture(culture, () => + { + Entity entity = JsonSerializer.Deserialize(json, SerializerOptions); + entity.UpdatedAt.Should().Be(value); + }); } - class SUT + #region Models + public class Entity { - public DateTimeOffset dt { get; set; } + public DateTimeOffset UpdatedAt { get; set; } } -} + #endregion +} \ No newline at end of file diff --git a/tests/CommunityToolkit.Datasync.Client.Test/Serialization/SerializerTests.cs b/tests/CommunityToolkit.Datasync.Client.Test/Serialization/SerializerTests.cs new file mode 100644 index 00000000..0ccf246f --- /dev/null +++ b/tests/CommunityToolkit.Datasync.Client.Test/Serialization/SerializerTests.cs @@ -0,0 +1,39 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using CommunityToolkit.Datasync.Client.Serialization; +using System.Globalization; +using System.Text.Json; + +#pragma warning disable IDE0028 // Simplify collection initialization + +namespace CommunityToolkit.Datasync.Client.Test.Serialization; + +[ExcludeFromCodeCoverage] +public abstract class SerializerTests +{ + protected static JsonSerializerOptions SerializerOptions + => DatasyncSerializer.JsonSerializerOptions; + + public static TheoryData Locales => new() + { + "fr-FR", + "da-DA", + "en-US" + }; + + protected static void TestWithCulture(string culture, Action act) + { + CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture; + Thread.CurrentThread.CurrentCulture = new CultureInfo(culture); + try + { + act.Invoke(); + } + finally + { + Thread.CurrentThread.CurrentCulture = currentCulture; + } + } +} diff --git a/tests/CommunityToolkit.Datasync.Client.Test/Serialization/TimeOnlyConverter_Tests.cs b/tests/CommunityToolkit.Datasync.Client.Test/Serialization/TimeOnlyConverter_Tests.cs index 39928bc0..63360c4b 100644 --- a/tests/CommunityToolkit.Datasync.Client.Test/Serialization/TimeOnlyConverter_Tests.cs +++ b/tests/CommunityToolkit.Datasync.Client.Test/Serialization/TimeOnlyConverter_Tests.cs @@ -2,40 +2,69 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using CommunityToolkit.Datasync.Client.Serialization; using System.Text.Json; +using System.Text.RegularExpressions; namespace CommunityToolkit.Datasync.Client.Test.Serialization; [ExcludeFromCodeCoverage] -public class TimeOnlyConverter_Tests +public class TimeOnlyConverter_Tests : SerializerTests { - private readonly JsonSerializerOptions serializerOptions; + [Theory] + [MemberData(nameof(Locales))] + public void Converter_ReadsJson(string culture) + { + const string json = """{"updatedAt":"12:30:15.123"}"""; + TimeOnly value = new(12, 30, 15, 123); + + TestWithCulture(culture, () => + { + Entity entity = JsonSerializer.Deserialize(json, SerializerOptions); + entity.UpdatedAt.Ticks.Should().Be(value.Ticks); + }); + } - public TimeOnlyConverter_Tests() + [Theory] + [MemberData(nameof(Locales))] + public void Converter_WritesJson(string culture) { - this.serializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web); - this.serializerOptions.Converters.Add(new TimeOnlyConverter()); + const string json = """{"updatedAt":"12:30:15.123"}"""; + TimeOnly value = new(12, 30, 15, 123, 456); + + TestWithCulture(culture, () => + { + Entity entity = new() { UpdatedAt = value }; + string actual = JsonSerializer.Serialize(entity, SerializerOptions); + Assert.Equal(json, actual); + }); } [Fact] - public void Read_Null_Works() + public void Converter_ThrowsOnBadDateInInput() { - string json = """{"dt":null}"""; - SUT actual = JsonSerializer.Deserialize(json, this.serializerOptions); - actual.dt.Should().Be(TimeOnly.MinValue); + const string json = """{"updatedAt":"foo"}"""; + Action act = () => _ = JsonSerializer.Deserialize(json, SerializerOptions); + act.Should().Throw(); } - [Fact] - public void Read_Int_Throws() + [Theory] + [MemberData(nameof(Locales))] + public void Converter_HandlesNullDateInInput(string culture) { - string json = """{"dt":42}"""; - Action act = () => _ = JsonSerializer.Deserialize(json, this.serializerOptions); - act.Should().Throw(); + const string json = """{"updatedAt":null}"""; + TimeOnly value = TimeOnly.MinValue; + + TestWithCulture(culture, () => + { + Entity entity = JsonSerializer.Deserialize(json, SerializerOptions); + entity.UpdatedAt.Ticks.Should().Be(value.Ticks); + }); } - class SUT + #region Models + public class Entity { - public TimeOnly dt { get; set; } + public TimeOnly UpdatedAt { get; set; } } + #endregion } diff --git a/tests/CommunityToolkit.Datasync.Server.Abstractions.Test/Json/DateTimeConverter_Tests.cs b/tests/CommunityToolkit.Datasync.Server.Abstractions.Test/Json/DateTimeConverter_Tests.cs index 8819bb07..e40b6814 100644 --- a/tests/CommunityToolkit.Datasync.Server.Abstractions.Test/Json/DateTimeConverter_Tests.cs +++ b/tests/CommunityToolkit.Datasync.Server.Abstractions.Test/Json/DateTimeConverter_Tests.cs @@ -13,7 +13,7 @@ public class DateTimeConverter_Tests : SerializerTests [MemberData(nameof(Locales))] public void Converter_ReadsJson(string culture) { - string json = """{"updatedAt":"2021-08-21T12:30:15.123+00:00"}"""; + const string json = """{"updatedAt":"2021-08-21T12:30:15.123+00:00"}"""; DateTime value = new(2021, 8, 21, 12, 30, 15, 123, DateTimeKind.Utc); TestWithCulture(culture, () => @@ -27,7 +27,7 @@ public void Converter_ReadsJson(string culture) [MemberData(nameof(Locales))] public void Converter_WritesJson(string culture) { - string json = """{"updatedAt":"2021-08-21T12:30:15.123Z"}"""; + const string json = """{"updatedAt":"2021-08-21T12:30:15.123Z"}"""; DateTime value = new(2021, 8, 21, 12, 30, 15, 123, 456, DateTimeKind.Utc); TestWithCulture(culture, () => @@ -42,7 +42,7 @@ public void Converter_WritesJson(string culture) [MemberData(nameof(Locales))] public void Converter_WritesJson_WithTimeZone(string culture) { - string json = """{"updatedAt":"2021-08-21T12:30:15.123Z"}"""; + const string json = """{"updatedAt":"2021-08-21T12:30:15.123Z"}"""; DateTime value = DateTime.Parse("2021-08-21T20:30:15.1234567+08:00"); TestWithCulture(culture, () => @@ -56,7 +56,7 @@ public void Converter_WritesJson_WithTimeZone(string culture) [Fact] public void Converter_ThrowsOnBadDateInInput() { - string json = """{"updatedAt":"foo"}"""; + const string json = """{"updatedAt":"foo"}"""; Action act = () => _ = JsonSerializer.Deserialize(json, SerializerOptions); act.Should().Throw(); } @@ -64,7 +64,7 @@ public void Converter_ThrowsOnBadDateInInput() [Fact] public void Converter_ThrowsOnNullDateInInput() { - string json = """{"updatedAt":null}"""; + const string json = """{"updatedAt":null}"""; Action act = () => _ = JsonSerializer.Deserialize(json, SerializerOptions); act.Should().Throw(); } diff --git a/tests/CommunityToolkit.Datasync.Server.Abstractions.Test/Json/DateTimeOffsetConverter_Tests.cs b/tests/CommunityToolkit.Datasync.Server.Abstractions.Test/Json/DateTimeOffsetConverter_Tests.cs index 39e4e372..dbc47ce5 100644 --- a/tests/CommunityToolkit.Datasync.Server.Abstractions.Test/Json/DateTimeOffsetConverter_Tests.cs +++ b/tests/CommunityToolkit.Datasync.Server.Abstractions.Test/Json/DateTimeOffsetConverter_Tests.cs @@ -13,7 +13,7 @@ public class DateTimeOffsetConverter_Tests : SerializerTests [MemberData(nameof(Locales))] public void Converter_ReadsJson(string culture) { - string json = "{\"updatedAt\":\"2021-08-21T12:30:15.123+00:00\"}"; + const string json = "{\"updatedAt\":\"2021-08-21T12:30:15.123+00:00\"}"; DateTimeOffset value = new(2021, 8, 21, 12, 30, 15, 123, TimeSpan.Zero); TestWithCulture(culture, () => @@ -27,7 +27,7 @@ public void Converter_ReadsJson(string culture) [MemberData(nameof(Locales))] public void Converter_WritesJson(string culture) { - string json = "{\"updatedAt\":\"2021-08-21T12:30:15.123Z\"}"; + const string json = "{\"updatedAt\":\"2021-08-21T12:30:15.123Z\"}"; DateTimeOffset value = new(2021, 8, 21, 12, 30, 15, 123, 456, TimeSpan.Zero); TestWithCulture(culture, () => @@ -42,7 +42,7 @@ public void Converter_WritesJson(string culture) [MemberData(nameof(Locales))] public void Converter_WritesJson_WithTimeZone(string culture) { - string json = "{\"updatedAt\":\"2021-08-21T12:30:15.123Z\"}"; + const string json = "{\"updatedAt\":\"2021-08-21T12:30:15.123Z\"}"; DateTimeOffset value = new(2021, 8, 21, 20, 30, 15, 123, 456, TimeSpan.FromHours(8)); TestWithCulture(culture, () => @@ -56,7 +56,7 @@ public void Converter_WritesJson_WithTimeZone(string culture) [Fact] public void Converter_ThrowsOnBadDateInInput() { - string json = "{\"updatedAt\":\"foo\"}"; + const string json = "{\"updatedAt\":\"foo\"}"; Action act = () => _ = JsonSerializer.Deserialize(json, SerializerOptions); act.Should().Throw(); } @@ -64,7 +64,7 @@ public void Converter_ThrowsOnBadDateInInput() [Fact] public void Converter_ThrowsOnNullDateInInput() { - string json = """{"updatedAt":null}"""; + const string json = """{"updatedAt":null}"""; Action act = () => _ = JsonSerializer.Deserialize(json, SerializerOptions); act.Should().Throw(); } diff --git a/tests/CommunityToolkit.Datasync.Server.Abstractions.Test/Json/TimeOnlyConverter_Tests.cs b/tests/CommunityToolkit.Datasync.Server.Abstractions.Test/Json/TimeOnlyConverter_Tests.cs index f0a4e7f3..81e2930c 100644 --- a/tests/CommunityToolkit.Datasync.Server.Abstractions.Test/Json/TimeOnlyConverter_Tests.cs +++ b/tests/CommunityToolkit.Datasync.Server.Abstractions.Test/Json/TimeOnlyConverter_Tests.cs @@ -13,7 +13,7 @@ public class TimeOnlyConverter_Tests : SerializerTests [MemberData(nameof(Locales))] public void Converter_ReadsJson(string culture) { - string json = """{"updatedAt":"12:30:15.123"}"""; + const string json = """{"updatedAt":"12:30:15.123"}"""; TimeOnly value = new(12, 30, 15, 123); TestWithCulture(culture, () => @@ -27,7 +27,7 @@ public void Converter_ReadsJson(string culture) [MemberData(nameof(Locales))] public void Converter_WritesJson(string culture) { - string json = """{"updatedAt":"12:30:15.123"}"""; + const string json = """{"updatedAt":"12:30:15.123"}"""; TimeOnly value = new(12, 30, 15, 123, 456); TestWithCulture(culture, () => @@ -41,7 +41,7 @@ public void Converter_WritesJson(string culture) [Fact] public void Converter_ThrowsOnBadDateInInput() { - string json = """{"updatedAt":"foo"}"""; + const string json = """{"updatedAt":"foo"}"""; Action act = () => _ = JsonSerializer.Deserialize(json, SerializerOptions); act.Should().Throw(); } @@ -49,7 +49,7 @@ public void Converter_ThrowsOnBadDateInInput() [Fact] public void Converter_ThrowsOnNullDateInInput() { - string json = """{"updatedAt":null}"""; + const string json = """{"updatedAt":null}"""; Action act = () => _ = JsonSerializer.Deserialize(json, SerializerOptions); act.Should().Throw(); } diff --git a/tests/CommunityToolkit.Datasync.Server.Swashbuckle.Test/swagger.json b/tests/CommunityToolkit.Datasync.Server.Swashbuckle.Test/swagger.json index 59c886ba..7623daf6 100644 --- a/tests/CommunityToolkit.Datasync.Server.Swashbuckle.Test/swagger.json +++ b/tests/CommunityToolkit.Datasync.Server.Swashbuckle.Test/swagger.json @@ -159,6 +159,15 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/KitchenSink" + } + } + } + }, "responses": { "201": { "description": "Created", @@ -448,6 +457,15 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/KitchenSink" + } + } + } + }, "responses": { "200": { "description": "OK", @@ -530,6 +548,15 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + }, "responses": { "201": { "description": "Created", @@ -819,6 +846,15 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TodoItem" + } + } + } + }, "responses": { "200": { "description": "OK",