diff --git a/.nuget/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json/PackageReleaseNotes.txt b/.nuget/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json/PackageReleaseNotes.txt index 7bfb931..0c474f6 100644 --- a/.nuget/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json/PackageReleaseNotes.txt +++ b/.nuget/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 1.0.7 +Availability: .NET 10 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 1.0.6 Availability: .NET 10 diff --git a/.nuget/Codebelt.Extensions.Carter.AspNetCore.Text.Json/PackageReleaseNotes.txt b/.nuget/Codebelt.Extensions.Carter.AspNetCore.Text.Json/PackageReleaseNotes.txt index a4e5086..597c57f 100644 --- a/.nuget/Codebelt.Extensions.Carter.AspNetCore.Text.Json/PackageReleaseNotes.txt +++ b/.nuget/Codebelt.Extensions.Carter.AspNetCore.Text.Json/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 1.0.7 +Availability: .NET 10 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 1.0.6 Availability: .NET 10 diff --git a/.nuget/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml/PackageReleaseNotes.txt b/.nuget/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml/PackageReleaseNotes.txt index 1a566f7..b74fa58 100644 --- a/.nuget/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml/PackageReleaseNotes.txt +++ b/.nuget/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 1.0.7 +Availability: .NET 10 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 1.0.6 Availability: .NET 10 diff --git a/.nuget/Codebelt.Extensions.Carter.AspNetCore.Xml/PackageReleaseNotes.txt b/.nuget/Codebelt.Extensions.Carter.AspNetCore.Xml/PackageReleaseNotes.txt index 9570c86..74f4438 100644 --- a/.nuget/Codebelt.Extensions.Carter.AspNetCore.Xml/PackageReleaseNotes.txt +++ b/.nuget/Codebelt.Extensions.Carter.AspNetCore.Xml/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 1.0.7 +Availability: .NET 10 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 1.0.6 Availability: .NET 10 diff --git a/.nuget/Codebelt.Extensions.Carter/PackageReleaseNotes.txt b/.nuget/Codebelt.Extensions.Carter/PackageReleaseNotes.txt index 0833676..e27e42a 100644 --- a/.nuget/Codebelt.Extensions.Carter/PackageReleaseNotes.txt +++ b/.nuget/Codebelt.Extensions.Carter/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 1.0.7 +Availability: .NET 10 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 1.0.6 Availability: .NET 10 diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a9a33b..af64ad9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), For more details, please refer to `PackageReleaseNotes.txt` on a per assembly basis in the `.nuget` folder. +## [1.0.7] - 2026-08-16 + +This is a service update that focuses on package dependencies. + ## [1.0.6] - 2026-07-24 This is a patch release that updates Cuemon and Codebelt shared dependencies to their latest stable versions, improves build configuration, enhances CI/CD automation, and modernizes code formatting. diff --git a/Directory.Packages.props b/Directory.Packages.props index 2fb9a09..c3ad13f 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,24 +1,24 @@ - - - true - - - - - - - - - - - - - - - - - - - - + + + true + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml/YamlResponseNegotiator.cs b/src/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml/YamlResponseNegotiator.cs index 63a4087..29a2558 100644 --- a/src/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml/YamlResponseNegotiator.cs +++ b/src/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml/YamlResponseNegotiator.cs @@ -1,37 +1,37 @@ -using Codebelt.Extensions.YamlDotNet.Formatters; -using Microsoft.Extensions.Options; -using System.Text; -using Codebelt.Extensions.Carter.Response; -using Cuemon.Runtime.Serialization.Formatters; - -namespace Codebelt.Extensions.Carter.AspNetCore.Text.Yaml; - -/// -/// Provides a YAML response negotiator for Carter, capable of serializing response models to YAML format. -/// -/// -public class YamlResponseNegotiator : ConfigurableResponseNegotiator -{ - /// - /// Initializes a new instance of the class. - /// - /// The used to configure YAML serialization and supported media types. - public YamlResponseNegotiator(IOptions options) : base(options.Value) - { - } - - /// - /// Returns the character encoding specified by the . - /// - /// The default for this negotiator. - protected override Encoding GetDefaultEncoding() => Options.Encoding; - - /// - /// Returns a new configured with the current . - /// - /// A instance configured with the current . - public override StreamFormatter GetFormatter() - { - return new YamlFormatter(Options); - } -} +using Codebelt.Extensions.YamlDotNet.Formatters; +using Microsoft.Extensions.Options; +using System.Text; +using Codebelt.Extensions.Carter.Response; +using Cuemon.Runtime.Serialization.Formatters; + +namespace Codebelt.Extensions.Carter.AspNetCore.Text.Yaml; + +/// +/// Provides a YAML response negotiator for Carter, capable of serializing response models to YAML format. +/// +/// +public class YamlResponseNegotiator : ConfigurableResponseNegotiator +{ + /// + /// Initializes a new instance of the class. + /// + /// The used to configure YAML serialization and supported media types. + public YamlResponseNegotiator(IOptions options) : base(options.Value) + { + } + + /// + /// Returns the character encoding specified by the . + /// + /// The default for this negotiator. + protected override Encoding GetDefaultEncoding() => Options.Encoding; + + /// + /// Returns a new configured with the current . + /// + /// A instance configured with the current . + public override StreamFormatter GetFormatter() + { + return new YamlFormatter(Options); + } +} diff --git a/src/Codebelt.Extensions.Carter.AspNetCore.Xml/XmlResponseNegotiator.cs b/src/Codebelt.Extensions.Carter.AspNetCore.Xml/XmlResponseNegotiator.cs index 8fe09dc..4ee5be5 100644 --- a/src/Codebelt.Extensions.Carter.AspNetCore.Xml/XmlResponseNegotiator.cs +++ b/src/Codebelt.Extensions.Carter.AspNetCore.Xml/XmlResponseNegotiator.cs @@ -10,7 +10,7 @@ namespace Codebelt.Extensions.Carter.AspNetCore.Xml; /// Provides an XML response negotiator for Carter, capable of serializing response models to XML format. /// /// - public class XmlResponseNegotiator : ConfigurableResponseNegotiator +public class XmlResponseNegotiator : ConfigurableResponseNegotiator { /// /// Initializes a new instance of the class. diff --git a/src/Codebelt.Extensions.Carter/EndpointConventionBuilderExtensions.cs b/src/Codebelt.Extensions.Carter/EndpointConventionBuilderExtensions.cs index 5def504..655c5ba 100644 --- a/src/Codebelt.Extensions.Carter/EndpointConventionBuilderExtensions.cs +++ b/src/Codebelt.Extensions.Carter/EndpointConventionBuilderExtensions.cs @@ -1,36 +1,36 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Http; - -namespace Codebelt.Extensions.Carter; - -/// -/// Extension methods for . -/// -public static class EndpointConventionBuilderExtensions -{ - /// The to add the metadata to. - extension(IEndpointConventionBuilder builder) - { - /// - /// Adds metadata indicating that the endpoint produces a response of the specified type with the given status code and content types. - /// - /// The type of the response body. - /// The HTTP status code of the response. Defaults to . - /// The content types produced by the endpoint. - /// The with the added metadata. - public IEndpointConventionBuilder Produces(int statusCode = StatusCodes.Status200OK, params string[] contentTypes) - { - return builder.WithMetadata(new ProducesResponseTypeMetadata(statusCode, typeof(TResponse), contentTypes)); - } - - /// - /// Adds metadata indicating that the endpoint produces a response with the given status code and no response body. - /// - /// The HTTP status code of the response. - /// The with the added metadata. - public IEndpointConventionBuilder Produces(int statusCode) - { - return builder.WithMetadata(new ProducesResponseTypeMetadata(statusCode)); - } - } -} +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; + +namespace Codebelt.Extensions.Carter; + +/// +/// Extension methods for . +/// +public static class EndpointConventionBuilderExtensions +{ + /// The to add the metadata to. + extension(IEndpointConventionBuilder builder) + { + /// + /// Adds metadata indicating that the endpoint produces a response of the specified type with the given status code and content types. + /// + /// The type of the response body. + /// The HTTP status code of the response. Defaults to . + /// The content types produced by the endpoint. + /// The with the added metadata. + public IEndpointConventionBuilder Produces(int statusCode = StatusCodes.Status200OK, params string[] contentTypes) + { + return builder.WithMetadata(new ProducesResponseTypeMetadata(statusCode, typeof(TResponse), contentTypes)); + } + + /// + /// Adds metadata indicating that the endpoint produces a response with the given status code and no response body. + /// + /// The HTTP status code of the response. + /// The with the added metadata. + public IEndpointConventionBuilder Produces(int statusCode) + { + return builder.WithMetadata(new ProducesResponseTypeMetadata(statusCode)); + } + } +} diff --git a/test/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json.Tests/NewtonsoftJsonNegotiatorTest.cs b/test/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json.Tests/NewtonsoftJsonNegotiatorTest.cs index 9b96867..ae5f9b5 100644 --- a/test/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json.Tests/NewtonsoftJsonNegotiatorTest.cs +++ b/test/Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json.Tests/NewtonsoftJsonNegotiatorTest.cs @@ -1,98 +1,98 @@ -using System.Collections.Generic; -using System.Net; -using System.Net.Http.Headers; -using System.Threading; -using System.Threading.Tasks; -using Carter; -using Carter.Response; -using Codebelt.Extensions.AspNetCore.Newtonsoft.Json.Formatters; -using Codebelt.Extensions.Newtonsoft.Json.Formatters; -using Codebelt.Extensions.Xunit; -using Codebelt.Extensions.Xunit.Hosting.AspNetCore; -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.Options; -using Microsoft.AspNetCore.Http; -using Xunit; -using AspNetCoreMediaType = Microsoft.Net.Http.Headers.MediaTypeHeaderValue; - -namespace Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json; - -/// -/// Tests for the class. -/// -public class NewtonsoftJsonNegotiatorTest : Test -{ - public NewtonsoftJsonNegotiatorTest(ITestOutputHelper output) : base(output) - { - } - - [Theory] - [InlineData("application/json")] - [InlineData("*/*")] - public void CanHandle_ShouldReturnTrue_WhenMediaTypeIsSupported(string mediaType) - { - var sut = new NewtonsoftJsonNegotiator(Options.Create(new NewtonsoftJsonFormatterOptions())); - - Assert.True(sut.CanHandle(AspNetCoreMediaType.Parse(mediaType))); - } - - [Theory] - [InlineData("application/xml")] - [InlineData("text/xml")] - [InlineData("application/yaml")] - public void CanHandle_ShouldReturnFalse_WhenMediaTypeIsNotSupported(string mediaType) - { - var sut = new NewtonsoftJsonNegotiator(Options.Create(new NewtonsoftJsonFormatterOptions - { - SupportedMediaTypes = new List - { - new("application/json") - } - })); - - Assert.False(sut.CanHandle(AspNetCoreMediaType.Parse(mediaType))); - } - - [Fact] - public async Task Handle_ShouldWriteJsonToResponseBody_WithCorrectContentType() - { - using var response = await MinimalWebHostTestFactory.RunAsync( - services => - { - services.AddNewtonsoftJsonFormatterOptions(); - services.AddCarter(configurator: c => c.WithResponseNegotiator()); - }, - app => - { - app.UseRouting(); - app.UseEndpoints(endpoints => - { - endpoints.MapGet("/", (HttpResponse res, CancellationToken ct) => - res.Negotiate(new FakeModel { Id = 1, Name = "Newtonsoft" }, ct)); - }); - }, - _ => { }, - async client => - { - client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - return await client.GetAsync("/"); - }); - - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.StartsWith("application/json", response.Content.Headers.ContentType?.ToString()); - - var body = await response.Content.ReadAsStringAsync(); - - Assert.NotEmpty(body); - Assert.Contains("1", body); - Assert.Contains("Newtonsoft", body); - - TestOutput.WriteLine(body); - } -} - -internal sealed class FakeModel -{ - public int Id { get; init; } - public string Name { get; init; } -} +using System.Collections.Generic; +using System.Net; +using System.Net.Http.Headers; +using System.Threading; +using System.Threading.Tasks; +using Carter; +using Carter.Response; +using Codebelt.Extensions.AspNetCore.Newtonsoft.Json.Formatters; +using Codebelt.Extensions.Newtonsoft.Json.Formatters; +using Codebelt.Extensions.Xunit; +using Codebelt.Extensions.Xunit.Hosting.AspNetCore; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.Options; +using Microsoft.AspNetCore.Http; +using Xunit; +using AspNetCoreMediaType = Microsoft.Net.Http.Headers.MediaTypeHeaderValue; + +namespace Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json; + +/// +/// Tests for the class. +/// +public class NewtonsoftJsonNegotiatorTest : Test +{ + public NewtonsoftJsonNegotiatorTest(ITestOutputHelper output) : base(output) + { + } + + [Theory] + [InlineData("application/json")] + [InlineData("*/*")] + public void CanHandle_ShouldReturnTrue_WhenMediaTypeIsSupported(string mediaType) + { + var sut = new NewtonsoftJsonNegotiator(Options.Create(new NewtonsoftJsonFormatterOptions())); + + Assert.True(sut.CanHandle(AspNetCoreMediaType.Parse(mediaType))); + } + + [Theory] + [InlineData("application/xml")] + [InlineData("text/xml")] + [InlineData("application/yaml")] + public void CanHandle_ShouldReturnFalse_WhenMediaTypeIsNotSupported(string mediaType) + { + var sut = new NewtonsoftJsonNegotiator(Options.Create(new NewtonsoftJsonFormatterOptions + { + SupportedMediaTypes = new List + { + new("application/json") + } + })); + + Assert.False(sut.CanHandle(AspNetCoreMediaType.Parse(mediaType))); + } + + [Fact] + public async Task Handle_ShouldWriteJsonToResponseBody_WithCorrectContentType() + { + using var response = await MinimalWebHostTestFactory.RunAsync( + services => + { + services.AddNewtonsoftJsonFormatterOptions(); + services.AddCarter(configurator: c => c.WithResponseNegotiator()); + }, + app => + { + app.UseRouting(); + app.UseEndpoints(endpoints => + { + endpoints.MapGet("/", (HttpResponse res, CancellationToken ct) => + res.Negotiate(new FakeModel { Id = 1, Name = "Newtonsoft" }, ct)); + }); + }, + _ => { }, + async client => + { + client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + return await client.GetAsync("/"); + }); + + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.StartsWith("application/json", response.Content.Headers.ContentType?.ToString()); + + var body = await response.Content.ReadAsStringAsync(); + + Assert.NotEmpty(body); + Assert.Contains("1", body); + Assert.Contains("Newtonsoft", body); + + TestOutput.WriteLine(body); + } +} + +internal sealed class FakeModel +{ + public int Id { get; init; } + public string Name { get; init; } +} diff --git a/test/Codebelt.Extensions.Carter.AspNetCore.Text.Json.Tests/JsonResponseNegotiatorTest.cs b/test/Codebelt.Extensions.Carter.AspNetCore.Text.Json.Tests/JsonResponseNegotiatorTest.cs index 9d97860..88fcca8 100644 --- a/test/Codebelt.Extensions.Carter.AspNetCore.Text.Json.Tests/JsonResponseNegotiatorTest.cs +++ b/test/Codebelt.Extensions.Carter.AspNetCore.Text.Json.Tests/JsonResponseNegotiatorTest.cs @@ -1,98 +1,98 @@ -using System.Collections.Generic; -using System.Net; -using System.Net.Http.Headers; -using System.Threading; -using System.Threading.Tasks; -using Carter; -using Carter.Response; -using Codebelt.Extensions.Xunit; -using Codebelt.Extensions.Xunit.Hosting.AspNetCore; -using Cuemon.Extensions.Text.Json.Formatters; -using Microsoft.Extensions.Options; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.DependencyInjection; -using Xunit; -using AspNetCoreMediaType = Microsoft.Net.Http.Headers.MediaTypeHeaderValue; - -namespace Codebelt.Extensions.Carter.AspNetCore.Text.Json; - -/// -/// Tests for the class. -/// -public class JsonResponseNegotiatorTest : Test -{ - public JsonResponseNegotiatorTest(ITestOutputHelper output) : base(output) - { - } - - [Theory] - [InlineData("application/json")] - [InlineData("*/*")] - public void CanHandle_ShouldReturnTrue_WhenMediaTypeIsSupported(string mediaType) - { - var sut = new JsonResponseNegotiator(Options.Create(new JsonFormatterOptions())); - - Assert.True(sut.CanHandle(AspNetCoreMediaType.Parse(mediaType))); - } - - [Theory] - [InlineData("application/xml")] - [InlineData("text/xml")] - [InlineData("application/yaml")] - public void CanHandle_ShouldReturnFalse_WhenMediaTypeIsNotSupported(string mediaType) - { - var sut = new JsonResponseNegotiator(Options.Create(new JsonFormatterOptions - { - SupportedMediaTypes = new List - { - new("application/json") - } - })); - - Assert.False(sut.CanHandle(AspNetCoreMediaType.Parse(mediaType))); - } - - [Fact] - public async Task Handle_ShouldWriteJsonToResponseBody_WithCorrectContentType() - { - using var response = await MinimalWebHostTestFactory.RunAsync( - services => - { - services.AddSingleton(new JsonFormatterOptions()); - services.AddCarter(configurator: c => c.WithResponseNegotiator()); - }, - app => - { - app.UseRouting(); - app.UseEndpoints(endpoints => - { - endpoints.MapGet("/", (HttpResponse res, CancellationToken ct) => - res.Negotiate(new FakeModel { Id = 1, Name = "Json" }, ct)); - }); - }, - _ => { }, - async client => - { - client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - return await client.GetAsync("/"); - }); - - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.StartsWith("application/json", response.Content.Headers.ContentType?.ToString()); - - var body = await response.Content.ReadAsStringAsync(); - - Assert.NotEmpty(body); - Assert.Contains("1", body); - Assert.Contains("Json", body); - - TestOutput.WriteLine(body); - } -} - -internal sealed class FakeModel -{ - public int Id { get; init; } - public string Name { get; init; } -} +using System.Collections.Generic; +using System.Net; +using System.Net.Http.Headers; +using System.Threading; +using System.Threading.Tasks; +using Carter; +using Carter.Response; +using Codebelt.Extensions.Xunit; +using Codebelt.Extensions.Xunit.Hosting.AspNetCore; +using Cuemon.Extensions.Text.Json.Formatters; +using Microsoft.Extensions.Options; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Xunit; +using AspNetCoreMediaType = Microsoft.Net.Http.Headers.MediaTypeHeaderValue; + +namespace Codebelt.Extensions.Carter.AspNetCore.Text.Json; + +/// +/// Tests for the class. +/// +public class JsonResponseNegotiatorTest : Test +{ + public JsonResponseNegotiatorTest(ITestOutputHelper output) : base(output) + { + } + + [Theory] + [InlineData("application/json")] + [InlineData("*/*")] + public void CanHandle_ShouldReturnTrue_WhenMediaTypeIsSupported(string mediaType) + { + var sut = new JsonResponseNegotiator(Options.Create(new JsonFormatterOptions())); + + Assert.True(sut.CanHandle(AspNetCoreMediaType.Parse(mediaType))); + } + + [Theory] + [InlineData("application/xml")] + [InlineData("text/xml")] + [InlineData("application/yaml")] + public void CanHandle_ShouldReturnFalse_WhenMediaTypeIsNotSupported(string mediaType) + { + var sut = new JsonResponseNegotiator(Options.Create(new JsonFormatterOptions + { + SupportedMediaTypes = new List + { + new("application/json") + } + })); + + Assert.False(sut.CanHandle(AspNetCoreMediaType.Parse(mediaType))); + } + + [Fact] + public async Task Handle_ShouldWriteJsonToResponseBody_WithCorrectContentType() + { + using var response = await MinimalWebHostTestFactory.RunAsync( + services => + { + services.AddSingleton(new JsonFormatterOptions()); + services.AddCarter(configurator: c => c.WithResponseNegotiator()); + }, + app => + { + app.UseRouting(); + app.UseEndpoints(endpoints => + { + endpoints.MapGet("/", (HttpResponse res, CancellationToken ct) => + res.Negotiate(new FakeModel { Id = 1, Name = "Json" }, ct)); + }); + }, + _ => { }, + async client => + { + client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + return await client.GetAsync("/"); + }); + + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.StartsWith("application/json", response.Content.Headers.ContentType?.ToString()); + + var body = await response.Content.ReadAsStringAsync(); + + Assert.NotEmpty(body); + Assert.Contains("1", body); + Assert.Contains("Json", body); + + TestOutput.WriteLine(body); + } +} + +internal sealed class FakeModel +{ + public int Id { get; init; } + public string Name { get; init; } +} diff --git a/test/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml.Tests/YamlResponseNegotiatorTest.cs b/test/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml.Tests/YamlResponseNegotiatorTest.cs index 91f0630..f47241f 100644 --- a/test/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml.Tests/YamlResponseNegotiatorTest.cs +++ b/test/Codebelt.Extensions.Carter.AspNetCore.Text.Yaml.Tests/YamlResponseNegotiatorTest.cs @@ -1,102 +1,102 @@ -using System.Collections.Generic; -using System.Net; -using System.Net.Http.Headers; -using System.Threading; -using System.Threading.Tasks; -using Carter; -using Carter.Response; -using Codebelt.Extensions.AspNetCore.Text.Yaml; -using Codebelt.Extensions.Xunit; -using Codebelt.Extensions.Xunit.Hosting.AspNetCore; -using Codebelt.Extensions.YamlDotNet.Formatters; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.Options; -using Xunit; -using AspNetCoreMediaType = Microsoft.Net.Http.Headers.MediaTypeHeaderValue; - -namespace Codebelt.Extensions.Carter.AspNetCore.Text.Yaml; - -/// -/// Tests for the class. -/// -public class YamlResponseNegotiatorTest : Test -{ - public YamlResponseNegotiatorTest(ITestOutputHelper output) : base(output) - { - } - - [Theory] - [InlineData("application/yaml")] - [InlineData("text/yaml")] - [InlineData("text/plain")] - [InlineData("*/*")] - public void CanHandle_ShouldReturnTrue_WhenMediaTypeIsSupported(string mediaType) - { - var sut = new YamlResponseNegotiator(Options.Create(new YamlFormatterOptions())); - - Assert.True(sut.CanHandle(AspNetCoreMediaType.Parse(mediaType))); - } - - [Theory] - [InlineData("application/json")] - [InlineData("text/xml")] - [InlineData("application/xml")] - public void CanHandle_ShouldReturnFalse_WhenMediaTypeIsNotSupported(string mediaType) - { - var sut = new YamlResponseNegotiator(Options.Create(new YamlFormatterOptions - { - SupportedMediaTypes = new List - { - new("application/x-yaml"), - new("application/yaml"), - new("text/yaml") - } - })); - - Assert.False(sut.CanHandle(AspNetCoreMediaType.Parse(mediaType))); - } - - [Fact] - public async Task Handle_ShouldWriteYamlToResponseBody_WithCorrectContentType() - { - using var response = await MinimalWebHostTestFactory.RunAsync( - services => - { - services.AddMinimalYamlOptions(); - services.AddCarter(configurator: c => c.WithResponseNegotiator()); - }, - app => - { - app.UseRouting(); - app.UseEndpoints(endpoints => - { - endpoints.MapGet("/", (HttpResponse res, CancellationToken ct) => - res.Negotiate(new FakeModel { Id = 1, Name = "YAML" }, ct)); - }); - }, - _ => { }, - async client => - { - client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/yaml")); - return await client.GetAsync("/"); - }); - - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.StartsWith("application/yaml", response.Content.Headers.ContentType?.ToString()); - - var body = await response.Content.ReadAsStringAsync(); - - Assert.NotEmpty(body); - Assert.Contains("id: 1", body); - Assert.Contains("name: YAML", body); - - TestOutput.WriteLine(body); - } -} - -internal sealed class FakeModel -{ - public int Id { get; init; } - public string Name { get; init; } -} +using System.Collections.Generic; +using System.Net; +using System.Net.Http.Headers; +using System.Threading; +using System.Threading.Tasks; +using Carter; +using Carter.Response; +using Codebelt.Extensions.AspNetCore.Text.Yaml; +using Codebelt.Extensions.Xunit; +using Codebelt.Extensions.Xunit.Hosting.AspNetCore; +using Codebelt.Extensions.YamlDotNet.Formatters; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Options; +using Xunit; +using AspNetCoreMediaType = Microsoft.Net.Http.Headers.MediaTypeHeaderValue; + +namespace Codebelt.Extensions.Carter.AspNetCore.Text.Yaml; + +/// +/// Tests for the class. +/// +public class YamlResponseNegotiatorTest : Test +{ + public YamlResponseNegotiatorTest(ITestOutputHelper output) : base(output) + { + } + + [Theory] + [InlineData("application/yaml")] + [InlineData("text/yaml")] + [InlineData("text/plain")] + [InlineData("*/*")] + public void CanHandle_ShouldReturnTrue_WhenMediaTypeIsSupported(string mediaType) + { + var sut = new YamlResponseNegotiator(Options.Create(new YamlFormatterOptions())); + + Assert.True(sut.CanHandle(AspNetCoreMediaType.Parse(mediaType))); + } + + [Theory] + [InlineData("application/json")] + [InlineData("text/xml")] + [InlineData("application/xml")] + public void CanHandle_ShouldReturnFalse_WhenMediaTypeIsNotSupported(string mediaType) + { + var sut = new YamlResponseNegotiator(Options.Create(new YamlFormatterOptions + { + SupportedMediaTypes = new List + { + new("application/x-yaml"), + new("application/yaml"), + new("text/yaml") + } + })); + + Assert.False(sut.CanHandle(AspNetCoreMediaType.Parse(mediaType))); + } + + [Fact] + public async Task Handle_ShouldWriteYamlToResponseBody_WithCorrectContentType() + { + using var response = await MinimalWebHostTestFactory.RunAsync( + services => + { + services.AddMinimalYamlOptions(); + services.AddCarter(configurator: c => c.WithResponseNegotiator()); + }, + app => + { + app.UseRouting(); + app.UseEndpoints(endpoints => + { + endpoints.MapGet("/", (HttpResponse res, CancellationToken ct) => + res.Negotiate(new FakeModel { Id = 1, Name = "YAML" }, ct)); + }); + }, + _ => { }, + async client => + { + client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/yaml")); + return await client.GetAsync("/"); + }); + + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.StartsWith("application/yaml", response.Content.Headers.ContentType?.ToString()); + + var body = await response.Content.ReadAsStringAsync(); + + Assert.NotEmpty(body); + Assert.Contains("id: 1", body); + Assert.Contains("name: YAML", body); + + TestOutput.WriteLine(body); + } +} + +internal sealed class FakeModel +{ + public int Id { get; init; } + public string Name { get; init; } +} diff --git a/test/Codebelt.Extensions.Carter.AspNetCore.Xml.Tests/XmlResponseNegotiatorTest.cs b/test/Codebelt.Extensions.Carter.AspNetCore.Xml.Tests/XmlResponseNegotiatorTest.cs index b4ff25f..4f84b39 100644 --- a/test/Codebelt.Extensions.Carter.AspNetCore.Xml.Tests/XmlResponseNegotiatorTest.cs +++ b/test/Codebelt.Extensions.Carter.AspNetCore.Xml.Tests/XmlResponseNegotiatorTest.cs @@ -1,100 +1,100 @@ -using System.Collections.Generic; -using System.Net; -using System.Net.Http.Headers; -using System.Threading; -using System.Threading.Tasks; -using Carter; -using Carter.Response; -using Codebelt.Extensions.Xunit; -using Codebelt.Extensions.Xunit.Hosting.AspNetCore; -using Cuemon.Extensions.AspNetCore.Xml; -using Cuemon.Xml.Serialization.Formatters; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.Options; -using Xunit; -using AspNetCoreMediaType = Microsoft.Net.Http.Headers.MediaTypeHeaderValue; - -namespace Codebelt.Extensions.Carter.AspNetCore.Xml; - -/// -/// Tests for the class. -/// -public class XmlResponseNegotiatorTest : Test -{ - public XmlResponseNegotiatorTest(ITestOutputHelper output) : base(output) - { - } - - [Theory] - [InlineData("application/xml")] - [InlineData("text/xml")] - [InlineData("*/*")] - public void CanHandle_ShouldReturnTrue_WhenMediaTypeIsSupported(string mediaType) - { - var sut = new XmlResponseNegotiator(Options.Create(new XmlFormatterOptions())); - - Assert.True(sut.CanHandle(AspNetCoreMediaType.Parse(mediaType))); - } - - [Theory] - [InlineData("application/json")] - [InlineData("text/yaml")] - [InlineData("application/yaml")] - public void CanHandle_ShouldReturnFalse_WhenMediaTypeIsNotSupported(string mediaType) - { - var sut = new XmlResponseNegotiator(Options.Create(new XmlFormatterOptions - { - SupportedMediaTypes = new List - { - new("application/xml"), - new("text/xml") - } - })); - - Assert.False(sut.CanHandle(AspNetCoreMediaType.Parse(mediaType))); - } - - [Fact] - public async Task Handle_ShouldWriteXmlToResponseBody_WithCorrectContentType() - { - using var response = await MinimalWebHostTestFactory.RunAsync( - services => - { - services.AddMinimalXmlOptions(); - services.AddCarter(configurator: c => c.WithResponseNegotiator()); - }, - app => - { - app.UseRouting(); - app.UseEndpoints(endpoints => - { - endpoints.MapGet("/", (HttpResponse res, CancellationToken ct) => - res.Negotiate(new FakeModel { Id = 1, Name = "XML" }, ct)); - }); - }, - _ => { }, - async client => - { - client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml")); - return await client.GetAsync("/"); - }); - - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.StartsWith("application/xml", response.Content.Headers.ContentType?.ToString()); - - var body = await response.Content.ReadAsStringAsync(); - - Assert.NotEmpty(body); - Assert.Contains("1", body); - Assert.Contains("XML", body); - - TestOutput.WriteLine(body); - } -} - -internal sealed class FakeModel -{ - public int Id { get; init; } - public string Name { get; init; } -} +using System.Collections.Generic; +using System.Net; +using System.Net.Http.Headers; +using System.Threading; +using System.Threading.Tasks; +using Carter; +using Carter.Response; +using Codebelt.Extensions.Xunit; +using Codebelt.Extensions.Xunit.Hosting.AspNetCore; +using Cuemon.Extensions.AspNetCore.Xml; +using Cuemon.Xml.Serialization.Formatters; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Options; +using Xunit; +using AspNetCoreMediaType = Microsoft.Net.Http.Headers.MediaTypeHeaderValue; + +namespace Codebelt.Extensions.Carter.AspNetCore.Xml; + +/// +/// Tests for the class. +/// +public class XmlResponseNegotiatorTest : Test +{ + public XmlResponseNegotiatorTest(ITestOutputHelper output) : base(output) + { + } + + [Theory] + [InlineData("application/xml")] + [InlineData("text/xml")] + [InlineData("*/*")] + public void CanHandle_ShouldReturnTrue_WhenMediaTypeIsSupported(string mediaType) + { + var sut = new XmlResponseNegotiator(Options.Create(new XmlFormatterOptions())); + + Assert.True(sut.CanHandle(AspNetCoreMediaType.Parse(mediaType))); + } + + [Theory] + [InlineData("application/json")] + [InlineData("text/yaml")] + [InlineData("application/yaml")] + public void CanHandle_ShouldReturnFalse_WhenMediaTypeIsNotSupported(string mediaType) + { + var sut = new XmlResponseNegotiator(Options.Create(new XmlFormatterOptions + { + SupportedMediaTypes = new List + { + new("application/xml"), + new("text/xml") + } + })); + + Assert.False(sut.CanHandle(AspNetCoreMediaType.Parse(mediaType))); + } + + [Fact] + public async Task Handle_ShouldWriteXmlToResponseBody_WithCorrectContentType() + { + using var response = await MinimalWebHostTestFactory.RunAsync( + services => + { + services.AddMinimalXmlOptions(); + services.AddCarter(configurator: c => c.WithResponseNegotiator()); + }, + app => + { + app.UseRouting(); + app.UseEndpoints(endpoints => + { + endpoints.MapGet("/", (HttpResponse res, CancellationToken ct) => + res.Negotiate(new FakeModel { Id = 1, Name = "XML" }, ct)); + }); + }, + _ => { }, + async client => + { + client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml")); + return await client.GetAsync("/"); + }); + + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.StartsWith("application/xml", response.Content.Headers.ContentType?.ToString()); + + var body = await response.Content.ReadAsStringAsync(); + + Assert.NotEmpty(body); + Assert.Contains("1", body); + Assert.Contains("XML", body); + + TestOutput.WriteLine(body); + } +} + +internal sealed class FakeModel +{ + public int Id { get; init; } + public string Name { get; init; } +} diff --git a/test/Codebelt.Extensions.Carter.FunctionalTests/Assets/WorldModule.cs b/test/Codebelt.Extensions.Carter.FunctionalTests/Assets/WorldModule.cs index 7a2733c..2119c71 100644 --- a/test/Codebelt.Extensions.Carter.FunctionalTests/Assets/WorldModule.cs +++ b/test/Codebelt.Extensions.Carter.FunctionalTests/Assets/WorldModule.cs @@ -1,28 +1,28 @@ -using System.Linq; -using System.Threading; -using Carter; -using Carter.Response; -using Cuemon.Globalization; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Routing; - -namespace Codebelt.Extensions.Carter.Assets; - -internal sealed class WorldModule : ICarterModule -{ - public void AddRoutes(IEndpointRouteBuilder app) - { - app.MapGet("/world/statistical-regions", (HttpResponse res, CancellationToken ct) => - res.Negotiate(World.StatisticalRegions - .Where(r => r.Kind == StatisticalRegionKind.World) - .Select(r => new StatisticalRegionModel { Code = r.Code, Name = r.Name, Kind = r.Kind }), ct)); - } -} - -internal sealed class StatisticalRegionModel -{ - public string Code { get; init; } - public string Name { get; init; } - public StatisticalRegionKind Kind { get; init; } -} +using System.Linq; +using System.Threading; +using Carter; +using Carter.Response; +using Cuemon.Globalization; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Routing; + +namespace Codebelt.Extensions.Carter.Assets; + +internal sealed class WorldModule : ICarterModule +{ + public void AddRoutes(IEndpointRouteBuilder app) + { + app.MapGet("/world/statistical-regions", (HttpResponse res, CancellationToken ct) => + res.Negotiate(World.StatisticalRegions + .Where(r => r.Kind == StatisticalRegionKind.World) + .Select(r => new StatisticalRegionModel { Code = r.Code, Name = r.Name, Kind = r.Kind }), ct)); + } +} + +internal sealed class StatisticalRegionModel +{ + public string Code { get; init; } + public string Name { get; init; } + public StatisticalRegionKind Kind { get; init; } +} diff --git a/test/Codebelt.Extensions.Carter.FunctionalTests/JsonResponseNegotiatorTest.cs b/test/Codebelt.Extensions.Carter.FunctionalTests/JsonResponseNegotiatorTest.cs index 66d55b1..3a38a08 100644 --- a/test/Codebelt.Extensions.Carter.FunctionalTests/JsonResponseNegotiatorTest.cs +++ b/test/Codebelt.Extensions.Carter.FunctionalTests/JsonResponseNegotiatorTest.cs @@ -1,32 +1,32 @@ -using System.Net; -using System.Net.Http.Headers; -using System.Text.Json.Serialization; -using System.Threading.Tasks; -using Carter; -using Codebelt.Extensions.Carter.AspNetCore.Text.Json; -using Codebelt.Extensions.Carter.Assets; -using Codebelt.Extensions.Xunit; -using Codebelt.Extensions.Xunit.Hosting.AspNetCore; -using Cuemon.Extensions.AspNetCore.Text.Json; -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.DependencyInjection; -using Xunit; - -namespace Codebelt.Extensions.Carter; - -/// -/// Functional tests verifying Carter bootstrapped with as the sole response negotiator. -/// -public class JsonResponseNegotiatorTest : Test -{ - public JsonResponseNegotiatorTest(ITestOutputHelper output) : base(output) - { - } - - [Fact] - public async Task GetStatisticalRegions_ShouldReturnJsonResponse_WhenCarterDefaultsAreDisabled() - { - using var response = await MinimalWebHostTestFactory.RunAsync( +using System.Net; +using System.Net.Http.Headers; +using System.Text.Json.Serialization; +using System.Threading.Tasks; +using Carter; +using Codebelt.Extensions.Carter.AspNetCore.Text.Json; +using Codebelt.Extensions.Carter.Assets; +using Codebelt.Extensions.Xunit; +using Codebelt.Extensions.Xunit.Hosting.AspNetCore; +using Cuemon.Extensions.AspNetCore.Text.Json; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; +using Xunit; + +namespace Codebelt.Extensions.Carter; + +/// +/// Functional tests verifying Carter bootstrapped with as the sole response negotiator. +/// +public class JsonResponseNegotiatorTest : Test +{ + public JsonResponseNegotiatorTest(ITestOutputHelper output) : base(output) + { + } + + [Fact] + public async Task GetStatisticalRegions_ShouldReturnJsonResponse_WhenCarterDefaultsAreDisabled() + { + using var response = await MinimalWebHostTestFactory.RunAsync( services => { services.AddMinimalJsonOptions(o => @@ -37,26 +37,26 @@ public async Task GetStatisticalRegions_ShouldReturnJsonResponse_WhenCarterDefau .WithModule() .WithResponseNegotiator()); services.AddRouting(); - }, - app => - { - app.UseRouting(); - app.UseEndpoints(endpoints => endpoints.MapCarter()); - }, - _ => { }, - async client => - { - client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - return await client.GetAsync("/world/statistical-regions"); - }); - - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.StartsWith("application/json", response.Content.Headers.ContentType?.ToString()); - - var body = await response.Content.ReadAsStringAsync(); - - Assert.NotEmpty(body); - - TestOutput.WriteLine(body); - } + }, + app => + { + app.UseRouting(); + app.UseEndpoints(endpoints => endpoints.MapCarter()); + }, + _ => { }, + async client => + { + client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + return await client.GetAsync("/world/statistical-regions"); + }); + + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.StartsWith("application/json", response.Content.Headers.ContentType?.ToString()); + + var body = await response.Content.ReadAsStringAsync(); + + Assert.NotEmpty(body); + + TestOutput.WriteLine(body); + } } diff --git a/test/Codebelt.Extensions.Carter.FunctionalTests/NewtonsoftJsonNegotiatorTest.cs b/test/Codebelt.Extensions.Carter.FunctionalTests/NewtonsoftJsonNegotiatorTest.cs index b129372..3d11fd8 100644 --- a/test/Codebelt.Extensions.Carter.FunctionalTests/NewtonsoftJsonNegotiatorTest.cs +++ b/test/Codebelt.Extensions.Carter.FunctionalTests/NewtonsoftJsonNegotiatorTest.cs @@ -1,63 +1,63 @@ -using System.Net; -using System.Net.Http.Headers; -using System.Threading.Tasks; -using Carter; -using Codebelt.Extensions.AspNetCore.Newtonsoft.Json.Formatters; -using Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json; -using Codebelt.Extensions.Carter.Assets; -using Codebelt.Extensions.Xunit; -using Codebelt.Extensions.Xunit.Hosting.AspNetCore; -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.DependencyInjection; -using Newtonsoft.Json.Converters; -using Newtonsoft.Json.Serialization; -using Xunit; - -namespace Codebelt.Extensions.Carter; - -/// -/// Functional tests verifying Carter bootstrapped with as the sole response negotiator. -/// -public class NewtonsoftJsonNegotiatorTest : Test -{ - public NewtonsoftJsonNegotiatorTest(ITestOutputHelper output) : base(output) - { - } - - [Fact] - public async Task GetStatisticalRegions_ShouldReturnJsonResponse_WhenCarterDefaultsAreDisabled() - { - using var response = await MinimalWebHostTestFactory.RunAsync( - services => - { - services.AddNewtonsoftJsonFormatterOptions(o => - { - o.Settings.Converters.Insert(0, new StringEnumConverter(new DefaultNamingStrategy(), false)); - }); - services.AddCarter(configurator: c => c - .WithModule() - .WithResponseNegotiator()); - services.AddRouting(); - }, - app => - { - app.UseRouting(); - app.UseEndpoints(endpoints => endpoints.MapCarter()); - }, - _ => { }, - async client => - { - client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - return await client.GetAsync("/world/statistical-regions"); - }); - - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.StartsWith("application/json", response.Content.Headers.ContentType?.ToString()); - - var body = await response.Content.ReadAsStringAsync(); - - Assert.NotEmpty(body); - - TestOutput.WriteLine(body); - } -} +using System.Net; +using System.Net.Http.Headers; +using System.Threading.Tasks; +using Carter; +using Codebelt.Extensions.AspNetCore.Newtonsoft.Json.Formatters; +using Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json; +using Codebelt.Extensions.Carter.Assets; +using Codebelt.Extensions.Xunit; +using Codebelt.Extensions.Xunit.Hosting.AspNetCore; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Serialization; +using Xunit; + +namespace Codebelt.Extensions.Carter; + +/// +/// Functional tests verifying Carter bootstrapped with as the sole response negotiator. +/// +public class NewtonsoftJsonNegotiatorTest : Test +{ + public NewtonsoftJsonNegotiatorTest(ITestOutputHelper output) : base(output) + { + } + + [Fact] + public async Task GetStatisticalRegions_ShouldReturnJsonResponse_WhenCarterDefaultsAreDisabled() + { + using var response = await MinimalWebHostTestFactory.RunAsync( + services => + { + services.AddNewtonsoftJsonFormatterOptions(o => + { + o.Settings.Converters.Insert(0, new StringEnumConverter(new DefaultNamingStrategy(), false)); + }); + services.AddCarter(configurator: c => c + .WithModule() + .WithResponseNegotiator()); + services.AddRouting(); + }, + app => + { + app.UseRouting(); + app.UseEndpoints(endpoints => endpoints.MapCarter()); + }, + _ => { }, + async client => + { + client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + return await client.GetAsync("/world/statistical-regions"); + }); + + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.StartsWith("application/json", response.Content.Headers.ContentType?.ToString()); + + var body = await response.Content.ReadAsStringAsync(); + + Assert.NotEmpty(body); + + TestOutput.WriteLine(body); + } +} diff --git a/test/Codebelt.Extensions.Carter.FunctionalTests/XmlResponseNegotiatorTest.cs b/test/Codebelt.Extensions.Carter.FunctionalTests/XmlResponseNegotiatorTest.cs index cec3a78..f8166ef 100644 --- a/test/Codebelt.Extensions.Carter.FunctionalTests/XmlResponseNegotiatorTest.cs +++ b/test/Codebelt.Extensions.Carter.FunctionalTests/XmlResponseNegotiatorTest.cs @@ -1,61 +1,61 @@ -using System.Net; -using System.Net.Http.Headers; -using System.Threading.Tasks; -using Carter; -using Codebelt.Extensions.Carter.AspNetCore.Xml; -using Codebelt.Extensions.Carter.Assets; -using Codebelt.Extensions.Xunit; -using Codebelt.Extensions.Xunit.Hosting.AspNetCore; -using Cuemon.Extensions.AspNetCore.Xml; -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.DependencyInjection; -using Xunit; - -namespace Codebelt.Extensions.Carter; - -/// -/// Functional tests verifying Carter bootstrapped with as the sole response negotiator. -/// -public class XmlResponseNegotiatorTest : Test -{ - public XmlResponseNegotiatorTest(ITestOutputHelper output) : base(output) - { - } - - [Fact] - public async Task GetStatisticalRegions_ShouldReturnXmlResponse_WhenCarterDefaultsAreDisabled() - { - using var response = await MinimalWebHostTestFactory.RunAsync( - services => - { - services.AddMinimalXmlOptions(o => - { - o.Settings.Writer.Indent = true; - }); - services.AddCarter(configurator: c => c - .WithModule() - .WithResponseNegotiator()); - services.AddRouting(); - }, - app => - { - app.UseRouting(); - app.UseEndpoints(endpoints => endpoints.MapCarter()); - }, - _ => { }, - async client => - { - client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml")); - return await client.GetAsync("/world/statistical-regions"); - }); - - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.StartsWith("application/xml", response.Content.Headers.ContentType?.ToString()); - - var body = await response.Content.ReadAsStringAsync(); - - Assert.NotEmpty(body); - - TestOutput.WriteLine(body); - } -} +using System.Net; +using System.Net.Http.Headers; +using System.Threading.Tasks; +using Carter; +using Codebelt.Extensions.Carter.AspNetCore.Xml; +using Codebelt.Extensions.Carter.Assets; +using Codebelt.Extensions.Xunit; +using Codebelt.Extensions.Xunit.Hosting.AspNetCore; +using Cuemon.Extensions.AspNetCore.Xml; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; +using Xunit; + +namespace Codebelt.Extensions.Carter; + +/// +/// Functional tests verifying Carter bootstrapped with as the sole response negotiator. +/// +public class XmlResponseNegotiatorTest : Test +{ + public XmlResponseNegotiatorTest(ITestOutputHelper output) : base(output) + { + } + + [Fact] + public async Task GetStatisticalRegions_ShouldReturnXmlResponse_WhenCarterDefaultsAreDisabled() + { + using var response = await MinimalWebHostTestFactory.RunAsync( + services => + { + services.AddMinimalXmlOptions(o => + { + o.Settings.Writer.Indent = true; + }); + services.AddCarter(configurator: c => c + .WithModule() + .WithResponseNegotiator()); + services.AddRouting(); + }, + app => + { + app.UseRouting(); + app.UseEndpoints(endpoints => endpoints.MapCarter()); + }, + _ => { }, + async client => + { + client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml")); + return await client.GetAsync("/world/statistical-regions"); + }); + + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.StartsWith("application/xml", response.Content.Headers.ContentType?.ToString()); + + var body = await response.Content.ReadAsStringAsync(); + + Assert.NotEmpty(body); + + TestOutput.WriteLine(body); + } +} diff --git a/test/Codebelt.Extensions.Carter.FunctionalTests/YamlResponseNegotiatorTest.cs b/test/Codebelt.Extensions.Carter.FunctionalTests/YamlResponseNegotiatorTest.cs index a514406..fd5a3c7 100644 --- a/test/Codebelt.Extensions.Carter.FunctionalTests/YamlResponseNegotiatorTest.cs +++ b/test/Codebelt.Extensions.Carter.FunctionalTests/YamlResponseNegotiatorTest.cs @@ -1,58 +1,58 @@ -using System.Net; -using System.Net.Http.Headers; -using System.Threading.Tasks; -using Carter; -using Codebelt.Extensions.AspNetCore.Text.Yaml; -using Codebelt.Extensions.Carter.AspNetCore.Text.Yaml; -using Codebelt.Extensions.Carter.Assets; -using Codebelt.Extensions.Xunit; -using Codebelt.Extensions.Xunit.Hosting.AspNetCore; -using Microsoft.AspNetCore.Builder; -using Microsoft.Extensions.DependencyInjection; -using Xunit; - -namespace Codebelt.Extensions.Carter; - -/// -/// Functional tests verifying Carter bootstrapped with as the sole response negotiator. -/// -public class YamlResponseNegotiatorTest : Test -{ - public YamlResponseNegotiatorTest(ITestOutputHelper output) : base(output) - { - } - - [Fact] - public async Task GetStatisticalRegions_ShouldReturnYamlResponse_WhenCarterDefaultsAreDisabled() - { - using var response = await MinimalWebHostTestFactory.RunAsync( - services => - { - services.AddMinimalYamlOptions(); - services.AddCarter(configurator: c => c - .WithModule() - .WithResponseNegotiator()); - services.AddRouting(); - }, - app => - { - app.UseRouting(); - app.UseEndpoints(endpoints => endpoints.MapCarter()); - }, - _ => { }, - async client => - { - client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/yaml")); - return await client.GetAsync("/world/statistical-regions"); - }); - - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.StartsWith("application/yaml", response.Content.Headers.ContentType?.ToString()); - - var body = await response.Content.ReadAsStringAsync(); - - Assert.NotEmpty(body); - - TestOutput.WriteLine(body); - } -} +using System.Net; +using System.Net.Http.Headers; +using System.Threading.Tasks; +using Carter; +using Codebelt.Extensions.AspNetCore.Text.Yaml; +using Codebelt.Extensions.Carter.AspNetCore.Text.Yaml; +using Codebelt.Extensions.Carter.Assets; +using Codebelt.Extensions.Xunit; +using Codebelt.Extensions.Xunit.Hosting.AspNetCore; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; +using Xunit; + +namespace Codebelt.Extensions.Carter; + +/// +/// Functional tests verifying Carter bootstrapped with as the sole response negotiator. +/// +public class YamlResponseNegotiatorTest : Test +{ + public YamlResponseNegotiatorTest(ITestOutputHelper output) : base(output) + { + } + + [Fact] + public async Task GetStatisticalRegions_ShouldReturnYamlResponse_WhenCarterDefaultsAreDisabled() + { + using var response = await MinimalWebHostTestFactory.RunAsync( + services => + { + services.AddMinimalYamlOptions(); + services.AddCarter(configurator: c => c + .WithModule() + .WithResponseNegotiator()); + services.AddRouting(); + }, + app => + { + app.UseRouting(); + app.UseEndpoints(endpoints => endpoints.MapCarter()); + }, + _ => { }, + async client => + { + client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/yaml")); + return await client.GetAsync("/world/statistical-regions"); + }); + + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.StartsWith("application/yaml", response.Content.Headers.ContentType?.ToString()); + + var body = await response.Content.ReadAsStringAsync(); + + Assert.NotEmpty(body); + + TestOutput.WriteLine(body); + } +} diff --git a/test/Codebelt.Extensions.Carter.Tests/EndpointConventionBuilderExtensionsTest.cs b/test/Codebelt.Extensions.Carter.Tests/EndpointConventionBuilderExtensionsTest.cs index dadc671..188f5ff 100644 --- a/test/Codebelt.Extensions.Carter.Tests/EndpointConventionBuilderExtensionsTest.cs +++ b/test/Codebelt.Extensions.Carter.Tests/EndpointConventionBuilderExtensionsTest.cs @@ -1,98 +1,98 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Codebelt.Extensions.Xunit; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Http.Metadata; -using Microsoft.AspNetCore.Routing; -using Microsoft.AspNetCore.Routing.Patterns; -using Xunit; - -namespace Codebelt.Extensions.Carter -{ - /// - /// Tests for the class. - /// - public class EndpointConventionBuilderExtensionsTest : Test - { - public EndpointConventionBuilderExtensionsTest(ITestOutputHelper output) : base(output) - { - } - - [Fact] - public void Produces_WithTResponse_ShouldAddProducesResponseTypeMetadata() - { - var delegateEndpointBuilder = new FakeEndpointConventionBuilder(); - - delegateEndpointBuilder.Produces(StatusCodes.Status201Created, "application/json", "text/plain"); - - var endpointBuilder = new RouteEndpointBuilder(context => System.Threading.Tasks.Task.CompletedTask, RoutePatternFactory.Parse("/"), 0); - foreach (var convention in delegateEndpointBuilder.Conventions) - { - convention(endpointBuilder); - } - - var typeMetadata = endpointBuilder.Metadata.OfType().FirstOrDefault(); - - Assert.NotNull(typeMetadata); - Assert.Equal(StatusCodes.Status201Created, typeMetadata.StatusCode); - Assert.Equal(typeof(string), typeMetadata.Type); - Assert.Contains("application/json", typeMetadata.ContentTypes); - Assert.Contains("text/plain", typeMetadata.ContentTypes); - } - - [Fact] - public void Produces_WithTResponse_DefaultStatusCode_ShouldAddProducesResponseTypeMetadata() - { - var delegateEndpointBuilder = new FakeEndpointConventionBuilder(); - - delegateEndpointBuilder.Produces(contentTypes: "application/xml"); - - var endpointBuilder = new RouteEndpointBuilder(context => System.Threading.Tasks.Task.CompletedTask, RoutePatternFactory.Parse("/"), 0); - foreach (var convention in delegateEndpointBuilder.Conventions) - { - convention(endpointBuilder); - } - - var typeMetadata = endpointBuilder.Metadata.OfType().FirstOrDefault(); - - Assert.NotNull(typeMetadata); - Assert.Equal(StatusCodes.Status200OK, typeMetadata.StatusCode); - Assert.Equal(typeof(int), typeMetadata.Type); - Assert.Contains("application/xml", typeMetadata.ContentTypes); - } - - [Fact] - public void Produces_WithStatusCode_ShouldAddProducesResponseTypeMetadata() - { - var delegateEndpointBuilder = new FakeEndpointConventionBuilder(); - - delegateEndpointBuilder.Produces(StatusCodes.Status404NotFound); - - var endpointBuilder = new RouteEndpointBuilder(context => System.Threading.Tasks.Task.CompletedTask, RoutePatternFactory.Parse("/"), 0); - foreach (var convention in delegateEndpointBuilder.Conventions) - { - convention(endpointBuilder); - } - - var typeMetadata = endpointBuilder.Metadata.OfType().FirstOrDefault(); - - Assert.NotNull(typeMetadata); - Assert.Equal(StatusCodes.Status404NotFound, typeMetadata.StatusCode); - Assert.Null(typeMetadata.Type); - // ContentTypes might be empty - Assert.Empty(typeMetadata.ContentTypes); - } - - private class FakeEndpointConventionBuilder : IEndpointConventionBuilder - { - public List> Conventions { get; } = []; - - public void Add(Action convention) - { - Conventions.Add(convention); - } - } - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using Codebelt.Extensions.Xunit; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Metadata; +using Microsoft.AspNetCore.Routing; +using Microsoft.AspNetCore.Routing.Patterns; +using Xunit; + +namespace Codebelt.Extensions.Carter +{ + /// + /// Tests for the class. + /// + public class EndpointConventionBuilderExtensionsTest : Test + { + public EndpointConventionBuilderExtensionsTest(ITestOutputHelper output) : base(output) + { + } + + [Fact] + public void Produces_WithTResponse_ShouldAddProducesResponseTypeMetadata() + { + var delegateEndpointBuilder = new FakeEndpointConventionBuilder(); + + delegateEndpointBuilder.Produces(StatusCodes.Status201Created, "application/json", "text/plain"); + + var endpointBuilder = new RouteEndpointBuilder(context => System.Threading.Tasks.Task.CompletedTask, RoutePatternFactory.Parse("/"), 0); + foreach (var convention in delegateEndpointBuilder.Conventions) + { + convention(endpointBuilder); + } + + var typeMetadata = endpointBuilder.Metadata.OfType().FirstOrDefault(); + + Assert.NotNull(typeMetadata); + Assert.Equal(StatusCodes.Status201Created, typeMetadata.StatusCode); + Assert.Equal(typeof(string), typeMetadata.Type); + Assert.Contains("application/json", typeMetadata.ContentTypes); + Assert.Contains("text/plain", typeMetadata.ContentTypes); + } + + [Fact] + public void Produces_WithTResponse_DefaultStatusCode_ShouldAddProducesResponseTypeMetadata() + { + var delegateEndpointBuilder = new FakeEndpointConventionBuilder(); + + delegateEndpointBuilder.Produces(contentTypes: "application/xml"); + + var endpointBuilder = new RouteEndpointBuilder(context => System.Threading.Tasks.Task.CompletedTask, RoutePatternFactory.Parse("/"), 0); + foreach (var convention in delegateEndpointBuilder.Conventions) + { + convention(endpointBuilder); + } + + var typeMetadata = endpointBuilder.Metadata.OfType().FirstOrDefault(); + + Assert.NotNull(typeMetadata); + Assert.Equal(StatusCodes.Status200OK, typeMetadata.StatusCode); + Assert.Equal(typeof(int), typeMetadata.Type); + Assert.Contains("application/xml", typeMetadata.ContentTypes); + } + + [Fact] + public void Produces_WithStatusCode_ShouldAddProducesResponseTypeMetadata() + { + var delegateEndpointBuilder = new FakeEndpointConventionBuilder(); + + delegateEndpointBuilder.Produces(StatusCodes.Status404NotFound); + + var endpointBuilder = new RouteEndpointBuilder(context => System.Threading.Tasks.Task.CompletedTask, RoutePatternFactory.Parse("/"), 0); + foreach (var convention in delegateEndpointBuilder.Conventions) + { + convention(endpointBuilder); + } + + var typeMetadata = endpointBuilder.Metadata.OfType().FirstOrDefault(); + + Assert.NotNull(typeMetadata); + Assert.Equal(StatusCodes.Status404NotFound, typeMetadata.StatusCode); + Assert.Null(typeMetadata.Type); + // ContentTypes might be empty + Assert.Empty(typeMetadata.ContentTypes); + } + + private class FakeEndpointConventionBuilder : IEndpointConventionBuilder + { + public List> Conventions { get; } = []; + + public void Add(Action convention) + { + Conventions.Add(convention); + } + } + } +} diff --git a/test/Codebelt.Extensions.Carter.Tests/Response/ConfigurableResponseNegotiatorTest.cs b/test/Codebelt.Extensions.Carter.Tests/Response/ConfigurableResponseNegotiatorTest.cs index 0aa3dbd..d8671fe 100644 --- a/test/Codebelt.Extensions.Carter.Tests/Response/ConfigurableResponseNegotiatorTest.cs +++ b/test/Codebelt.Extensions.Carter.Tests/Response/ConfigurableResponseNegotiatorTest.cs @@ -1,149 +1,149 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using Codebelt.Extensions.Xunit; -using Cuemon.Configuration; -using Cuemon.Diagnostics; -using Cuemon.Net.Http; -using Cuemon.Runtime.Serialization.Formatters; -using Microsoft.AspNetCore.Http; -using Microsoft.Net.Http.Headers; -using Xunit; - -namespace Codebelt.Extensions.Carter.Response -{ - public class ConfigurableResponseNegotiatorTest : Test - { - public ConfigurableResponseNegotiatorTest(ITestOutputHelper output) : base(output) - { - } - - [Fact] - public void CanHandle_ShouldReturnTrue_WhenAcceptHeaderMatches() - { - var options = new FakeOptions(); - options.SupportedMediaTypes = new[] { new System.Net.Http.Headers.MediaTypeHeaderValue("application/json") }; - var negotiator = new FakeResponseNegotiator(options); - - var result = negotiator.CanHandle(new MediaTypeHeaderValue("application/json")); - - Assert.True(result); - Assert.Equal("application/json", negotiator.ContentType); - } - - [Fact] - public void CanHandle_ShouldReturnFalse_WhenAcceptHeaderDoesNotMatch() - { - var options = new FakeOptions(); - options.SupportedMediaTypes = new[] { new System.Net.Http.Headers.MediaTypeHeaderValue("application/xml") }; - var negotiator = new FakeResponseNegotiator(options); - - var result = negotiator.CanHandle(new MediaTypeHeaderValue("application/json")); - - Assert.False(result); - } - - [Fact] - public void GetEncoding_ShouldReturnPreferredEncoding_FromRequest() - { - var options = new FakeOptions(); - var negotiator = new FakeResponseNegotiator(options); - - var context = new DefaultHttpContext(); - context.Request.Headers.Append("Accept-Charset", "utf-16;q=1.0, utf-8;q=0.8"); - - var encoding = negotiator.GetEncoding(context.Request); - - Assert.Equal(Encoding.Unicode, encoding); - } - - [Fact] - public void GetEncoding_ShouldReturnDefaultEncoding_WhenNoMatch() - { - var options = new FakeOptions(); - var negotiator = new FakeResponseNegotiator(options); - - var context = new DefaultHttpContext(); - context.Request.Headers.Append("Accept-Charset", "unknown-encoding;q=1.0"); - - var encoding = negotiator.GetEncoding(context.Request); - - Assert.Equal("utf-8", encoding.WebName); - } - - [Fact] - public async Task Handle_ShouldWriteToResponse() - { - var options = new FakeOptions(); - options.SupportedMediaTypes = new[] { new System.Net.Http.Headers.MediaTypeHeaderValue("text/plain") }; - var negotiator = new FakeResponseNegotiator(options); - - var context = new DefaultHttpContext(); - var ms = new MemoryStream(); - context.Response.Body = ms; - - // Simulate CanHandle to set ContentType - negotiator.CanHandle(new MediaTypeHeaderValue("text/plain")); - - await negotiator.Handle(context.Request, context.Response, "Hello World", CancellationToken.None); - - var result = Encoding.UTF8.GetString(ms.ToArray()); - - Assert.Equal("Hello World", result); - Assert.Equal("text/plain; charset=utf-8", context.Response.ContentType); - } - } - - public class FakeResponseNegotiator : ConfigurableResponseNegotiator - { - public FakeResponseNegotiator(FakeOptions options) : base(options) - { - } - - protected override Encoding GetDefaultEncoding() - { - return new UTF8Encoding(false); - } - - public override StreamFormatter GetFormatter() - { - return new FakeStreamFormatter(o => { }); - } - } - - public class FakeOptions : IExceptionDescriptorOptions, IContentNegotiation, IValidatableParameterObject - { - public FaultSensitivityDetails SensitivityDetails { get; set; } - - public IReadOnlyCollection SupportedMediaTypes { get; set; } = new List(); - - public void ValidateOptions() - { - } - } - +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Codebelt.Extensions.Xunit; +using Cuemon.Configuration; +using Cuemon.Diagnostics; +using Cuemon.Net.Http; +using Cuemon.Runtime.Serialization.Formatters; +using Microsoft.AspNetCore.Http; +using Microsoft.Net.Http.Headers; +using Xunit; + +namespace Codebelt.Extensions.Carter.Response +{ + public class ConfigurableResponseNegotiatorTest : Test + { + public ConfigurableResponseNegotiatorTest(ITestOutputHelper output) : base(output) + { + } + + [Fact] + public void CanHandle_ShouldReturnTrue_WhenAcceptHeaderMatches() + { + var options = new FakeOptions(); + options.SupportedMediaTypes = new[] { new System.Net.Http.Headers.MediaTypeHeaderValue("application/json") }; + var negotiator = new FakeResponseNegotiator(options); + + var result = negotiator.CanHandle(new MediaTypeHeaderValue("application/json")); + + Assert.True(result); + Assert.Equal("application/json", negotiator.ContentType); + } + + [Fact] + public void CanHandle_ShouldReturnFalse_WhenAcceptHeaderDoesNotMatch() + { + var options = new FakeOptions(); + options.SupportedMediaTypes = new[] { new System.Net.Http.Headers.MediaTypeHeaderValue("application/xml") }; + var negotiator = new FakeResponseNegotiator(options); + + var result = negotiator.CanHandle(new MediaTypeHeaderValue("application/json")); + + Assert.False(result); + } + + [Fact] + public void GetEncoding_ShouldReturnPreferredEncoding_FromRequest() + { + var options = new FakeOptions(); + var negotiator = new FakeResponseNegotiator(options); + + var context = new DefaultHttpContext(); + context.Request.Headers.Append("Accept-Charset", "utf-16;q=1.0, utf-8;q=0.8"); + + var encoding = negotiator.GetEncoding(context.Request); + + Assert.Equal(Encoding.Unicode, encoding); + } + + [Fact] + public void GetEncoding_ShouldReturnDefaultEncoding_WhenNoMatch() + { + var options = new FakeOptions(); + var negotiator = new FakeResponseNegotiator(options); + + var context = new DefaultHttpContext(); + context.Request.Headers.Append("Accept-Charset", "unknown-encoding;q=1.0"); + + var encoding = negotiator.GetEncoding(context.Request); + + Assert.Equal("utf-8", encoding.WebName); + } + + [Fact] + public async Task Handle_ShouldWriteToResponse() + { + var options = new FakeOptions(); + options.SupportedMediaTypes = new[] { new System.Net.Http.Headers.MediaTypeHeaderValue("text/plain") }; + var negotiator = new FakeResponseNegotiator(options); + + var context = new DefaultHttpContext(); + var ms = new MemoryStream(); + context.Response.Body = ms; + + // Simulate CanHandle to set ContentType + negotiator.CanHandle(new MediaTypeHeaderValue("text/plain")); + + await negotiator.Handle(context.Request, context.Response, "Hello World", CancellationToken.None); + + var result = Encoding.UTF8.GetString(ms.ToArray()); + + Assert.Equal("Hello World", result); + Assert.Equal("text/plain; charset=utf-8", context.Response.ContentType); + } + } + + public class FakeResponseNegotiator : ConfigurableResponseNegotiator + { + public FakeResponseNegotiator(FakeOptions options) : base(options) + { + } + + protected override Encoding GetDefaultEncoding() + { + return new UTF8Encoding(false); + } + + public override StreamFormatter GetFormatter() + { + return new FakeStreamFormatter(o => { }); + } + } + + public class FakeOptions : IExceptionDescriptorOptions, IContentNegotiation, IValidatableParameterObject + { + public FaultSensitivityDetails SensitivityDetails { get; set; } + + public IReadOnlyCollection SupportedMediaTypes { get; set; } = new List(); + + public void ValidateOptions() + { + } + } + public class FakeStreamFormatter : StreamFormatter - { - public FakeStreamFormatter(Action setup) : base(setup) - { - } - - public override Stream Serialize(object source, Type objectType) - { - var ms = new MemoryStream(); - var writer = new StreamWriter(ms); - writer.Write(source?.ToString()); - writer.Flush(); - ms.Position = 0; - return ms; - } - - public override object Deserialize(Stream stream, Type objectType) - { - throw new NotImplementedException(); - } - } -} + { + public FakeStreamFormatter(Action setup) : base(setup) + { + } + + public override Stream Serialize(object source, Type objectType) + { + var ms = new MemoryStream(); + var writer = new StreamWriter(ms); + writer.Write(source?.ToString()); + writer.Flush(); + ms.Position = 0; + return ms; + } + + public override object Deserialize(Stream stream, Type objectType) + { + throw new NotImplementedException(); + } + } +} diff --git a/testenvironments.json b/testenvironments.json index 59d1b66..587b2ef 100644 --- a/testenvironments.json +++ b/testenvironments.json @@ -7,9 +7,9 @@ "wslDistribution": "Ubuntu-24.04" }, { - "name": "Docker-Ubuntu (net10)", + "name": "Docker-Ubuntu", "type": "docker", - "dockerImage": "codebeltnet/ubuntu-testrunner:10" + "dockerImage": "codebeltnet/ubuntu-testrunner:8-9-10-11" } ] }