From a8685bb27b775160b2face1226e5b1d8bdd261b3 Mon Sep 17 00:00:00 2001 From: jhmoon Date: Sun, 1 Sep 2024 20:12:11 +0900 Subject: [PATCH 1/9] add endpoint for list of deployment models --- .../Endpoints/PlaygroundEndpointUrls.cs | 8 +++++ .../Endpoints/PlaygroundEndpoints.cs | 29 +++++++++++++++++++ .../Models/DeploymentModelDetails.cs | 23 +++++++++++++++ src/AzureOpenAIProxy.ApiApp/Program.cs | 1 + 4 files changed, 61 insertions(+) create mode 100644 src/AzureOpenAIProxy.ApiApp/Models/DeploymentModelDetails.cs diff --git a/src/AzureOpenAIProxy.ApiApp/Endpoints/PlaygroundEndpointUrls.cs b/src/AzureOpenAIProxy.ApiApp/Endpoints/PlaygroundEndpointUrls.cs index b8ccbd2b..13faee0e 100644 --- a/src/AzureOpenAIProxy.ApiApp/Endpoints/PlaygroundEndpointUrls.cs +++ b/src/AzureOpenAIProxy.ApiApp/Endpoints/PlaygroundEndpointUrls.cs @@ -12,4 +12,12 @@ public static class PlaygroundEndpointUrls /// - GET method for listing all events /// public const string Events = "/events"; + + /// + /// Declares the deployment models list endpoint. + /// + /// + /// - GET method for listing all deployment models + /// + public const string DeploymentModels = "/events/{eventId}/deployment-models"; } diff --git a/src/AzureOpenAIProxy.ApiApp/Endpoints/PlaygroundEndpoints.cs b/src/AzureOpenAIProxy.ApiApp/Endpoints/PlaygroundEndpoints.cs index c21d6029..62647e1c 100644 --- a/src/AzureOpenAIProxy.ApiApp/Endpoints/PlaygroundEndpoints.cs +++ b/src/AzureOpenAIProxy.ApiApp/Endpoints/PlaygroundEndpoints.cs @@ -32,4 +32,33 @@ public static RouteHandlerBuilder AddListEvents(this WebApplication app) return builder; } + + + /// + /// Adds the get deployment models by event endpoint + /// + /// instance. + /// Returns instance. + public static RouteHandlerBuilder AddListDeploymentModels(this WebApplication app) + { + // Todo: Issue #170 https://github.com/aliencube/azure-openai-sdk-proxy/issues/170 + var builder = app.MapGet(PlaygroundEndpointUrls.DeploymentModels, () => + { + return Results.Ok(); + }) + .Produces>(statusCode: StatusCodes.Status200OK, contentType: "application/json") + .Produces(statusCode: StatusCodes.Status401Unauthorized) + .Produces(statusCode: StatusCodes.Status500InternalServerError, contentType: "text/plain") + .WithTags("events") + .WithName("GetDeploymentModel") + .WithOpenApi(operation => + { + operation.Summary = "Gets all deployment models"; + operation.Description = "This endpoint gets all deployment models avaliable"; + + return operation; + }); + + return builder; + } } \ No newline at end of file diff --git a/src/AzureOpenAIProxy.ApiApp/Models/DeploymentModelDetails.cs b/src/AzureOpenAIProxy.ApiApp/Models/DeploymentModelDetails.cs new file mode 100644 index 00000000..4969b921 --- /dev/null +++ b/src/AzureOpenAIProxy.ApiApp/Models/DeploymentModelDetails.cs @@ -0,0 +1,23 @@ +using System.Text.Json.Serialization; + +/// +/// This represent the event detail data for response by admin event endpoint. +/// +public class DeploymentModelDetails +{ + /// + /// Gets or sets the deployment id of the model. + /// + [JsonRequired] + public int? Id { get; set; } + + /// + /// Gets or sets the deployment model name. + /// + public string? Name { get; set; } + + /// + /// Gets or sets the version of deployment model. + /// + public string? version { get; set; } +} \ No newline at end of file diff --git a/src/AzureOpenAIProxy.ApiApp/Program.cs b/src/AzureOpenAIProxy.ApiApp/Program.cs index 4c5a0e55..4258e259 100644 --- a/src/AzureOpenAIProxy.ApiApp/Program.cs +++ b/src/AzureOpenAIProxy.ApiApp/Program.cs @@ -51,6 +51,7 @@ // Playground endpoints app.AddListEvents(); +app.AddListDeploymentModels(); // Admin endpoints app.AddNewAdminEvent(); From 084492697f7f5a3ddf41b89c2c20a3ca8a290467 Mon Sep 17 00:00:00 2001 From: jhmoon Date: Sun, 1 Sep 2024 21:26:54 +0900 Subject: [PATCH 2/9] fix typo --- src/AzureOpenAIProxy.ApiApp/Endpoints/PlaygroundEndpoints.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AzureOpenAIProxy.ApiApp/Endpoints/PlaygroundEndpoints.cs b/src/AzureOpenAIProxy.ApiApp/Endpoints/PlaygroundEndpoints.cs index 62647e1c..3230a76a 100644 --- a/src/AzureOpenAIProxy.ApiApp/Endpoints/PlaygroundEndpoints.cs +++ b/src/AzureOpenAIProxy.ApiApp/Endpoints/PlaygroundEndpoints.cs @@ -35,7 +35,7 @@ public static RouteHandlerBuilder AddListEvents(this WebApplication app) /// - /// Adds the get deployment models by event endpoint + /// Adds the get deployment models /// /// instance. /// Returns instance. @@ -50,7 +50,7 @@ public static RouteHandlerBuilder AddListDeploymentModels(this WebApplication ap .Produces(statusCode: StatusCodes.Status401Unauthorized) .Produces(statusCode: StatusCodes.Status500InternalServerError, contentType: "text/plain") .WithTags("events") - .WithName("GetDeploymentModel") + .WithName("GetDeploymentModels") .WithOpenApi(operation => { operation.Summary = "Gets all deployment models"; From 549bd959b5709d3e27f4d235e4a653ea805f2454 Mon Sep 17 00:00:00 2001 From: jhmoon Date: Mon, 2 Sep 2024 01:00:41 +0900 Subject: [PATCH 3/9] add path variable to api doc --- .../Endpoints/PlaygroundEndpoints.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/AzureOpenAIProxy.ApiApp/Endpoints/PlaygroundEndpoints.cs b/src/AzureOpenAIProxy.ApiApp/Endpoints/PlaygroundEndpoints.cs index 3230a76a..5690d26d 100644 --- a/src/AzureOpenAIProxy.ApiApp/Endpoints/PlaygroundEndpoints.cs +++ b/src/AzureOpenAIProxy.ApiApp/Endpoints/PlaygroundEndpoints.cs @@ -1,3 +1,5 @@ +using Microsoft.AspNetCore.Mvc; + namespace AzureOpenAIProxy.ApiApp.Endpoints; /// @@ -42,7 +44,9 @@ public static RouteHandlerBuilder AddListEvents(this WebApplication app) public static RouteHandlerBuilder AddListDeploymentModels(this WebApplication app) { // Todo: Issue #170 https://github.com/aliencube/azure-openai-sdk-proxy/issues/170 - var builder = app.MapGet(PlaygroundEndpointUrls.DeploymentModels, () => + var builder = app.MapGet(PlaygroundEndpointUrls.DeploymentModels, ( + [FromRoute] string eventId + ) => { return Results.Ok(); }) From 6d9356f636c82c55a051f58ac2433c1f575287d2 Mon Sep 17 00:00:00 2001 From: jhmoon Date: Sat, 7 Sep 2024 11:51:17 +0900 Subject: [PATCH 4/9] Add test code for getDeploymentModels open api endpoint --- .../Endpoints/PlaygroundEndpoints.cs | 1 + .../GetDeploymentModelsOpenApiTest.cs | 148 ++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 test/AzureOpenAIProxy.AppHost.Tests/ApiApp/Endpoints/GetDeploymentModelsOpenApiTest.cs diff --git a/src/AzureOpenAIProxy.ApiApp/Endpoints/PlaygroundEndpoints.cs b/src/AzureOpenAIProxy.ApiApp/Endpoints/PlaygroundEndpoints.cs index 5690d26d..91c01b8f 100644 --- a/src/AzureOpenAIProxy.ApiApp/Endpoints/PlaygroundEndpoints.cs +++ b/src/AzureOpenAIProxy.ApiApp/Endpoints/PlaygroundEndpoints.cs @@ -52,6 +52,7 @@ [FromRoute] string eventId }) .Produces>(statusCode: StatusCodes.Status200OK, contentType: "application/json") .Produces(statusCode: StatusCodes.Status401Unauthorized) + .Produces(statusCode: StatusCodes.Status404NotFound) .Produces(statusCode: StatusCodes.Status500InternalServerError, contentType: "text/plain") .WithTags("events") .WithName("GetDeploymentModels") diff --git a/test/AzureOpenAIProxy.AppHost.Tests/ApiApp/Endpoints/GetDeploymentModelsOpenApiTest.cs b/test/AzureOpenAIProxy.AppHost.Tests/ApiApp/Endpoints/GetDeploymentModelsOpenApiTest.cs new file mode 100644 index 00000000..44894360 --- /dev/null +++ b/test/AzureOpenAIProxy.AppHost.Tests/ApiApp/Endpoints/GetDeploymentModelsOpenApiTest.cs @@ -0,0 +1,148 @@ +using System.Text.Json; + +using AzureOpenAIProxy.AppHost.Tests.Fixtures; + +using FluentAssertions; + +namespace AzureOpenAIProxy.AppHost.Tests.ApiApp.Endpoints; + +public class GetDeploymentModelsOpenApiTests(AspireAppHostFixture host) : IClassFixture +{ + [Fact] + public async Task Given_Resource_When_Invoked_Endpoint_Then_It_Should_Return_Path() + { + // Arrange + using var httpClient = host.App!.CreateHttpClient("apiapp"); + + // Act + var json = await httpClient.GetStringAsync("/swagger/v1.0.0/swagger.json"); + var apiDocument = JsonSerializer.Deserialize(json); + + // Assert + var result = apiDocument!.RootElement.GetProperty("paths") + .TryGetProperty("/events/{eventId}/deployment-models", out var property) ? property : default; + result.ValueKind.Should().Be(JsonValueKind.Object); + } + + [Fact] + public async Task Given_Resource_When_Invoked_Endpoint_Then_It_Should_Return_Verb() + { + // Arrange + using var httpClient = host.App!.CreateHttpClient("apiapp"); + + // Act + var json = await httpClient.GetStringAsync("/swagger/v1.0.0/swagger.json"); + var apiDocument = JsonSerializer.Deserialize(json); + + // Assert + var result = apiDocument!.RootElement.GetProperty("paths") + .GetProperty("/events/{eventId}/deployment-models") + .TryGetProperty("get", out var property) ? property : default; + result.ValueKind.Should().Be(JsonValueKind.Object); + } + + [Theory] + [InlineData("events")] + public async Task Given_Resource_When_Invoked_Endpoint_Then_It_Should_Return_Tags(string tag) + { + // Arrange + using var httpClient = host.App!.CreateHttpClient("apiapp"); + + // Act + var json = await httpClient.GetStringAsync("/swagger/v1.0.0/swagger.json"); + var apiDocument = JsonSerializer.Deserialize(json); + + // Assert + var result = apiDocument!.RootElement.GetProperty("paths") + .GetProperty("/events/{eventId}/deployment-models") + .GetProperty("get") + .TryGetProperty("tags", out var property) ? property : default; + result.ValueKind.Should().Be(JsonValueKind.Array); + result.EnumerateArray().Select(p => p.GetString()).Should().Contain(tag); + } + + [Theory] + [InlineData("summary")] + [InlineData("description")] + [InlineData("operationId")] + public async Task Given_Resource_When_Invoked_Endpoint_Then_It_Should_Return_Value(string attribute) + { + // Arrange + using var httpClient = host.App!.CreateHttpClient("apiapp"); + + // Act + var json = await httpClient.GetStringAsync("/swagger/v1.0.0/swagger.json"); + var apiDocument = JsonSerializer.Deserialize(json); + + // Assert + var result = apiDocument!.RootElement.GetProperty("paths") + .GetProperty("/events/{eventId}/deployment-models") + .GetProperty("get") + .TryGetProperty(attribute, out var property) ? property : default; + result.ValueKind.Should().Be(JsonValueKind.String); + } + + + [Theory] + [InlineData("eventId")] + public async Task Given_Resource_When_Invoked_Endpoint_Then_It_Should_Return_Path_Parameter(string name) + { + // Arrange + using var httpClient = host.App!.CreateHttpClient("apiapp"); + + // Act + var json = await httpClient.GetStringAsync("/swagger/v1.0.0/swagger.json"); + var openapi = JsonSerializer.Deserialize(json); + + // Assert + var result = openapi!.RootElement.GetProperty("paths") + .GetProperty("/events/{eventId}/deployment-models") + .GetProperty("get") + .GetProperty("parameters") + .EnumerateArray() + .Where(p => p.GetProperty("in").GetString() == "path") + .Select(p => p.GetProperty("name").ToString()); + result.Should().Contain(name); + } + + [Theory] + [InlineData("responses")] + public async Task Given_Resource_When_Invoked_Endpoint_Then_It_Should_Return_Object(string attribute) + { + // Arrange + using var httpClient = host.App!.CreateHttpClient("apiapp"); + + // Act + var json = await httpClient.GetStringAsync("/swagger/v1.0.0/swagger.json"); + var apiDocument = JsonSerializer.Deserialize(json); + + // Assert + var result = apiDocument!.RootElement.GetProperty("paths") + .GetProperty("/events/{eventId}/deployment-models") + .GetProperty("get") + .TryGetProperty(attribute, out var property) ? property : default; + result.ValueKind.Should().Be(JsonValueKind.Object); + } + + [Theory] + [InlineData("200")] + [InlineData("401")] + [InlineData("404")] + public async Task Given_Resource_When_Invoked_Endpoint_Then_It_Should_Return_Response(string attribute) + { + // Arrange + using var httpClient = host.App!.CreateHttpClient("apiapp"); + + // Act + var json = await httpClient.GetStringAsync("/swagger/v1.0.0/swagger.json"); + var apiDocument = JsonSerializer.Deserialize(json); + + // Assert + var result = apiDocument!.RootElement.GetProperty("paths") + .GetProperty("/events/{eventId}/deployment-models") + .GetProperty("get") + .GetProperty("responses") + .TryGetProperty(attribute, out var property) ? property : default; + result.ValueKind.Should().Be(JsonValueKind.Object); + } +} \ No newline at end of file From 99e9c303f50b59ca77f3271d2628bd4df2385eca Mon Sep 17 00:00:00 2001 From: jhmoon Date: Sat, 7 Sep 2024 11:54:33 +0900 Subject: [PATCH 5/9] Fix field name to meet the coding convention --- src/AzureOpenAIProxy.ApiApp/Models/DeploymentModelDetails.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AzureOpenAIProxy.ApiApp/Models/DeploymentModelDetails.cs b/src/AzureOpenAIProxy.ApiApp/Models/DeploymentModelDetails.cs index 4969b921..1af12f35 100644 --- a/src/AzureOpenAIProxy.ApiApp/Models/DeploymentModelDetails.cs +++ b/src/AzureOpenAIProxy.ApiApp/Models/DeploymentModelDetails.cs @@ -19,5 +19,5 @@ public class DeploymentModelDetails /// /// Gets or sets the version of deployment model. /// - public string? version { get; set; } + public string? Version { get; set; } } \ No newline at end of file From 4f2befcba933c8f5c3f33fba00d3b27768559ea4 Mon Sep 17 00:00:00 2001 From: jhmoon Date: Sat, 7 Sep 2024 14:41:31 +0900 Subject: [PATCH 6/9] Fix DeploymentModelDetails class to have only Name field --- .../Models/DeploymentModelDetails.cs | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/AzureOpenAIProxy.ApiApp/Models/DeploymentModelDetails.cs b/src/AzureOpenAIProxy.ApiApp/Models/DeploymentModelDetails.cs index 1af12f35..ab2ef317 100644 --- a/src/AzureOpenAIProxy.ApiApp/Models/DeploymentModelDetails.cs +++ b/src/AzureOpenAIProxy.ApiApp/Models/DeploymentModelDetails.cs @@ -5,19 +5,10 @@ /// public class DeploymentModelDetails { - /// - /// Gets or sets the deployment id of the model. - /// - [JsonRequired] - public int? Id { get; set; } - /// /// Gets or sets the deployment model name. /// - public string? Name { get; set; } + [JsonRequired] + public string Name { get; set; } = string.Empty; - /// - /// Gets or sets the version of deployment model. - /// - public string? Version { get; set; } } \ No newline at end of file From 831ef9d9975d4ed33f1a461b448323ef6e9a03d6 Mon Sep 17 00:00:00 2001 From: jhmoon Date: Mon, 9 Sep 2024 19:30:59 +0900 Subject: [PATCH 7/9] Add response entity test --- .../GetDeploymentModelsOpenApiTest.cs | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/test/AzureOpenAIProxy.AppHost.Tests/ApiApp/Endpoints/GetDeploymentModelsOpenApiTest.cs b/test/AzureOpenAIProxy.AppHost.Tests/ApiApp/Endpoints/GetDeploymentModelsOpenApiTest.cs index 44894360..7d9b649a 100644 --- a/test/AzureOpenAIProxy.AppHost.Tests/ApiApp/Endpoints/GetDeploymentModelsOpenApiTest.cs +++ b/test/AzureOpenAIProxy.AppHost.Tests/ApiApp/Endpoints/GetDeploymentModelsOpenApiTest.cs @@ -4,6 +4,9 @@ using FluentAssertions; +using IdentityModel.Client; + + namespace AzureOpenAIProxy.AppHost.Tests.ApiApp.Endpoints; public class GetDeploymentModelsOpenApiTests(AspireAppHostFixture host) : IClassFixture @@ -128,6 +131,7 @@ public async Task Given_Resource_When_Invoked_Endpoint_Then_It_Should_Return_Obj [InlineData("200")] [InlineData("401")] [InlineData("404")] + [InlineData("500")] public async Task Given_Resource_When_Invoked_Endpoint_Then_It_Should_Return_Response(string attribute) { // Arrange @@ -145,4 +149,41 @@ public async Task Given_Resource_When_Invoked_Endpoint_Then_It_Should_Return_Res .TryGetProperty(attribute, out var property) ? property : default; result.ValueKind.Should().Be(JsonValueKind.Object); } + + public static IEnumerable DeploymentModelAttributeData => + [ + ["name", true, "string"] + ]; + + [Theory] + [MemberData(nameof(DeploymentModelAttributeData))] + public async Task Given_DeploymentModel_When_Invoked_Endpoint_Then_It_Should_Return_Type(string attribute, bool isRequired, string type) + { + // Arrange + using var httpClient = host.App!.CreateHttpClient("apiapp"); + await host.ResourceNotificationService.WaitForResourceAsync("apiapp", KnownResourceStates.Running) + .WaitAsync(TimeSpan.FromSeconds(30)); + + // Act + var json = await httpClient.GetStringAsync("/swagger/v1.0.0/swagger.json"); + var openapi = JsonSerializer.Deserialize(json); + + // Assert + var result = openapi!.RootElement.GetProperty("components") + .GetProperty("schemas") + .GetProperty("DeploymentModelDetails") + .GetProperty("properties") + .GetProperty(attribute); + + result.TryGetString("type").Should().Be(type); + + if (isRequired) + { + var requiredProperties = openapi.RootElement.GetProperty("components") + .GetProperty("schemas") + .GetProperty("DeploymentModelDetails") + .GetProperty("required"); + requiredProperties.EnumerateArray().Any(p => p.GetString() == attribute).Should().BeTrue(); + } + } } \ No newline at end of file From ac237a72da6e6cad27dc1a996fe6a366631ed331 Mon Sep 17 00:00:00 2001 From: jhmoon Date: Sat, 14 Sep 2024 15:36:08 +0900 Subject: [PATCH 8/9] =?UTF-8?q?Add=20properties=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GetDeploymentModelsOpenApiTest.cs | 76 +++++++++++++++---- 1 file changed, 63 insertions(+), 13 deletions(-) diff --git a/test/AzureOpenAIProxy.AppHost.Tests/ApiApp/Endpoints/GetDeploymentModelsOpenApiTest.cs b/test/AzureOpenAIProxy.AppHost.Tests/ApiApp/Endpoints/GetDeploymentModelsOpenApiTest.cs index 7d9b649a..8e9edefa 100644 --- a/test/AzureOpenAIProxy.AppHost.Tests/ApiApp/Endpoints/GetDeploymentModelsOpenApiTest.cs +++ b/test/AzureOpenAIProxy.AppHost.Tests/ApiApp/Endpoints/GetDeploymentModelsOpenApiTest.cs @@ -150,19 +150,59 @@ public async Task Given_Resource_When_Invoked_Endpoint_Then_It_Should_Return_Res result.ValueKind.Should().Be(JsonValueKind.Object); } + + [Fact] + public async Task Given_Resource_When_Invoked_Endpoint_Then_It_Should_Return_Model() + { + // Arrange + using var httpClient = host.App!.CreateHttpClient("apiapp"); + + // Act + var json = await httpClient.GetStringAsync("/swagger/v1.0.0/swagger.json"); + var openapi = JsonSerializer.Deserialize(json); + + // Assert + var result = openapi!.RootElement.GetProperty("components") + .GetProperty("schemas") + .TryGetProperty("DeploymentModelDetails", out var property) ? property : default; + result.ValueKind.Should().Be(JsonValueKind.Object); + } + public static IEnumerable DeploymentModelAttributeData => [ ["name", true, "string"] ]; + + [Theory] + [MemberData(nameof(DeploymentModelAttributeData))] + public async Task Given_Resource_When_Invoked_Endpoint_Then_It_Should_Return_Required(string attribute, bool isRequired, string type) + { + // Arrange + using var httpClient = host.App!.CreateHttpClient("apiapp"); + + var isReq = isRequired; + var typeStr = type; + + // Act + var json = await httpClient.GetStringAsync("/swagger/v1.0.0/swagger.json"); + var openapi = JsonSerializer.Deserialize(json); + + // Assert + var result = openapi!.RootElement.GetProperty("components") + .GetProperty("schemas") + .GetProperty("DeploymentModelDetails") + .TryGetStringArray("required") + .ToList(); + result.Contains(attribute).Should().Be(isRequired); + } + [Theory] [MemberData(nameof(DeploymentModelAttributeData))] - public async Task Given_DeploymentModel_When_Invoked_Endpoint_Then_It_Should_Return_Type(string attribute, bool isRequired, string type) + public async Task Given_Resource_When_Invoked_Endpoint_Then_It_Should_Return_Property(string attribute, bool isRequired, string type) { // Arrange using var httpClient = host.App!.CreateHttpClient("apiapp"); - await host.ResourceNotificationService.WaitForResourceAsync("apiapp", KnownResourceStates.Running) - .WaitAsync(TimeSpan.FromSeconds(30)); // Act var json = await httpClient.GetStringAsync("/swagger/v1.0.0/swagger.json"); @@ -173,17 +213,27 @@ await host.ResourceNotificationService.WaitForResourceAsync("apiapp", KnownResou .GetProperty("schemas") .GetProperty("DeploymentModelDetails") .GetProperty("properties") - .GetProperty(attribute); + .TryGetProperty(attribute, out var property) ? property : default; + result.ValueKind.Should().Be(JsonValueKind.Object); + } - result.TryGetString("type").Should().Be(type); + [Theory] + [MemberData(nameof(DeploymentModelAttributeData))] + public async Task Given_Resource_When_Invoked_Endpoint_Then_It_Should_Return_Type(string attribute, bool isRequired, string type) + { + // Arrange + using var httpClient = host.App!.CreateHttpClient("apiapp"); - if (isRequired) - { - var requiredProperties = openapi.RootElement.GetProperty("components") - .GetProperty("schemas") - .GetProperty("DeploymentModelDetails") - .GetProperty("required"); - requiredProperties.EnumerateArray().Any(p => p.GetString() == attribute).Should().BeTrue(); - } + // Act + var json = await httpClient.GetStringAsync("/swagger/v1.0.0/swagger.json"); + var openapi = JsonSerializer.Deserialize(json); + + // Assert + var result = openapi!.RootElement.GetProperty("components") + .GetProperty("schemas") + .GetProperty("DeploymentModelDetails") + .GetProperty("properties") + .GetProperty(attribute); + result.TryGetString("type").Should().Be(type); } } \ No newline at end of file From 86ee842359acd5ecc0cd2ce26fb8a1d0f0c0b0fe Mon Sep 17 00:00:00 2001 From: jhmoon Date: Tue, 17 Sep 2024 22:55:28 +0900 Subject: [PATCH 9/9] Refactor memberData to inlineData --- .../GetDeploymentModelsOpenApiTest.cs | 21 ++++++------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/test/AzureOpenAIProxy.AppHost.Tests/ApiApp/Endpoints/GetDeploymentModelsOpenApiTest.cs b/test/AzureOpenAIProxy.AppHost.Tests/ApiApp/Endpoints/GetDeploymentModelsOpenApiTest.cs index 8e9edefa..51e72085 100644 --- a/test/AzureOpenAIProxy.AppHost.Tests/ApiApp/Endpoints/GetDeploymentModelsOpenApiTest.cs +++ b/test/AzureOpenAIProxy.AppHost.Tests/ApiApp/Endpoints/GetDeploymentModelsOpenApiTest.cs @@ -168,22 +168,13 @@ public async Task Given_Resource_When_Invoked_Endpoint_Then_It_Should_Return_Mod result.ValueKind.Should().Be(JsonValueKind.Object); } - public static IEnumerable DeploymentModelAttributeData => - [ - ["name", true, "string"] - ]; - - [Theory] - [MemberData(nameof(DeploymentModelAttributeData))] - public async Task Given_Resource_When_Invoked_Endpoint_Then_It_Should_Return_Required(string attribute, bool isRequired, string type) + [InlineData("name", true)] + public async Task Given_Resource_When_Invoked_Endpoint_Then_It_Should_Return_Required(string attribute, bool isRequired) { // Arrange using var httpClient = host.App!.CreateHttpClient("apiapp"); - var isReq = isRequired; - var typeStr = type; - // Act var json = await httpClient.GetStringAsync("/swagger/v1.0.0/swagger.json"); var openapi = JsonSerializer.Deserialize(json); @@ -198,8 +189,8 @@ public async Task Given_Resource_When_Invoked_Endpoint_Then_It_Should_Return_Req } [Theory] - [MemberData(nameof(DeploymentModelAttributeData))] - public async Task Given_Resource_When_Invoked_Endpoint_Then_It_Should_Return_Property(string attribute, bool isRequired, string type) + [InlineData("name")] + public async Task Given_Resource_When_Invoked_Endpoint_Then_It_Should_Return_Property(string attribute) { // Arrange using var httpClient = host.App!.CreateHttpClient("apiapp"); @@ -218,8 +209,8 @@ public async Task Given_Resource_When_Invoked_Endpoint_Then_It_Should_Return_Pro } [Theory] - [MemberData(nameof(DeploymentModelAttributeData))] - public async Task Given_Resource_When_Invoked_Endpoint_Then_It_Should_Return_Type(string attribute, bool isRequired, string type) + [InlineData("name", "string")] + public async Task Given_Resource_When_Invoked_Endpoint_Then_It_Should_Return_Type(string attribute, string type) { // Arrange using var httpClient = host.App!.CreateHttpClient("apiapp");