diff --git a/source/AAS.TwinEngine.DataEngine.ModuleTests/Api/Services/Description/DescriptionControllerTests.cs b/source/AAS.TwinEngine.DataEngine.ModuleTests/Api/Services/Description/DescriptionControllerTests.cs new file mode 100644 index 00000000..5d48b1da --- /dev/null +++ b/source/AAS.TwinEngine.DataEngine.ModuleTests/Api/Services/Description/DescriptionControllerTests.cs @@ -0,0 +1,102 @@ +using System.Net; +using System.Net.Http.Json; +using System.Text.Json.Nodes; + +using AAS.TwinEngine.DataEngine.ApplicationLogic.Exceptions.Base; +using AAS.TwinEngine.DataEngine.ApplicationLogic.Exceptions.Infrastructure; +using AAS.TwinEngine.DataEngine.ApplicationLogic.Services.Description; +using AAS.TwinEngine.DataEngine.ApplicationLogic.Services.Plugin; +using AAS.TwinEngine.DataEngine.ApplicationLogic.Services.Plugin.Providers; +using AAS.TwinEngine.DataEngine.DomainModel.Description; +using AAS.TwinEngine.DataEngine.ModuleTests.Common; + +using Microsoft.Extensions.DependencyInjection; + +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace AAS.TwinEngine.DataEngine.ModuleTests.Api.Services.Description; + +public abstract class DescriptionControllerTests : IDisposable +{ + private readonly ConfigTestFactory _factory; + private readonly IDescriptionService _mockDescriptionService; + private readonly HttpClient _client; + private readonly IPluginManifestProvider _mockPluginManifestProvider; + private readonly IPluginManifestConflictHandler _mockPluginManifestConflictHandler; + + protected DescriptionControllerTests(string configDir) + { + _mockDescriptionService = Substitute.For(); + + _mockPluginManifestProvider = Substitute.For(); + _mockPluginManifestConflictHandler = Substitute.For(); + + _factory = new ConfigTestFactory(configDir, services => + { + _ = services.AddSingleton(_mockDescriptionService); + _ =services.AddSingleton(_mockPluginManifestProvider); + _ = services.AddSingleton(_mockPluginManifestConflictHandler); + }); + + _client = _factory.CreateClient(); + _ = _mockPluginManifestConflictHandler.Manifests.Returns([]); + } + + public void Dispose() + { + _client.Dispose(); + _factory.Dispose(); + GC.SuppressFinalize(this); + } + + [Fact] + public async Task GetDescriptor_ReturnsOkAsync() + { + _ = _mockDescriptionService + .GetDescriptor(Arg.Any()) + .Returns(new ServiceDescription + { + Profiles = + [ + "https://admin-shell.io/aas/API/3/1/AssetAdministrationShellRegistryServiceSpecification/SSP-002" + ] + }); + + var response = await _client.GetAsync("/description"); + + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + + var json = await response.Content.ReadFromJsonAsync(); + + Assert.NotNull(json); + } + + [Fact] + public async Task GetDescriptor_WhenForbidden_Returns403Async() + { + _ = _mockDescriptionService + .GetDescriptor(Arg.Any()) + .Throws(new ForbiddenException()); + + var response = await _client.GetAsync("/description"); + + Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode); + } + + [Fact] + public async Task GetDescriptor_WhenInternalServerError_Returns500Async() + { + _ = _mockDescriptionService + .GetDescriptor(Arg.Any()) + .Throws(new ResponseParsingException()); + + var response = await _client.GetAsync("/description"); + + Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode); + } +} + +public class DescriptionControllerTestsV1Config() : DescriptionControllerTests("v1-config"); + +public class DescriptionControllerTestsV2Config() : DescriptionControllerTests("v2-config"); diff --git a/source/AAS.TwinEngine.DataEngine.ModuleTests/Api/Services/Discovery/DiscoveryControllerTests.cs b/source/AAS.TwinEngine.DataEngine.ModuleTests/Api/Services/Discovery/DiscoveryControllerTests.cs index 8c1e0034..dd8f8cbd 100644 --- a/source/AAS.TwinEngine.DataEngine.ModuleTests/Api/Services/Discovery/DiscoveryControllerTests.cs +++ b/source/AAS.TwinEngine.DataEngine.ModuleTests/Api/Services/Discovery/DiscoveryControllerTests.cs @@ -1,7 +1,5 @@ using System.Net; using System.Net.Http.Json; -using System.Text; -using System.Text.Json; using System.Text.Json.Nodes; using AAS.TwinEngine.DataEngine.Api.Discovery.Requests; @@ -13,9 +11,6 @@ using AAS.TwinEngine.DataEngine.ModuleTests.Common; using AAS.TwinEngine.DataEngine.ServiceConfiguration.Config; -using AasCore.Aas3_1; - -using Microsoft.AspNetCore.WebUtilities; using Microsoft.Extensions.DependencyInjection; using NSubstitute; @@ -177,29 +172,6 @@ private void SetupPluginHttpClient(string pluginResponse) const string HttpClientName = $"{HttpClientNames.PluginDataProviderPrefix}TestPlugin1"; _ = _httpClientFactory.CreateClient(HttpClientName).Returns(httpClient); } - - private void SetupPluginHttpClientNotCalled() - { - const string HttpClientName = $"{HttpClientNames.PluginDataProviderPrefix}TestPlugin1"; - _ = _httpClientFactory.CreateClient(HttpClientName).Returns((HttpClient)null!); - } - - private void SetupTemplateProvider() - { - _ = _mockTemplateService.GetShellTemplateAsync(Arg.Any(), Arg.Any()) - .Returns(callInfo => new AssetAdministrationShell( - callInfo.ArgAt(0), - new AssetInformation(AssetKind.Instance)) - { - Submodels = - [ - new Reference(ReferenceTypes.ModelReference, - [ - new Key(KeyTypes.Submodel, "urn:example:sm:nameplate:001") - ]) - ] - }); - } } public class DiscoveryControllerTestsV2Config() : DiscoveryControllerTests("v2-config"); diff --git a/source/AAS.TwinEngine.DataEngine.UnitTests/Api/Description/DescriptionControllerTests.cs b/source/AAS.TwinEngine.DataEngine.UnitTests/Api/Description/DescriptionControllerTests.cs new file mode 100644 index 00000000..f110196f --- /dev/null +++ b/source/AAS.TwinEngine.DataEngine.UnitTests/Api/Description/DescriptionControllerTests.cs @@ -0,0 +1,80 @@ +using AAS.TwinEngine.DataEngine.Api.Description; +using AAS.TwinEngine.DataEngine.Api.Description.Handler; +using AAS.TwinEngine.DataEngine.Api.Description.Responses; +using AAS.TwinEngine.DataEngine.ApplicationLogic.Exceptions.Base; + +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; + +using NSubstitute; +using NSubstitute.ExceptionExtensions; + +namespace AAS.TwinEngine.DataEngine.UnitTests.Api.Description; + +public class DescriptionControllerTests +{ + private readonly IDescriptionHandler _handler; + private readonly DescriptionController _sut; + + public DescriptionControllerTests() + { + var logger = Substitute.For>(); + _handler = Substitute.For(); + + _sut = new DescriptionController(logger, _handler); + } + + [Fact] + public void GetDescriptor_ReturnsOkResult() + { + var expected = new ServiceDescriptionDto + { + Profiles = + [ + "https://admin-shell.io/aas/API/3/1/AssetAdministrationShellRegistryServiceSpecification/SSP-002", + "https://admin-shell.io/aas/API/3/1/AssetAdministrationShellRepositoryServiceSpecification/SSP-002", + "https://admin-shell.io/aas/API/3/1/SubmodelRegistryServiceSpecification/SSP-002", + "https://admin-shell.io/aas/API/3/1/SubmodelRepositoryServiceSpecification/SSP-002", + "https://admin-shell.io/aas/API/3/1/DiscoveryServiceSpecification/SSP-002" + ] + }; + + _handler + .GetDescriptor(Arg.Any()) + .Returns(expected); + + var result = _sut.GetDescriptor(CancellationToken.None); + + var okResult = Assert.IsType(result.Result); + var dto = Assert.IsType(okResult.Value); + + Assert.Equal(expected, dto); + } + + [Fact] + public void GetDescriptor_ReturnsOkWithNull_WhenHandlerReturnsNull() + { + _handler + .GetDescriptor(Arg.Any()) + .Returns((ServiceDescriptionDto?)null); + + var result = _sut.GetDescriptor(CancellationToken.None); + + var okResult = Assert.IsType(result.Result); + + Assert.Null(okResult.Value); + } + + [Fact] + public void GetDescriptor_ThrowsForbiddenException() + { + _handler + .GetDescriptor(Arg.Any()) + .Throws(new ForbiddenException("Forbidden")); + + var ex = Record.Exception(() => + _sut.GetDescriptor(CancellationToken.None)); + + Assert.IsType(ex); + } +} diff --git a/source/AAS.TwinEngine.DataEngine.UnitTests/Api/Description/Handler/DescriptionHandlerTests.cs b/source/AAS.TwinEngine.DataEngine.UnitTests/Api/Description/Handler/DescriptionHandlerTests.cs new file mode 100644 index 00000000..fb6f74b1 --- /dev/null +++ b/source/AAS.TwinEngine.DataEngine.UnitTests/Api/Description/Handler/DescriptionHandlerTests.cs @@ -0,0 +1,62 @@ +using AAS.TwinEngine.DataEngine.Api.Description.Handler; +using AAS.TwinEngine.DataEngine.ApplicationLogic.Services.Description; +using AAS.TwinEngine.DataEngine.DomainModel.Description; + +using Microsoft.Extensions.Logging; + +using NSubstitute; + +namespace AAS.TwinEngine.DataEngine.UnitTests.Api.Description.Handler; + +public class DescriptionHandlerTests +{ + private readonly ILogger _logger; + private readonly IDescriptionService _descriptionService; + private readonly DescriptionHandler _sut; + + public DescriptionHandlerTests() + { + _logger = Substitute.For>(); + _descriptionService = Substitute.For(); + + _sut = new DescriptionHandler(_logger, _descriptionService); + } + + [Fact] + public void GetDescriptor_ReturnsExpectedDto() + { + var descriptor = new ServiceDescription + { + Profiles = + [ + "https://admin-shell.io/aas/API/3/1/AssetAdministrationShellRegistryServiceSpecification/SSP-002", + "https://admin-shell.io/aas/API/3/1/AssetAdministrationShellRepositoryServiceSpecification/SSP-002", + "https://admin-shell.io/aas/API/3/1/SubmodelRegistryServiceSpecification/SSP-002", + "https://admin-shell.io/aas/API/3/1/SubmodelRepositoryServiceSpecification/SSP-002", + "https://admin-shell.io/aas/API/3/1/DiscoveryServiceSpecification/SSP-002" + ] + }; + + _descriptionService + .GetDescriptor(Arg.Any()) + .Returns(descriptor); + + var result = _sut.GetDescriptor(CancellationToken.None); + + Assert.NotNull(result); + Assert.Equal(descriptor.Profiles, result.Profiles); + } + + [Fact] + public void GetDescriptor_CallsServiceOnce() + { + _descriptionService + .GetDescriptor(Arg.Any()) + .Returns(new ServiceDescription()); + + _sut.GetDescriptor(CancellationToken.None); + + _descriptionService.Received(1) + .GetDescriptor(CancellationToken.None); + } +} diff --git a/source/AAS.TwinEngine.DataEngine.UnitTests/Api/Description/MappingProfiles/ServiceDescriptionMapperProfileTests.cs b/source/AAS.TwinEngine.DataEngine.UnitTests/Api/Description/MappingProfiles/ServiceDescriptionMapperProfileTests.cs new file mode 100644 index 00000000..d2cd288a --- /dev/null +++ b/source/AAS.TwinEngine.DataEngine.UnitTests/Api/Description/MappingProfiles/ServiceDescriptionMapperProfileTests.cs @@ -0,0 +1,40 @@ +using AAS.TwinEngine.DataEngine.Api.Description.MappingProfiles; +using AAS.TwinEngine.DataEngine.DomainModel.Description; + +namespace AAS.TwinEngine.DataEngine.UnitTests.Api.Description.MappingProfiles; + +public class ServiceDescriptionMapperProfileTests +{ + [Fact] + public void ToDto_WithProfiles_ReturnsMappedDto() + { + var serviceDescription = new ServiceDescription + { + Profiles = + [ + "https://admin-shell.io/aas/API/3/1/AssetAdministrationShellRegistryServiceSpecification/SSP-002", + "https://admin-shell.io/aas/API/3/1/SubmodelRegistryServiceSpecification/SSP-002" + ] + }; + + var result = serviceDescription.ToDto(); + + Assert.NotNull(result); + Assert.Equal(serviceDescription.Profiles, result.Profiles); + } + + [Fact] + public void ToDto_WithNullProfiles_ReturnsEmptyProfilesCollection() + { + var serviceDescription = new ServiceDescription + { + Profiles = null + }; + + var result = serviceDescription.ToDto(); + + Assert.NotNull(result); + Assert.NotNull(result.Profiles); + Assert.Empty(result.Profiles); + } +} diff --git a/source/AAS.TwinEngine.DataEngine.UnitTests/ApplicationLogic/Services/Description/DescriptionServiceTests.cs b/source/AAS.TwinEngine.DataEngine.UnitTests/ApplicationLogic/Services/Description/DescriptionServiceTests.cs new file mode 100644 index 00000000..b89e6144 --- /dev/null +++ b/source/AAS.TwinEngine.DataEngine.UnitTests/ApplicationLogic/Services/Description/DescriptionServiceTests.cs @@ -0,0 +1,28 @@ +using AAS.TwinEngine.DataEngine.ApplicationLogic.Services.Description; + +namespace AAS.TwinEngine.DataEngine.UnitTests.ApplicationLogic.Services.Description; + +public class DescriptionServiceTests +{ + private static readonly string[] ExpectedProfiles = + [ + "https://admin-shell.io/aas/API/3/1/AssetAdministrationShellRegistryServiceSpecification/SSP-002", + "https://admin-shell.io/aas/API/3/1/AssetAdministrationShellRepositoryServiceSpecification/SSP-002", + "https://admin-shell.io/aas/API/3/1/SubmodelRegistryServiceSpecification/SSP-002", + "https://admin-shell.io/aas/API/3/1/SubmodelRepositoryServiceSpecification/SSP-002", + "https://admin-shell.io/aas/API/3/1/DiscoveryServiceSpecification/SSP-002" + ]; + + [Fact] + public void GetDescriptor_WhenCalled_ReturnsAllFiveSspProfiles() + { + var sut = new DescriptionService(); + + var result = sut.GetDescriptor(CancellationToken.None); + + Assert.NotNull(result); + Assert.NotNull(result.Profiles); + Assert.Equal(5, result.Profiles!.Count); + Assert.Equal(ExpectedProfiles, result.Profiles); + } +} diff --git a/source/AAS.TwinEngine.DataEngine/Api/Description/DescriptionController.cs b/source/AAS.TwinEngine.DataEngine/Api/Description/DescriptionController.cs new file mode 100644 index 00000000..5c135397 --- /dev/null +++ b/source/AAS.TwinEngine.DataEngine/Api/Description/DescriptionController.cs @@ -0,0 +1,39 @@ +using System.Net; + +using AAS.TwinEngine.DataEngine.Api.Description.Handler; +using AAS.TwinEngine.DataEngine.Api.Description.Responses; +using AAS.TwinEngine.DataEngine.ApplicationLogic.Exceptions.Responses; + +using Asp.Versioning; + +using Microsoft.AspNetCore.Mvc; + +using NSwag.Annotations; + +namespace AAS.TwinEngine.DataEngine.Api.Description; + +[ApiController] +[Route("description")] +[OpenApiTags("Description API")] +[ApiVersion(1)] +public class DescriptionController( + ILogger logger, + IDescriptionHandler descriptionHandler) : ControllerBase +{ + /// + /// Returns the self-describing information of a network resource (ServiceDescription) + /// + /// Requested Description + /// Forbidden + [HttpGet("")] + [ProducesResponseType(typeof(ServiceDescriptionDto), (int)HttpStatusCode.OK)] + [ProducesResponseType(typeof(ServiceErrorResponse), (int)HttpStatusCode.Forbidden)] + public ActionResult GetDescriptor(CancellationToken cancellationToken) + { + logger.LogInformation("Get Description"); + + var response = descriptionHandler.GetDescriptor(cancellationToken); + + return Ok(response); + } +} diff --git a/source/AAS.TwinEngine.DataEngine/Api/Description/Handler/DescriptionHandler.cs b/source/AAS.TwinEngine.DataEngine/Api/Description/Handler/DescriptionHandler.cs new file mode 100644 index 00000000..3181bb15 --- /dev/null +++ b/source/AAS.TwinEngine.DataEngine/Api/Description/Handler/DescriptionHandler.cs @@ -0,0 +1,19 @@ +using AAS.TwinEngine.DataEngine.Api.Description.MappingProfiles; +using AAS.TwinEngine.DataEngine.Api.Description.Responses; +using AAS.TwinEngine.DataEngine.ApplicationLogic.Services.Description; + +namespace AAS.TwinEngine.DataEngine.Api.Description.Handler; + +public class DescriptionHandler( + ILogger logger, + IDescriptionService descriptionService) : IDescriptionHandler +{ + public ServiceDescriptionDto GetDescriptor(CancellationToken cancellationToken) + { + logger.LogInformation("Start executing get request for descriptor"); + + var descriptor = descriptionService.GetDescriptor(cancellationToken); + + return descriptor.ToDto(); + } +} diff --git a/source/AAS.TwinEngine.DataEngine/Api/Description/Handler/IDescriptionHandler.cs b/source/AAS.TwinEngine.DataEngine/Api/Description/Handler/IDescriptionHandler.cs new file mode 100644 index 00000000..6c31e1e3 --- /dev/null +++ b/source/AAS.TwinEngine.DataEngine/Api/Description/Handler/IDescriptionHandler.cs @@ -0,0 +1,8 @@ +using AAS.TwinEngine.DataEngine.Api.Description.Responses; + +namespace AAS.TwinEngine.DataEngine.Api.Description.Handler; + +public interface IDescriptionHandler +{ + ServiceDescriptionDto GetDescriptor(CancellationToken cancellationToken); +} diff --git a/source/AAS.TwinEngine.DataEngine/Api/Description/MappingProfiles/ServiceDescriptionMapperProfile.cs b/source/AAS.TwinEngine.DataEngine/Api/Description/MappingProfiles/ServiceDescriptionMapperProfile.cs new file mode 100644 index 00000000..3ca45fd7 --- /dev/null +++ b/source/AAS.TwinEngine.DataEngine/Api/Description/MappingProfiles/ServiceDescriptionMapperProfile.cs @@ -0,0 +1,15 @@ +using AAS.TwinEngine.DataEngine.Api.Description.Responses; +using AAS.TwinEngine.DataEngine.DomainModel.Description; + +namespace AAS.TwinEngine.DataEngine.Api.Description.MappingProfiles; + +public static class ServiceDescriptionMapperProfile +{ + public static ServiceDescriptionDto ToDto(this ServiceDescription serviceDescription) + { + return new ServiceDescriptionDto + { + Profiles = serviceDescription.Profiles ?? [] + }; + } +} diff --git a/source/AAS.TwinEngine.DataEngine/Api/Description/Responses/ServiceDescriptionDto.cs b/source/AAS.TwinEngine.DataEngine/Api/Description/Responses/ServiceDescriptionDto.cs new file mode 100644 index 00000000..98f394a6 --- /dev/null +++ b/source/AAS.TwinEngine.DataEngine/Api/Description/Responses/ServiceDescriptionDto.cs @@ -0,0 +1,18 @@ +using System.Text.Json.Serialization; + +using NJsonSchema.Annotations; + +namespace AAS.TwinEngine.DataEngine.Api.Description.Responses; + +public class ServiceDescriptionDto +{ + [JsonPropertyName("profiles")] + [JsonSchemaExtensionData( + "example", + new[] + { + "https://admin-shell.io/aas/API/3/0/AssetAdministrationShellRegistryServiceSpecification/SSP-002", + "https://admin-shell.io/aas/API/3/0/SubmodelRegistryServiceSpecification/SSP-002" + })] + public IList? Profiles { get; init; } +} diff --git a/source/AAS.TwinEngine.DataEngine/ApplicationLogic/Services/Description/DescriptionService.cs b/source/AAS.TwinEngine.DataEngine/ApplicationLogic/Services/Description/DescriptionService.cs new file mode 100644 index 00000000..9d9be383 --- /dev/null +++ b/source/AAS.TwinEngine.DataEngine/ApplicationLogic/Services/Description/DescriptionService.cs @@ -0,0 +1,17 @@ +using AAS.TwinEngine.DataEngine.DomainModel.Description; + +namespace AAS.TwinEngine.DataEngine.ApplicationLogic.Services.Description; + +public class DescriptionService : IDescriptionService +{ + private static readonly string[] SupportedProfiles = + [ + "https://admin-shell.io/aas/API/3/1/AssetAdministrationShellRegistryServiceSpecification/SSP-002", + "https://admin-shell.io/aas/API/3/1/AssetAdministrationShellRepositoryServiceSpecification/SSP-002", + "https://admin-shell.io/aas/API/3/1/SubmodelRegistryServiceSpecification/SSP-002", + "https://admin-shell.io/aas/API/3/1/SubmodelRepositoryServiceSpecification/SSP-002", + "https://admin-shell.io/aas/API/3/1/DiscoveryServiceSpecification/SSP-002" + ]; + + public ServiceDescription GetDescriptor(CancellationToken cancellationToken) => new() { Profiles = SupportedProfiles }; +} diff --git a/source/AAS.TwinEngine.DataEngine/ApplicationLogic/Services/Description/IDescriptionService.cs b/source/AAS.TwinEngine.DataEngine/ApplicationLogic/Services/Description/IDescriptionService.cs new file mode 100644 index 00000000..8d95a500 --- /dev/null +++ b/source/AAS.TwinEngine.DataEngine/ApplicationLogic/Services/Description/IDescriptionService.cs @@ -0,0 +1,8 @@ +using AAS.TwinEngine.DataEngine.DomainModel.Description; + +namespace AAS.TwinEngine.DataEngine.ApplicationLogic.Services.Description; + +public interface IDescriptionService +{ + ServiceDescription GetDescriptor(CancellationToken cancellationToken); +} diff --git a/source/AAS.TwinEngine.DataEngine/DomainModel/Description/ServiceDescription.cs b/source/AAS.TwinEngine.DataEngine/DomainModel/Description/ServiceDescription.cs new file mode 100644 index 00000000..74f149d1 --- /dev/null +++ b/source/AAS.TwinEngine.DataEngine/DomainModel/Description/ServiceDescription.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace AAS.TwinEngine.DataEngine.DomainModel.Description; + +public class ServiceDescription +{ + [JsonPropertyName("profiles")] + public IList? Profiles { get; init; } +} diff --git a/source/AAS.TwinEngine.DataEngine/ServiceConfiguration/ApplicationDependencyInjectionExtensions.cs b/source/AAS.TwinEngine.DataEngine/ServiceConfiguration/ApplicationDependencyInjectionExtensions.cs index 6609c909..88f37335 100644 --- a/source/AAS.TwinEngine.DataEngine/ServiceConfiguration/ApplicationDependencyInjectionExtensions.cs +++ b/source/AAS.TwinEngine.DataEngine/ServiceConfiguration/ApplicationDependencyInjectionExtensions.cs @@ -1,11 +1,13 @@ using AAS.TwinEngine.DataEngine.Api.AasRegistry.Handler; using AAS.TwinEngine.DataEngine.Api.AasRepository.Handler; +using AAS.TwinEngine.DataEngine.Api.Description.Handler; using AAS.TwinEngine.DataEngine.Api.Discovery.Handler; using AAS.TwinEngine.DataEngine.Api.SubmodelRegistry.Handler; using AAS.TwinEngine.DataEngine.Api.SubmodelRepository.Handler; using AAS.TwinEngine.DataEngine.ApplicationLogic.Exceptions; using AAS.TwinEngine.DataEngine.ApplicationLogic.Services.AasRegistry; using AAS.TwinEngine.DataEngine.ApplicationLogic.Services.AasRepository; +using AAS.TwinEngine.DataEngine.ApplicationLogic.Services.Description; using AAS.TwinEngine.DataEngine.ApplicationLogic.Services.Discovery; using AAS.TwinEngine.DataEngine.ApplicationLogic.Services.Plugin; using AAS.TwinEngine.DataEngine.ApplicationLogic.Services.SubmodelRegistry; @@ -33,6 +35,8 @@ public static void ConfigureApplication(this IServiceCollection services, IConfi _ = services.AddScoped(); _ = services.AddScoped(); _ = services.AddScoped(); + _ = services.AddScoped(); + _ = services.AddScoped(); _ = services.AddScoped(); _ = services.AddScoped(); _ = services.AddScoped(); diff --git a/source/AAS.TwinEngine.Plugin.TestPlugin.PlaywrightTests/AAS.TwinEngine.Plugin.TestPlugin.PlaywrightTests.csproj b/source/AAS.TwinEngine.Plugin.TestPlugin.PlaywrightTests/AAS.TwinEngine.Plugin.TestPlugin.PlaywrightTests.csproj index 0b36de1c..cf81cbfc 100644 --- a/source/AAS.TwinEngine.Plugin.TestPlugin.PlaywrightTests/AAS.TwinEngine.Plugin.TestPlugin.PlaywrightTests.csproj +++ b/source/AAS.TwinEngine.Plugin.TestPlugin.PlaywrightTests/AAS.TwinEngine.Plugin.TestPlugin.PlaywrightTests.csproj @@ -42,6 +42,9 @@ Always + + Always + Always diff --git a/source/AAS.TwinEngine.Plugin.TestPlugin.PlaywrightTests/Description/DescriptionTests.cs b/source/AAS.TwinEngine.Plugin.TestPlugin.PlaywrightTests/Description/DescriptionTests.cs new file mode 100644 index 00000000..912ea10c --- /dev/null +++ b/source/AAS.TwinEngine.Plugin.TestPlugin.PlaywrightTests/Description/DescriptionTests.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.Json; + +namespace AAS.TwinEngine.Plugin.TestPlugin.PlaywrightTests.Description; + +/// +/// Tests for Description endpoints +/// +public class DescriptionTests : ApiTestBase +{ + [Fact] + public async Task GetDescription_ShouldReturnSuccess_ContentAsExpected() + { + // Arrange + const string url = "/description"; + + // Act + var response = await ApiContext.GetAsync(url); + + // Assert + AssertSuccessResponse(response); + + var content = await response.TextAsync(); + Assert.False(string.IsNullOrEmpty(content)); + + var json = JsonDocument.Parse(content); + Assert.NotNull(json); + + await CompareJsonAsync(json, Path.Combine(Directory.GetCurrentDirectory(), "Description", "TestData", "GetDescription_Expected.json")); + } +} diff --git a/source/AAS.TwinEngine.Plugin.TestPlugin.PlaywrightTests/Description/TestData/GetDescription_Expected.json b/source/AAS.TwinEngine.Plugin.TestPlugin.PlaywrightTests/Description/TestData/GetDescription_Expected.json new file mode 100644 index 00000000..f0ea28f7 --- /dev/null +++ b/source/AAS.TwinEngine.Plugin.TestPlugin.PlaywrightTests/Description/TestData/GetDescription_Expected.json @@ -0,0 +1,9 @@ +{ + "profiles": [ + "https://admin-shell.io/aas/API/3/1/AssetAdministrationShellRegistryServiceSpecification/SSP-002", + "https://admin-shell.io/aas/API/3/1/AssetAdministrationShellRepositoryServiceSpecification/SSP-002", + "https://admin-shell.io/aas/API/3/1/SubmodelRegistryServiceSpecification/SSP-002", + "https://admin-shell.io/aas/API/3/1/SubmodelRepositoryServiceSpecification/SSP-002", + "https://admin-shell.io/aas/API/3/1/DiscoveryServiceSpecification/SSP-002" + ] +}