From cf1cf0ca7727c3f2451c635337cb53592b9a0e3f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 20 Aug 2024 12:37:20 +0200 Subject: [PATCH 1/2] chore(deps): update nuget non-major dependencies (main) (#727) * chore(deps): update nuget non-major dependencies * Renames argument `token` -> `cancellationToken` --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Daniel Skovli --- src/Altinn.App.Api/Altinn.App.Api.csproj | 2 +- src/Altinn.App.Core/Altinn.App.Core.csproj | 2 +- .../Features/Maskinporten/MaskinportenClient.cs | 4 ++-- test/Altinn.App.Api.Tests/Altinn.App.Api.Tests.csproj | 6 +++--- test/Altinn.App.Common.Tests/Altinn.App.Common.Tests.csproj | 2 +- test/Altinn.App.Core.Tests/Altinn.App.Core.Tests.csproj | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Altinn.App.Api/Altinn.App.Api.csproj b/src/Altinn.App.Api/Altinn.App.Api.csproj index 3c00263cf..586e0d0bf 100644 --- a/src/Altinn.App.Api/Altinn.App.Api.csproj +++ b/src/Altinn.App.Api/Altinn.App.Api.csproj @@ -25,7 +25,7 @@ - + diff --git a/src/Altinn.App.Core/Altinn.App.Core.csproj b/src/Altinn.App.Core/Altinn.App.Core.csproj index c283a66fc..0712646d7 100644 --- a/src/Altinn.App.Core/Altinn.App.Core.csproj +++ b/src/Altinn.App.Core/Altinn.App.Core.csproj @@ -19,7 +19,7 @@ - + diff --git a/src/Altinn.App.Core/Features/Maskinporten/MaskinportenClient.cs b/src/Altinn.App.Core/Features/Maskinporten/MaskinportenClient.cs index bb8115136..d5459799d 100644 --- a/src/Altinn.App.Core/Features/Maskinporten/MaskinportenClient.cs +++ b/src/Altinn.App.Core/Features/Maskinporten/MaskinportenClient.cs @@ -87,7 +87,7 @@ public async Task GetAccessToken( HasSetExpiration: false ); }, - token: cancellationToken, + cancellationToken: cancellationToken, options: _defaultCacheExpiration ); @@ -99,7 +99,7 @@ await _tokenCache.SetAsync( cacheKey, result, options: CacheExpiry(result.Expiration), - token: cancellationToken + cancellationToken: cancellationToken ); } diff --git a/test/Altinn.App.Api.Tests/Altinn.App.Api.Tests.csproj b/test/Altinn.App.Api.Tests/Altinn.App.Api.Tests.csproj index abab50751..ca6de8bff 100644 --- a/test/Altinn.App.Api.Tests/Altinn.App.Api.Tests.csproj +++ b/test/Altinn.App.Api.Tests/Altinn.App.Api.Tests.csproj @@ -9,9 +9,9 @@ - - - + + + diff --git a/test/Altinn.App.Common.Tests/Altinn.App.Common.Tests.csproj b/test/Altinn.App.Common.Tests/Altinn.App.Common.Tests.csproj index a60c95be7..a9159603b 100644 --- a/test/Altinn.App.Common.Tests/Altinn.App.Common.Tests.csproj +++ b/test/Altinn.App.Common.Tests/Altinn.App.Common.Tests.csproj @@ -16,7 +16,7 @@ - + diff --git a/test/Altinn.App.Core.Tests/Altinn.App.Core.Tests.csproj b/test/Altinn.App.Core.Tests/Altinn.App.Core.Tests.csproj index 24247e2f8..50b3331ac 100644 --- a/test/Altinn.App.Core.Tests/Altinn.App.Core.Tests.csproj +++ b/test/Altinn.App.Core.Tests/Altinn.App.Core.Tests.csproj @@ -42,8 +42,8 @@ - - + + From 1a630c9ad2438786043726068c399d9d3746b0fd Mon Sep 17 00:00:00 2001 From: Johannes Haukland <42615991+HauklandJ@users.noreply.github.com> Date: Wed, 21 Aug 2024 14:31:00 +0200 Subject: [PATCH 2/2] Feat/679 named pdf prereqs (#732) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add language constants * fix: naming violations * refactor: pdf service * test: existing pdf service functionality * refactor: simplify, rm unused usings * refactor: add readonly modifier * refactor: remove httpcontext dependency for helper methods * fix: rm typo * test: add profilemock to test * test: rm unused using * mark languageconst class as static to prevent instantiation * Bokmål -> Nb, Nynorsk -> Nn, English -> En * format changes --- .../Controllers/OptionsController.cs | 3 +- .../Controllers/TextsController.cs | 5 +- .../Extensions/HostBuilderExtensions.cs | 2 +- .../Helpers/ValidContributorHelper.cs | 2 +- .../FakePaymentProcessor.cs | 2 +- .../Models/NetsCheckoutConsumerDetails.cs | 2 +- .../Internal/Language/LanguageConst.cs | 8 + .../Internal/Pdf/PdfService.cs | 64 +++--- .../Controllers/DataController_PatchTests.cs | 25 +-- .../Controllers/OptionsControllerTests.cs | 3 +- .../Controllers/PdfControllerTests.cs | 54 ++--- .../Controllers/TextsControllerTests.cs | 13 +- .../ValidateControllerValidateDataTests.cs | 3 +- .../Helpers/ValidContributorHelperTests.cs | 2 +- .../DataLists/NullDataListProviderTest.cs | 3 +- .../NullInstanceDataListProviderTest.cs | 3 +- .../Altinn2OptionsCacheTests.cs | 13 +- .../Altinn2Provider/Altinn2OptionsTests.cs | 21 +- .../Options/AppOptionsFactoryTests.cs | 3 +- .../Features/Options/JoinedAppOptionsTests.cs | 48 ++--- .../NullInstanceAppOptionsProviderTests.cs | 3 +- .../Features/Payment/PaymentServiceTests.cs | 30 +-- .../Payment/Providers/Nets/NetsMapperTests.cs | 2 +- .../Nets/NetsPaymentProcessorTests.cs | 7 +- .../Implementation/AppResourcesSITests.cs | 24 +-- .../Implementation/TextClientTest.cs | 83 ++++---- .../Internal/Pdf/PdfServiceTests.cs | 197 +++++++++++++++--- 27 files changed, 412 insertions(+), 213 deletions(-) create mode 100644 src/Altinn.App.Core/Internal/Language/LanguageConst.cs diff --git a/src/Altinn.App.Api/Controllers/OptionsController.cs b/src/Altinn.App.Api/Controllers/OptionsController.cs index 10cf50000..6f79586e2 100644 --- a/src/Altinn.App.Api/Controllers/OptionsController.cs +++ b/src/Altinn.App.Api/Controllers/OptionsController.cs @@ -1,6 +1,7 @@ using Altinn.App.Core.Constants; using Altinn.App.Core.Extensions; using Altinn.App.Core.Features.Options; +using Altinn.App.Core.Internal.Language; using Altinn.App.Core.Models; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; @@ -84,7 +85,7 @@ [FromQuery] Dictionary queryParams AppOptions appOptions = await _appOptionsService.GetOptionsAsync( instanceIdentifier, optionsId, - language ?? "nb", + language ?? LanguageConst.Nb, queryParams ); diff --git a/src/Altinn.App.Api/Controllers/TextsController.cs b/src/Altinn.App.Api/Controllers/TextsController.cs index 4ecc0204c..fe87df463 100644 --- a/src/Altinn.App.Api/Controllers/TextsController.cs +++ b/src/Altinn.App.Api/Controllers/TextsController.cs @@ -1,4 +1,5 @@ using Altinn.App.Core.Internal.App; +using Altinn.App.Core.Internal.Language; using Altinn.Platform.Storage.Interface.Models; using Microsoft.AspNetCore.Mvc; @@ -40,9 +41,9 @@ public async Task> Get(string org, string app, [FromR TextResource? textResource = await _appResources.GetTexts(org, app, language); - if (textResource == null && language != "nb") + if (textResource == null && language != LanguageConst.Nb) { - textResource = await _appResources.GetTexts(org, app, "nb"); + textResource = await _appResources.GetTexts(org, app, LanguageConst.Nb); } if (textResource == null) diff --git a/src/Altinn.App.Api/Extensions/HostBuilderExtensions.cs b/src/Altinn.App.Api/Extensions/HostBuilderExtensions.cs index d3a6279a0..9bd00a49f 100644 --- a/src/Altinn.App.Api/Extensions/HostBuilderExtensions.cs +++ b/src/Altinn.App.Api/Extensions/HostBuilderExtensions.cs @@ -1,4 +1,4 @@ -using Altinn.App.Core.Internal.App; +using Altinn.App.Core.Internal.App; using Azure.Identity; namespace Altinn.App.Api.Extensions; diff --git a/src/Altinn.App.Api/Helpers/ValidContributorHelper.cs b/src/Altinn.App.Api/Helpers/ValidContributorHelper.cs index c409cf727..4f8e655d3 100644 --- a/src/Altinn.App.Api/Helpers/ValidContributorHelper.cs +++ b/src/Altinn.App.Api/Helpers/ValidContributorHelper.cs @@ -1,4 +1,4 @@ -using System.Globalization; +using System.Globalization; using Altinn.Platform.Storage.Interface.Models; namespace Altinn.App.Api.Helpers; diff --git a/src/Altinn.App.Core/Features/Payment/Processors/FakePaymentProcessor/FakePaymentProcessor.cs b/src/Altinn.App.Core/Features/Payment/Processors/FakePaymentProcessor/FakePaymentProcessor.cs index 552c02719..1939c7f3c 100644 --- a/src/Altinn.App.Core/Features/Payment/Processors/FakePaymentProcessor/FakePaymentProcessor.cs +++ b/src/Altinn.App.Core/Features/Payment/Processors/FakePaymentProcessor/FakePaymentProcessor.cs @@ -1,4 +1,4 @@ -using Altinn.App.Core.Configuration; +using Altinn.App.Core.Configuration; using Altinn.App.Core.Features.Payment.Models; using Altinn.App.Core.Models; using Altinn.Platform.Storage.Interface.Models; diff --git a/src/Altinn.App.Core/Features/Payment/Processors/Nets/Models/NetsCheckoutConsumerDetails.cs b/src/Altinn.App.Core/Features/Payment/Processors/Nets/Models/NetsCheckoutConsumerDetails.cs index 70ea4dea2..7d765e32c 100644 --- a/src/Altinn.App.Core/Features/Payment/Processors/Nets/Models/NetsCheckoutConsumerDetails.cs +++ b/src/Altinn.App.Core/Features/Payment/Processors/Nets/Models/NetsCheckoutConsumerDetails.cs @@ -1,4 +1,4 @@ -namespace Altinn.App.Core.Features.Payment.Processors.Nets.Models; +namespace Altinn.App.Core.Features.Payment.Processors.Nets.Models; internal class NetsCheckoutConsumerDetails { diff --git a/src/Altinn.App.Core/Internal/Language/LanguageConst.cs b/src/Altinn.App.Core/Internal/Language/LanguageConst.cs new file mode 100644 index 000000000..a94b8dbd5 --- /dev/null +++ b/src/Altinn.App.Core/Internal/Language/LanguageConst.cs @@ -0,0 +1,8 @@ +namespace Altinn.App.Core.Internal.Language; + +internal static class LanguageConst +{ + internal static string Nb => "nb"; + internal static string Nn => "nn"; + internal static string En => "en"; +} diff --git a/src/Altinn.App.Core/Internal/Pdf/PdfService.cs b/src/Altinn.App.Core/Internal/Pdf/PdfService.cs index 600b21db3..e8ac114e2 100644 --- a/src/Altinn.App.Core/Internal/Pdf/PdfService.cs +++ b/src/Altinn.App.Core/Internal/Pdf/PdfService.cs @@ -5,6 +5,7 @@ using Altinn.App.Core.Helpers.Extensions; using Altinn.App.Core.Internal.App; using Altinn.App.Core.Internal.Data; +using Altinn.App.Core.Internal.Language; using Altinn.App.Core.Internal.Profile; using Altinn.App.Core.Models; using Altinn.Platform.Profile.Models; @@ -68,9 +69,12 @@ public PdfService( public async Task GenerateAndStorePdf(Instance instance, string taskId, CancellationToken ct) { using var activity = _telemetry?.StartGenerateAndStorePdfActivity(instance, taskId); - string language = GetOverriddenLanguage(); - // Avoid a costly call if the language is allready overriden by the user - language = string.IsNullOrEmpty(language) ? await GetLanguage() : language; + + HttpContext? httpContext = _httpContextAccessor.HttpContext; + var queries = httpContext?.Request.Query; + var user = httpContext?.User; + + var language = GetOverriddenLanguage(queries) ?? await GetLanguage(user); var pdfContent = await GeneratePdfContent(instance, taskId, language, ct); @@ -85,9 +89,12 @@ public async Task GenerateAndStorePdf(Instance instance, string taskId, Cancella public async Task GeneratePdf(Instance instance, string taskId, CancellationToken ct) { using var activity = _telemetry?.StartGeneratePdfActivity(instance, taskId); - var language = GetOverriddenLanguage(); - // Avoid a costly call if the language is allready overriden by the user - language = string.IsNullOrEmpty(language) ? await GetLanguage() : language; + + HttpContext? httpContext = _httpContextAccessor.HttpContext; + var queries = httpContext?.Request.Query; + var user = httpContext?.User; + + var language = GetOverriddenLanguage(queries) ?? await GetLanguage(user); return await GeneratePdfContent(instance, taskId, language, ct); } @@ -128,14 +135,18 @@ private static Uri BuildUri(string baseUrl, string pagePath, string language) return new Uri(url); } - private async Task GetLanguage() + internal async Task GetLanguage(ClaimsPrincipal? user) { - string language = "nb"; - ClaimsPrincipal? user = _httpContextAccessor.HttpContext?.User; + string language = LanguageConst.Nb; + + if (user is null) + { + return language; + } int? userId = user.GetUserIdAsInt(); - if (userId != null) + if (userId is not null) { UserProfile userProfile = await _profileClient.GetUserProfile((int)userId) @@ -150,33 +161,32 @@ await _profileClient.GetUserProfile((int)userId) return language; } - private string GetOverriddenLanguage() + internal static string? GetOverriddenLanguage(IQueryCollection? queries) { - // If the user has overridden the language from his profile by selecting a - // language directly in the form, then use the selected language. - if (_httpContextAccessor.HttpContext != null) + if (queries is null) { - StringValues queryLanguage; - bool hasQueryLanguage = - _httpContextAccessor.HttpContext.Request.Query.TryGetValue("language", out queryLanguage) - || _httpContextAccessor.HttpContext.Request.Query.TryGetValue("lang", out queryLanguage); - if (hasQueryLanguage) - { - return queryLanguage.ToString(); - } + return null; + } + + if ( + queries.TryGetValue("language", out StringValues queryLanguage) + || queries.TryGetValue("lang", out queryLanguage) + ) + { + return queryLanguage.ToString(); } - return string.Empty; + return null; } private async Task GetTextResource(string app, string org, string language) { TextResource? textResource = await _resourceService.GetTexts(org, app, language); - if (textResource == null && language != "nb") + if (textResource == null && language != LanguageConst.Nb) { // fallback to norwegian if texts does not exist - textResource = await _resourceService.GetTexts(org, app, "nb"); + textResource = await _resourceService.GetTexts(org, app, LanguageConst.Nb); } return textResource; @@ -189,7 +199,7 @@ private static string GetFileName(Instance instance, TextResource? textResource) fileName = $"{app}.pdf"; - if (textResource == null) + if (textResource is null) { return GetValidFileName(fileName); } @@ -202,7 +212,7 @@ private static string GetFileName(Instance instance, TextResource? textResource) textResourceElement.Id.Equals("ServiceName", StringComparison.Ordinal) ); - if (titleText != null && !string.IsNullOrEmpty(titleText.Value)) + if (titleText is not null && !string.IsNullOrEmpty(titleText.Value)) { fileName = titleText.Value + ".pdf"; } diff --git a/test/Altinn.App.Api.Tests/Controllers/DataController_PatchTests.cs b/test/Altinn.App.Api.Tests/Controllers/DataController_PatchTests.cs index b01772c24..32316e7b0 100644 --- a/test/Altinn.App.Api.Tests/Controllers/DataController_PatchTests.cs +++ b/test/Altinn.App.Api.Tests/Controllers/DataController_PatchTests.cs @@ -9,6 +9,7 @@ using Altinn.App.Api.Tests.Data.apps.tdd.contributer_restriction.models; using Altinn.App.Api.Tests.Utils; using Altinn.App.Core.Features; +using Altinn.App.Core.Internal.Language; using Altinn.App.Core.Models.Validation; using Altinn.Platform.Storage.Interface.Models; using FluentAssertions; @@ -38,9 +39,9 @@ public class DataControllerPatchTests : ApiTestBase, IClassFixture _dataProcessorMock = new(MockBehavior.Strict); @@ -56,8 +57,8 @@ public DataControllerPatchTests(WebApplicationFactory factory, ITestOut services.AddSingleton(_dataProcessorMock.Object); services.AddSingleton(_formDataValidatorMock.Object); }; - TestData.DeleteInstanceAndData(Org, App, InstanceOwnerPartyId, InstanceGuid); - TestData.PrepareInstance(Org, App, InstanceOwnerPartyId, InstanceGuid); + TestData.DeleteInstanceAndData(Org, App, InstanceOwnerPartyId, _instanceGuid); + TestData.PrepareInstance(Org, App, InstanceOwnerPartyId, _instanceGuid); } // Helper method to call the API @@ -72,7 +73,7 @@ TResponse parsedResponse string? language = null ) { - var url = $"/{Org}/{App}/instances/{InstanceId}/data/{DataGuid}"; + var url = $"/{Org}/{App}/instances/{_instanceId}/data/{_dataGuid}"; if (language is not null) { url += $"?language={language}"; @@ -136,7 +137,7 @@ public async Task ValidName_ReturnsOk() p => p.ProcessDataWrite( It.IsAny(), - It.Is(dataId => dataId == DataGuid), + It.Is(dataId => dataId == _dataGuid), It.IsAny(), It.IsAny(), null @@ -184,7 +185,7 @@ public async Task NullName_ReturnsOkAndValidationError() p => p.ProcessDataWrite( It.IsAny(), - It.Is(dataId => dataId == DataGuid), + It.Is(dataId => dataId == _dataGuid), It.IsAny(), It.IsAny(), null @@ -295,7 +296,7 @@ public async Task TestEmptyListAndInsertElement_ReturnsNewModel() p => p.ProcessDataWrite( It.IsAny(), - It.Is(dataId => dataId == DataGuid), + It.Is(dataId => dataId == _dataGuid), It.Is(s => s.Melding!.NestedList!.Count == 1), It.Is(s => s!.Melding!.NestedList!.Count == 0), null @@ -669,7 +670,7 @@ public async Task RowId_GetsAddedAutomatically() public async Task DataReadChanges_IsPreservedWhenCallingPatch() { _dataProcessorMock - .Setup(p => p.ProcessDataRead(It.IsAny(), It.IsAny(), It.IsAny(), "nn")) + .Setup(p => p.ProcessDataRead(It.IsAny(), It.IsAny(), It.IsAny(), LanguageConst.Nn)) .Returns( (Instance instance, Guid dataGuid, Skjema skjema, string language) => { @@ -695,7 +696,7 @@ public async Task DataReadChanges_IsPreservedWhenCallingPatch() .Verifiable(Times.Exactly(1)); // call Read to get the data with changes to Melding.Random from ProcessDataRead - var url = $"/{Org}/{App}/instances/{InstanceId}/data/{DataGuid}?language=nn"; + var url = $"/{Org}/{App}/instances/{_instanceId}/data/{_dataGuid}?language=nn"; _outputHelper.WriteLine($"Calling GET {url}"); using var httpClient = GetRootedClient(Org, App); string token = PrincipalUtil.GetToken(1337, null); @@ -754,7 +755,7 @@ public async Task VerifyLanguageIsPassedToDataProcessor() p => p.ProcessDataWrite( It.IsAny(), - It.Is(dataId => dataId == DataGuid), + It.Is(dataId => dataId == _dataGuid), It.IsAny(), It.IsAny(), "es" diff --git a/test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs b/test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs index 7c8d3b3a1..44a2afc5d 100644 --- a/test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs +++ b/test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs @@ -1,5 +1,6 @@ using System.Net; using Altinn.App.Core.Features; +using Altinn.App.Core.Internal.Language; using Altinn.App.Core.Models; using FluentAssertions; using Microsoft.AspNetCore.Mvc.Testing; @@ -118,7 +119,7 @@ public async Task Get_ShouldNotDefaultToNbLanguage() var headerValue = response.Headers.GetValues("Altinn-DownstreamParameters"); response.StatusCode.Should().Be(HttpStatusCode.OK); - headerValue.Should().NotContain("nb"); + headerValue.Should().NotContain(LanguageConst.Nb); } [Fact] diff --git a/test/Altinn.App.Api.Tests/Controllers/PdfControllerTests.cs b/test/Altinn.App.Api.Tests/Controllers/PdfControllerTests.cs index ec94bdc59..6755f9302 100644 --- a/test/Altinn.App.Api.Tests/Controllers/PdfControllerTests.cs +++ b/test/Altinn.App.Api.Tests/Controllers/PdfControllerTests.cs @@ -6,6 +6,7 @@ using Altinn.App.Core.Internal.Auth; using Altinn.App.Core.Internal.Data; using Altinn.App.Core.Internal.Instances; +using Altinn.App.Core.Internal.Language; using Altinn.App.Core.Internal.Pdf; using Altinn.App.Core.Internal.Profile; using Altinn.Platform.Storage.Interface.Models; @@ -22,24 +23,24 @@ namespace Altinn.App.Api.Tests.Controllers; public class PdfControllerTests { - private readonly string org = "org"; - private readonly string app = "app"; - private readonly Guid instanceId = new Guid("e11e3e0b-a45c-48fb-a968-8d4ddf868c80"); - private readonly int partyId = 12345; - private readonly string taskId = "Task_1"; + private readonly string _org = "org"; + private readonly string _app = "app"; + private readonly Guid _instanceId = new("e11e3e0b-a45c-48fb-a968-8d4ddf868c80"); + private readonly int _partyId = 12345; + private readonly string _taskId = "Task_1"; private readonly Mock _appResources = new(); private readonly Mock _dataClient = new(); private readonly Mock _profile = new(); - private readonly IOptions _platformSettingsOptions = - Microsoft.Extensions.Options.Options.Create(new() { }); + private readonly IOptions _platformSettingsOptions = Options.Create(new() { }); private readonly Mock _instanceClient = new(); private readonly Mock _pdfFormatter = new(); private readonly Mock _appModel = new(); private readonly Mock _userTokenProvider = new(); - private readonly IOptions _pdfGeneratorSettingsOptions = - Microsoft.Extensions.Options.Options.Create(new() { }); + private readonly IOptions _pdfGeneratorSettingsOptions = Options.Create( + new() { } + ); public PdfControllerTests() { @@ -49,10 +50,13 @@ public PdfControllerTests() Task.FromResult( new Instance() { - Org = org, - AppId = $"{org}/{app}", - Id = $"{partyId}/{instanceId}", - Process = new ProcessState() { CurrentTask = new ProcessElementInfo() { ElementId = taskId, }, } + Org = _org, + AppId = $"{_org}/{_app}", + Id = $"{_partyId}/{_instanceId}", + Process = new ProcessState() + { + CurrentTask = new ProcessElementInfo() { ElementId = _taskId, }, + } } ) ); @@ -64,12 +68,12 @@ public async Task Request_In_Prod_Should_Be_Blocked() var env = new Mock(); env.Setup(a => a.EnvironmentName).Returns("Production"); - IOptions generalSettingsOptions = Microsoft.Extensions.Options.Options.Create( + IOptions generalSettingsOptions = Options.Create( new() { HostName = "org.apps.altinn.no" } ); var httpContextAccessor = new Mock(); - httpContextAccessor.Setup(x => x.HttpContext!.Request!.Query["lang"]).Returns("nb"); + httpContextAccessor.Setup(x => x.HttpContext!.Request!.Query["lang"]).Returns(LanguageConst.Nb); var handler = new Mock(); var httpClient = new HttpClient(handler.Object); @@ -100,7 +104,7 @@ public async Task Request_In_Prod_Should_Be_Blocked() pdfService ); - var result = await pdfController.GetPdfPreview(org, app, partyId, instanceId); + var result = await pdfController.GetPdfPreview(_org, _app, _partyId, _instanceId); result.Should().BeOfType(typeof(NotFoundResult)); handler @@ -114,12 +118,12 @@ public async Task Request_In_Dev_Should_Generate() var env = new Mock(); env.Setup(a => a.EnvironmentName).Returns("Development"); - IOptions generalSettingsOptions = Microsoft.Extensions.Options.Options.Create( + IOptions generalSettingsOptions = Options.Create( new() { HostName = "local.altinn.cloud" } ); var httpContextAccessor = new Mock(); - httpContextAccessor.Setup(x => x.HttpContext!.Request!.Query["lang"]).Returns("nb"); + httpContextAccessor.Setup(x => x.HttpContext!.Request!.Query["lang"]).Returns(LanguageConst.Nb); string? frontendVersion = null; httpContextAccessor .Setup(x => x.HttpContext!.Request!.Cookies.TryGetValue("frontendVersion", out frontendVersion)) @@ -175,7 +179,7 @@ public async Task Request_In_Dev_Should_Generate() ) .ReturnsAsync(mockResponse); - var result = await pdfController.GetPdfPreview(org, app, partyId, instanceId); + var result = await pdfController.GetPdfPreview(_org, _app, _partyId, _instanceId); result.Should().BeOfType(typeof(FileStreamResult)); } @@ -193,12 +197,12 @@ public async Task Request_In_Dev_Should_Include_Frontend_Version() var env = new Mock(); env.Setup(a => a.EnvironmentName).Returns("Development"); - IOptions generalSettingsOptions = Microsoft.Extensions.Options.Options.Create( + IOptions generalSettingsOptions = Options.Create( new() { HostName = "local.altinn.cloud" } ); var httpContextAccessor = new Mock(); - httpContextAccessor.Setup(x => x.HttpContext!.Request!.Query["lang"]).Returns("nb"); + httpContextAccessor.Setup(x => x.HttpContext!.Request!.Query["lang"]).Returns(LanguageConst.Nb); string? frontendVersion = "https://altinncdn.no/toolkits/altinn-app-frontend/3/"; httpContextAccessor .Setup(x => x.HttpContext!.Request!.Cookies.TryGetValue("frontendVersion", out frontendVersion)) @@ -254,7 +258,7 @@ public async Task Request_In_Dev_Should_Include_Frontend_Version() ) .ReturnsAsync(mockResponse); - var result = await pdfController.GetPdfPreview(org, app, partyId, instanceId); + var result = await pdfController.GetPdfPreview(_org, _app, _partyId, _instanceId); result.Should().BeOfType(typeof(FileStreamResult)); } @@ -274,12 +278,12 @@ public async Task Request_In_TT02_Should_Ignore_Frontend_Version() var env = new Mock(); env.Setup(a => a.EnvironmentName).Returns("Staging"); - IOptions generalSettingsOptions = Microsoft.Extensions.Options.Options.Create( + IOptions generalSettingsOptions = Options.Create( new() { HostName = "org.apps.tt02.altinn.no" } ); var httpContextAccessor = new Mock(); - httpContextAccessor.Setup(x => x.HttpContext!.Request!.Query["lang"]).Returns("nb"); + httpContextAccessor.Setup(x => x.HttpContext!.Request!.Query["lang"]).Returns(LanguageConst.Nb); string? frontendVersion = "https://altinncdn.no/toolkits/altinn-app-frontend/3/"; httpContextAccessor .Setup(x => x.HttpContext!.Request!.Cookies.TryGetValue("frontendVersion", out frontendVersion)) @@ -335,7 +339,7 @@ public async Task Request_In_TT02_Should_Ignore_Frontend_Version() ) .ReturnsAsync(mockResponse); - var result = await pdfController.GetPdfPreview(org, app, partyId, instanceId); + var result = await pdfController.GetPdfPreview(_org, _app, _partyId, _instanceId); result.Should().BeOfType(typeof(FileStreamResult)); } diff --git a/test/Altinn.App.Api.Tests/Controllers/TextsControllerTests.cs b/test/Altinn.App.Api.Tests/Controllers/TextsControllerTests.cs index e614ae0e4..c5f05387b 100644 --- a/test/Altinn.App.Api.Tests/Controllers/TextsControllerTests.cs +++ b/test/Altinn.App.Api.Tests/Controllers/TextsControllerTests.cs @@ -1,5 +1,6 @@ using Altinn.App.Api.Controllers; using Altinn.App.Core.Internal.App; +using Altinn.App.Core.Internal.Language; using Altinn.Platform.Storage.Interface.Models; using FluentAssertions; using Microsoft.AspNetCore.Mvc; @@ -15,7 +16,7 @@ public async Task Get_RetrunsTexts_when_found() // Arrange const string org = "ttd"; const string app = "unit-app"; - const string language = "nb"; + string language = LanguageConst.Nb; TextResource expected = new TextResource { @@ -49,12 +50,12 @@ public async Task Get_checks_for_nb_text_if_language_specific_not_found_and_retu // Arrange const string org = "ttd"; const string app = "unit-app"; - const string language = "en"; + string language = LanguageConst.En; TextResource expected = new TextResource { Id = "test", - Language = "nb", + Language = LanguageConst.Nb, Org = org, Resources = new List { @@ -64,7 +65,9 @@ public async Task Get_checks_for_nb_text_if_language_specific_not_found_and_retu var appResourceMock = new Mock(); appResourceMock.Setup(a => a.GetTexts(org, app, language)).Returns(Task.FromResult(null)); - appResourceMock.Setup(a => a.GetTexts(org, app, "nb")).Returns(Task.FromResult(null)); + appResourceMock + .Setup(a => a.GetTexts(org, app, LanguageConst.Nb)) + .Returns(Task.FromResult(null)); // Act var controller = new TextsController(appResourceMock.Object); var result = await controller.Get(org, app, language); @@ -74,7 +77,7 @@ public async Task Get_checks_for_nb_text_if_language_specific_not_found_and_retu result.Result.Should().BeOfType(); resultValue.Should().BeNull(); appResourceMock.Verify(a => a.GetTexts(org, app, language), Times.Once); - appResourceMock.Verify(a => a.GetTexts(org, app, "nb"), Times.Once); + appResourceMock.Verify(a => a.GetTexts(org, app, LanguageConst.Nb), Times.Once); appResourceMock.VerifyNoOtherCalls(); } diff --git a/test/Altinn.App.Api.Tests/Controllers/ValidateControllerValidateDataTests.cs b/test/Altinn.App.Api.Tests/Controllers/ValidateControllerValidateDataTests.cs index 688e1f35e..6f7b679ba 100644 --- a/test/Altinn.App.Api.Tests/Controllers/ValidateControllerValidateDataTests.cs +++ b/test/Altinn.App.Api.Tests/Controllers/ValidateControllerValidateDataTests.cs @@ -3,6 +3,7 @@ using Altinn.App.Core.Helpers; using Altinn.App.Core.Internal.App; using Altinn.App.Core.Internal.Instances; +using Altinn.App.Core.Internal.Language; using Altinn.App.Core.Internal.Validation; using Altinn.App.Core.Models; using Altinn.App.Core.Models.Validation; @@ -88,7 +89,7 @@ public class TestScenariosData : IEnumerable ValidationIssueCodes.DataElementCodes.DataElementValidatedAtWrongTask, new Dictionary>(), null, - "nb" + LanguageConst.Nb ) } }, diff --git a/test/Altinn.App.Api.Tests/Helpers/ValidContributorHelperTests.cs b/test/Altinn.App.Api.Tests/Helpers/ValidContributorHelperTests.cs index c7b37a4e8..807cf00d7 100644 --- a/test/Altinn.App.Api.Tests/Helpers/ValidContributorHelperTests.cs +++ b/test/Altinn.App.Api.Tests/Helpers/ValidContributorHelperTests.cs @@ -1,4 +1,4 @@ -using Altinn.App.Api.Helpers; +using Altinn.App.Api.Helpers; using Altinn.Platform.Storage.Interface.Models; using FluentAssertions; diff --git a/test/Altinn.App.Core.Tests/DataLists/NullDataListProviderTest.cs b/test/Altinn.App.Core.Tests/DataLists/NullDataListProviderTest.cs index 4ef472934..9ff6ce780 100644 --- a/test/Altinn.App.Core.Tests/DataLists/NullDataListProviderTest.cs +++ b/test/Altinn.App.Core.Tests/DataLists/NullDataListProviderTest.cs @@ -1,5 +1,6 @@ #nullable disable using Altinn.App.Core.Features.DataLists; +using Altinn.App.Core.Internal.Language; using FluentAssertions; namespace Altinn.App.PlatformServices.Tests.DataLists; @@ -12,7 +13,7 @@ public async Task Constructor_InitializedWithEmptyValues() var provider = new NullDataListProvider(); provider.Id.Should().Be(string.Empty); - var list = await provider.GetDataListAsync("nb", new Dictionary()); + var list = await provider.GetDataListAsync(LanguageConst.Nb, new Dictionary()); list.ListItems.Should().BeNull(); } } diff --git a/test/Altinn.App.Core.Tests/DataLists/NullInstanceDataListProviderTest.cs b/test/Altinn.App.Core.Tests/DataLists/NullInstanceDataListProviderTest.cs index 2327c6f62..0b326bdd1 100644 --- a/test/Altinn.App.Core.Tests/DataLists/NullInstanceDataListProviderTest.cs +++ b/test/Altinn.App.Core.Tests/DataLists/NullInstanceDataListProviderTest.cs @@ -1,5 +1,6 @@ #nullable disable using Altinn.App.Core.Features.DataLists; +using Altinn.App.Core.Internal.Language; using Altinn.App.Core.Models; using FluentAssertions; @@ -15,7 +16,7 @@ public async Task Constructor_InitializedWithEmptyValues() provider.Id.Should().Be(string.Empty); var options = await provider.GetInstanceDataListAsync( new InstanceIdentifier(12345, Guid.NewGuid()), - "nb", + LanguageConst.Nb, new Dictionary() ); options.ListItems.Should().BeNull(); diff --git a/test/Altinn.App.Core.Tests/Features/Options/Altinn2Provider/Altinn2OptionsCacheTests.cs b/test/Altinn.App.Core.Tests/Features/Options/Altinn2Provider/Altinn2OptionsCacheTests.cs index c11953937..dfb9d74e5 100644 --- a/test/Altinn.App.Core.Tests/Features/Options/Altinn2Provider/Altinn2OptionsCacheTests.cs +++ b/test/Altinn.App.Core.Tests/Features/Options/Altinn2Provider/Altinn2OptionsCacheTests.cs @@ -1,6 +1,7 @@ using Altinn.App.Core.Features; using Altinn.App.Core.Features.Options; using Altinn.App.Core.Features.Options.Altinn2Provider; +using Altinn.App.Core.Internal.Language; using FluentAssertions; using Microsoft.Extensions.DependencyInjection; @@ -58,11 +59,11 @@ public async Task Altinn2OptionsTests_TestCache() messageHandler.CallCounter.Should().Be(0); providers.Count().Should().Be(3); var optionsProvider = providers.Single(p => p.Id == "ASF_Land3"); - await optionsProvider.GetAppOptionsAsync("nb", new Dictionary()); + await optionsProvider.GetAppOptionsAsync(LanguageConst.Nb, new Dictionary()); await Task.Delay(5); messageHandler.CallCounter.Should().Be(1); - await optionsProvider.GetAppOptionsAsync("nb", new Dictionary()); + await optionsProvider.GetAppOptionsAsync(LanguageConst.Nb, new Dictionary()); await Task.Delay(5); messageHandler.CallCounter.Should().Be(1); } @@ -74,11 +75,11 @@ public async Task Altinn2OptionsTests_TestCache() var messageHandler = scope.ServiceProvider.GetRequiredService(); var optionsProvider = providers.Single(p => p.Id == "ASF_Land3"); - await optionsProvider.GetAppOptionsAsync("nb", new Dictionary()); + await optionsProvider.GetAppOptionsAsync(LanguageConst.Nb, new Dictionary()); await Task.Delay(5); messageHandler.CallCounter.Should().Be(1); - await optionsProvider.GetAppOptionsAsync("nb", new Dictionary()); + await optionsProvider.GetAppOptionsAsync(LanguageConst.Nb, new Dictionary()); await Task.Delay(5); messageHandler.CallCounter.Should().Be(1); } @@ -90,12 +91,12 @@ public async Task Altinn2OptionsTests_TestCache() var messageHandler = scope.ServiceProvider.GetRequiredService(); var optionsProvider = providers.Single(p => p.Id == "ASF_Fylker"); - await optionsProvider.GetAppOptionsAsync("nb", new Dictionary()); + await optionsProvider.GetAppOptionsAsync(LanguageConst.Nb, new Dictionary()); await Task.Delay(5); messageHandler.CallCounter.Should().Be(2); // Fetch the list in nynorsk and see that yeat another call is made - await optionsProvider.GetAppOptionsAsync("nn", new Dictionary()); + await optionsProvider.GetAppOptionsAsync(LanguageConst.Nn, new Dictionary()); await Task.Delay(5); messageHandler.CallCounter.Should().Be(3); } diff --git a/test/Altinn.App.Core.Tests/Features/Options/Altinn2Provider/Altinn2OptionsTests.cs b/test/Altinn.App.Core.Tests/Features/Options/Altinn2Provider/Altinn2OptionsTests.cs index 66c175cd2..525b1afb5 100644 --- a/test/Altinn.App.Core.Tests/Features/Options/Altinn2Provider/Altinn2OptionsTests.cs +++ b/test/Altinn.App.Core.Tests/Features/Options/Altinn2Provider/Altinn2OptionsTests.cs @@ -1,6 +1,7 @@ using Altinn.App.Core.Features; using Altinn.App.Core.Features.Options; using Altinn.App.Core.Features.Options.Altinn2Provider; +using Altinn.App.Core.Internal.Language; using FluentAssertions; using Microsoft.Extensions.DependencyInjection; @@ -62,7 +63,10 @@ public async Task Altinn2OptionsTests_MoreThan4AndNorwayIncluded() var providers = scope.ServiceProvider.GetRequiredService>(); providers.Count().Should().Be(1); var optionsProvider = providers.Single(p => p.Id == "ASF_Land1"); - var landOptions = await optionsProvider.GetAppOptionsAsync("nb", new Dictionary()); + var landOptions = await optionsProvider.GetAppOptionsAsync( + LanguageConst.Nb, + new Dictionary() + ); landOptions.Options.Should().HaveCountGreaterThan(4, "ASF_Land needs to have more than 4 countries"); landOptions.Options.Should().Match(options => options.Any(o => o.Value == "NORGE")); } @@ -85,7 +89,10 @@ public async Task Altinn2OptionsTests_EnglishLanguage() var providers = scope.ServiceProvider.GetRequiredService>(); providers.Count().Should().Be(1); var optionsProvider = providers.Single(p => p.Id == "ASF_Land1"); - var landOptions = await optionsProvider.GetAppOptionsAsync("en", new Dictionary()); + var landOptions = await optionsProvider.GetAppOptionsAsync( + LanguageConst.En, + new Dictionary() + ); landOptions.Options.Should().HaveCountGreaterThan(4, "ASF_Land needs to have more than 4 countries"); landOptions.Options.Should().Match(options => options.Any(o => o.Label == "NORWAY")); } @@ -109,7 +116,10 @@ public async Task Altinn2OptionsTests_FilterOnlyNorway() var providers = scope.ServiceProvider.GetRequiredService>(); providers.Count().Should().Be(1); var optionsProvider = providers.Single(p => p.Id == "OnlyNorway"); - var landOptions = await optionsProvider.GetAppOptionsAsync("nb", new Dictionary()); + var landOptions = await optionsProvider.GetAppOptionsAsync( + LanguageConst.Nb, + new Dictionary() + ); landOptions.Options.Should().HaveCount(1, "We filter out only norway"); landOptions.Options.Should().Match(options => options.Any(o => o.Value == "NORGE")); } @@ -133,7 +143,10 @@ public async Task Altinn2OptionsTests_NoCodeListVersionProvided() var providers = scope.ServiceProvider.GetRequiredService>(); providers.Count().Should().Be(1); var optionsProvider = providers.Single(p => p.Id == "OnlyNorway"); - var landOptions = await optionsProvider.GetAppOptionsAsync("nb", new Dictionary()); + var landOptions = await optionsProvider.GetAppOptionsAsync( + LanguageConst.Nb, + new Dictionary() + ); landOptions.Options.Should().HaveCount(1, "We filter out only norway"); landOptions.Options.Should().Match(options => options.Any(o => o.Value == "NORGE")); } diff --git a/test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs b/test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs index 6a8512ed2..6c988d8d3 100644 --- a/test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs +++ b/test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs @@ -1,5 +1,6 @@ using Altinn.App.Core.Features; using Altinn.App.Core.Features.Options; +using Altinn.App.Core.Internal.Language; using Altinn.App.Core.Models; using FluentAssertions; using Moq; @@ -98,7 +99,7 @@ public async Task GetParameters_CustomOptionsProviderWithUpperCase_ShouldReturnC IAppOptionsProvider optionsProvider = factory.GetOptionsProvider("Country"); AppOptions options = await optionsProvider.GetAppOptionsAsync( - "nb", + LanguageConst.Nb, new Dictionary() { { "key", "value" } } ); options.Parameters.First(x => x.Key == "key").Value.Should().Be("value"); diff --git a/test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cs b/test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cs index a082bd9c1..ffa162a23 100644 --- a/test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cs +++ b/test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cs @@ -1,5 +1,6 @@ using Altinn.App.Core.Features; using Altinn.App.Core.Features.Options; +using Altinn.App.Core.Internal.Language; using Altinn.App.Core.Models; using FluentAssertions; using Microsoft.Extensions.DependencyInjection; @@ -15,37 +16,32 @@ public class JoinedAppOptionsTests private readonly Mock _fileHandlerMock = new(MockBehavior.Strict); private readonly ServiceCollection _serviceCollection = new(); - private const string Language = "nb"; - private static readonly List AppOptionsCountries = - new() - { - new AppOption { Value = "no", Label = "Norway" }, - new AppOption { Value = "se", Label = "Sweden" } - }; + private readonly string _language = LanguageConst.Nb; + private static readonly List _appOptionsCountries = + [ + new AppOption { Value = "no", Label = "Norway" }, + new AppOption { Value = "se", Label = "Sweden" } + ]; - private static readonly List AppOptionsSentinel = - new() - { - new AppOption { Value = null, Label = "Sentinel" } - }; + private static readonly List _appOptionsSentinel = [new AppOption { Value = null, Label = "Sentinel" }]; public JoinedAppOptionsTests() { _countryAppOptionsMock.Setup(p => p.Id).Returns("country-no-sentinel"); _countryAppOptionsMock - .Setup(p => p.GetAppOptionsAsync(Language, It.IsAny>())) + .Setup(p => p.GetAppOptionsAsync(_language, It.IsAny>())) .ReturnsAsync( (string language, Dictionary keyValuePairs) => - new AppOptions() { Options = AppOptionsCountries, Parameters = keyValuePairs.ToDictionary()!, } + new AppOptions() { Options = _appOptionsCountries, Parameters = keyValuePairs.ToDictionary()!, } ); _serviceCollection.AddSingleton(_countryAppOptionsMock.Object); _sentinelOptionsProviderMock.Setup(p => p.Id).Returns("sentinel"); _sentinelOptionsProviderMock - .Setup(p => p.GetAppOptionsAsync(Language, It.IsAny>())) + .Setup(p => p.GetAppOptionsAsync(_language, It.IsAny>())) .ReturnsAsync( (string language, Dictionary keyValuePairs) => - new AppOptions() { Options = AppOptionsSentinel, Parameters = keyValuePairs.ToDictionary()!, } + new AppOptions() { Options = _appOptionsSentinel, Parameters = keyValuePairs.ToDictionary()!, } ); _serviceCollection.AddSingleton(_sentinelOptionsProviderMock.Object); @@ -73,9 +69,9 @@ public async Task JoinedOptionsProvider_ReturnsOptionsFromBothProviders() optionsProvider.Should().BeOfType(); optionsProvider.Id.Should().Be("country"); - var appOptions = await optionsProvider.GetAppOptionsAsync(Language, new Dictionary()); + var appOptions = await optionsProvider.GetAppOptionsAsync(_language, new Dictionary()); appOptions.Options.Should().HaveCount(3); - appOptions.Options.Should().BeEquivalentTo(AppOptionsCountries.Concat(AppOptionsSentinel)); + appOptions.Options.Should().BeEquivalentTo(_appOptionsCountries.Concat(_appOptionsSentinel)); _neverUsedOptionsProviderMock.VerifyAll(); _countryAppOptionsMock.VerifyAll(); @@ -90,9 +86,9 @@ public async Task JoinedOptionPovider_UseAppOptionsServiceWithBothProviders() using var sp = _serviceCollection.BuildServiceProvider(); var appOptionsService = sp.GetRequiredService(); - var options = await appOptionsService.GetOptionsAsync("country", Language, new()); + var options = await appOptionsService.GetOptionsAsync("country", _language, new()); - options.Options.Should().BeEquivalentTo(AppOptionsCountries.Concat(AppOptionsSentinel)); + options.Options.Should().BeEquivalentTo(_appOptionsCountries.Concat(_appOptionsSentinel)); _neverUsedOptionsProviderMock.VerifyAll(); _countryAppOptionsMock.VerifyAll(); @@ -109,12 +105,12 @@ public async Task JoinSingleList() var appOptionsService = sp.GetRequiredService(); // Fetch the country options (now without sentinel) - var options = await appOptionsService.GetOptionsAsync("country", Language, new()); - options.Options.Should().BeEquivalentTo(AppOptionsCountries); + var options = await appOptionsService.GetOptionsAsync("country", _language, new()); + options.Options.Should().BeEquivalentTo(_appOptionsCountries); // Fetch sentinel options to make verifications work - var sentinelOptions = await appOptionsService.GetOptionsAsync("sentinel", Language, new()); - sentinelOptions.Options.Should().BeEquivalentTo(AppOptionsSentinel); + var sentinelOptions = await appOptionsService.GetOptionsAsync("sentinel", _language, new()); + sentinelOptions.Options.Should().BeEquivalentTo(_appOptionsSentinel); _neverUsedOptionsProviderMock.VerifyAll(); _countryAppOptionsMock.VerifyAll(); @@ -132,7 +128,7 @@ public async Task JoinLists_VerifyParameters() var parameters = new Dictionary { { "key", "value" } }; - var options = await appOptionsService.GetOptionsAsync("country", Language, parameters); + var options = await appOptionsService.GetOptionsAsync("country", _language, parameters); options .Parameters.Should() @@ -154,7 +150,7 @@ public async Task JoinWithMissingProvider_ThrowsExceptionToWarnAboutMissconfigur using var sp = _serviceCollection.BuildServiceProvider(); var appOptionsService = sp.GetRequiredService(); - var action = new Func(async () => await appOptionsService.GetOptionsAsync("country", Language, new())); + var action = new Func(async () => await appOptionsService.GetOptionsAsync("country", _language, new())); var exception = await action.Should().ThrowAsync(); exception.WithMessage("missing is not registrered as an app option"); diff --git a/test/Altinn.App.Core.Tests/Features/Options/NullInstanceAppOptionsProviderTests.cs b/test/Altinn.App.Core.Tests/Features/Options/NullInstanceAppOptionsProviderTests.cs index 270788bd9..05cdf714d 100644 --- a/test/Altinn.App.Core.Tests/Features/Options/NullInstanceAppOptionsProviderTests.cs +++ b/test/Altinn.App.Core.Tests/Features/Options/NullInstanceAppOptionsProviderTests.cs @@ -1,4 +1,5 @@ using Altinn.App.Core.Features.Options; +using Altinn.App.Core.Internal.Language; using Altinn.App.Core.Models; using FluentAssertions; @@ -14,7 +15,7 @@ public async Task Constructor_InitializedWithEmptyValues() provider.Id.Should().Be(string.Empty); var options = await provider.GetInstanceAppOptionsAsync( new InstanceIdentifier(12345, Guid.NewGuid()), - "nb", + LanguageConst.Nb, new Dictionary() ); options.Options.Should().BeNull(); diff --git a/test/Altinn.App.Core.Tests/Features/Payment/PaymentServiceTests.cs b/test/Altinn.App.Core.Tests/Features/Payment/PaymentServiceTests.cs index 55221087b..a2ff1d6ff 100644 --- a/test/Altinn.App.Core.Tests/Features/Payment/PaymentServiceTests.cs +++ b/test/Altinn.App.Core.Tests/Features/Payment/PaymentServiceTests.cs @@ -4,6 +4,7 @@ using Altinn.App.Core.Features.Payment.Processors; using Altinn.App.Core.Features.Payment.Services; using Altinn.App.Core.Internal.Data; +using Altinn.App.Core.Internal.Language; using Altinn.App.Core.Internal.Process.Elements.AltinnExtensionProperties; using Altinn.App.Core.Models; using Altinn.Platform.Storage.Interface.Models; @@ -40,7 +41,7 @@ public async Task StartPayment_ReturnsRedirectUrl_WhenPaymentStartedSuccessfully PaymentInformation paymentInformation = CreatePaymentInformation(); PaymentDetails paymentDetails = paymentInformation.PaymentDetails ?? throw new NullReferenceException("PaymentDetails should not be null"); - const string language = "nb"; + string language = LanguageConst.Nb; _orderDetailsCalculator.Setup(p => p.CalculateOrderDetails(instance, language)).ReturnsAsync(orderDetails); _dataService @@ -88,7 +89,7 @@ public async Task StartPayment_ReturnsAlreadyPaidTrue_WhenPaymentIsAlreadyPaid() Instance instance = CreateInstance(); OrderDetails orderDetails = CreateOrderDetails(); ValidAltinnPaymentConfiguration paymentConfiguration = CreatePaymentConfiguration(); - const string language = "nb"; + string language = LanguageConst.Nb; _paymentProcessor.Setup(pp => pp.PaymentProcessorId).Returns(orderDetails.PaymentProcessorId); @@ -124,7 +125,7 @@ public async Task StartPayment_ThrowsException_WhenOrderDetailsCannotBeRetrieved { Instance instance = CreateInstance(); ValidAltinnPaymentConfiguration paymentConfiguration = CreatePaymentConfiguration(); - const string language = "nb"; + string language = LanguageConst.Nb; _dataService .Setup(ds => ds.GetByType(It.IsAny(), It.IsAny())) @@ -148,7 +149,7 @@ public async Task StartPayment_ThrowsException_WhenPaymentCannotBeStarted() Instance instance = CreateInstance(); OrderDetails orderDetails = CreateOrderDetails(); ValidAltinnPaymentConfiguration paymentConfiguration = CreatePaymentConfiguration(); - const string language = "nb"; + string language = LanguageConst.Nb; _dataService .Setup(ds => ds.GetByType(It.IsAny(), It.IsAny())) @@ -173,7 +174,7 @@ public async Task StartPayment_ThrowsException_WhenPaymentInformationCannotBeSto PaymentInformation paymentInformation = CreatePaymentInformation(); PaymentDetails paymentDetails = paymentInformation.PaymentDetails ?? throw new NullReferenceException("PaymentDetails should not be null"); - const string language = "nb"; + string language = LanguageConst.Nb; _orderDetailsCalculator.Setup(p => p.CalculateOrderDetails(instance, language)).ReturnsAsync(orderDetails); _dataService @@ -197,7 +198,7 @@ public async Task CheckAndStorePaymentInformation_ReturnsNull_WhenNoPaymentInfor Instance instance = CreateInstance(); OrderDetails orderDetails = CreateOrderDetails(); ValidAltinnPaymentConfiguration paymentConfiguration = CreatePaymentConfiguration(); - const string language = "nb"; + string language = LanguageConst.Nb; _orderDetailsCalculator.Setup(p => p.CalculateOrderDetails(instance, language)).ReturnsAsync(orderDetails); @@ -226,7 +227,7 @@ public async Task CheckAndStorePaymentInformation_ThrowsException_WhenUnableToCh OrderDetails orderDetails = CreateOrderDetails(); ValidAltinnPaymentConfiguration paymentConfiguration = CreatePaymentConfiguration(); PaymentInformation paymentInformation = CreatePaymentInformation(); - const string language = "nb"; + string language = LanguageConst.Nb; _orderDetailsCalculator.Setup(odc => odc.CalculateOrderDetails(instance, language)).ReturnsAsync(orderDetails); @@ -260,7 +261,7 @@ public async Task CheckAndStorePaymentInformation_ReturnsPaymentInformation_When OrderDetails orderDetails = CreateOrderDetails(); ValidAltinnPaymentConfiguration paymentConfiguration = CreatePaymentConfiguration(); PaymentInformation paymentInformation = CreatePaymentInformation(); - const string language = "nb"; + string language = LanguageConst.Nb; _orderDetailsCalculator.Setup(p => p.CalculateOrderDetails(instance, language)).ReturnsAsync(orderDetails); @@ -317,7 +318,7 @@ public async Task CancelPayment_ShouldCallCancelAndDelete_WhenPaymentIsNotPaid() PaymentInformation paymentInformation = CreatePaymentInformation(); PaymentDetails paymentDetails = paymentInformation.PaymentDetails ?? throw new NullReferenceException("PaymentDetails should not be null"); - const string language = "nb"; + string language = LanguageConst.Nb; paymentInformation.Status = PaymentStatus.Cancelled; @@ -368,7 +369,7 @@ public async Task CancelPayment_ShouldNotDelete_WhenPaymentCancellationFails() PaymentInformation paymentInformation = CreatePaymentInformation(); PaymentDetails paymentDetails = paymentInformation.PaymentDetails ?? throw new NullReferenceException("PaymentDetails should not be null"); - const string language = "nb"; + string language = LanguageConst.Nb; _orderDetailsCalculator.Setup(p => p.CalculateOrderDetails(instance, language)).ReturnsAsync(orderDetails); _dataService @@ -408,7 +409,8 @@ public async Task StartPayment_ShouldThrowPaymentException_WhenOrderDetailsCalcu var paymentService = new PaymentService(paymentProcessors, _dataService.Object, _logger.Object); // Act - Func act = async () => await paymentService.StartPayment(instance, paymentConfiguration, "en"); + Func act = async () => + await paymentService.StartPayment(instance, paymentConfiguration, LanguageConst.En); // Assert await act.Should() @@ -433,7 +435,11 @@ public async Task CheckAndStorePaymentStatus_ShouldThrowPaymentException_WhenOrd // Act Func act = async () => - await paymentService.CheckAndStorePaymentStatus(instance, paymentConfiguration.Validate(), "en"); + await paymentService.CheckAndStorePaymentStatus( + instance, + paymentConfiguration.Validate(), + LanguageConst.En + ); // Assert await act.Should() diff --git a/test/Altinn.App.Core.Tests/Features/Payment/Providers/Nets/NetsMapperTests.cs b/test/Altinn.App.Core.Tests/Features/Payment/Providers/Nets/NetsMapperTests.cs index 2a63629c8..ccc448b83 100644 --- a/test/Altinn.App.Core.Tests/Features/Payment/Providers/Nets/NetsMapperTests.cs +++ b/test/Altinn.App.Core.Tests/Features/Payment/Providers/Nets/NetsMapperTests.cs @@ -1,4 +1,4 @@ -using Altinn.App.Core.Features.Payment.Models; +using Altinn.App.Core.Features.Payment.Models; using Altinn.App.Core.Features.Payment.Processors.Nets; using Altinn.App.Core.Features.Payment.Processors.Nets.Models; using FluentAssertions; diff --git a/test/Altinn.App.Core.Tests/Features/Payment/Providers/Nets/NetsPaymentProcessorTests.cs b/test/Altinn.App.Core.Tests/Features/Payment/Providers/Nets/NetsPaymentProcessorTests.cs index 2756f1406..8a08aa3ff 100644 --- a/test/Altinn.App.Core.Tests/Features/Payment/Providers/Nets/NetsPaymentProcessorTests.cs +++ b/test/Altinn.App.Core.Tests/Features/Payment/Providers/Nets/NetsPaymentProcessorTests.cs @@ -3,6 +3,7 @@ using Altinn.App.Core.Features.Payment.Models; using Altinn.App.Core.Features.Payment.Processors.Nets; using Altinn.App.Core.Features.Payment.Processors.Nets.Models; +using Altinn.App.Core.Internal.Language; using Altinn.Platform.Storage.Interface.Models; using FluentAssertions; using Microsoft.Extensions.Options; @@ -59,7 +60,7 @@ public async Task StartPayment_WithValidOrderDetails_ReturnsPaymentInformation() ); // Act - PaymentDetails result = await _processor.StartPayment(instance, orderDetails, "nb"); + PaymentDetails result = await _processor.StartPayment(instance, orderDetails, LanguageConst.Nb); // Assert Assert.NotNull(result); @@ -116,7 +117,7 @@ public async Task StartPayment_WithValidInstanceAndOrderDetails_ReturnsPaymentIn ); // Act - PaymentDetails result = await _processor.StartPayment(instance, orderDetails, "nb"); + PaymentDetails result = await _processor.StartPayment(instance, orderDetails, LanguageConst.Nb); // Assert result.Should().NotBeNull(); @@ -199,7 +200,7 @@ public async Task GetPaymentStatus_WithValidPaymentReferenceAndExpectedTotal_Ret Instance instance = CreateInstance(); const string paymentReference = "12345"; const decimal expectedTotalIncVat = 100; - const string language = "nb"; + string language = LanguageConst.Nb; _netsClientMock .Setup(x => x.RetrievePayment(paymentReference)) diff --git a/test/Altinn.App.Core.Tests/Implementation/AppResourcesSITests.cs b/test/Altinn.App.Core.Tests/Implementation/AppResourcesSITests.cs index 72c0c9575..9cf24cbe6 100644 --- a/test/Altinn.App.Core.Tests/Implementation/AppResourcesSITests.cs +++ b/test/Altinn.App.Core.Tests/Implementation/AppResourcesSITests.cs @@ -15,8 +15,8 @@ namespace Altinn.App.Core.Tests.Implementation; public class AppResourcesSITests { - private readonly string appBasePath = Path.Combine("Implementation", "TestData") + Path.DirectorySeparatorChar; - private readonly TelemetrySink telemetry = new(); + private readonly string _appBasePath = Path.Combine("Implementation", "TestData") + Path.DirectorySeparatorChar; + private readonly TelemetrySink _telemetry = new(); [Fact] public void GetApplication_desrializes_file_from_disk() @@ -29,7 +29,7 @@ public void GetApplication_desrializes_file_from_disk() appMetadata, null, new NullLogger(), - telemetry.Object + _telemetry.Object ); Application expected = new Application() { @@ -80,7 +80,7 @@ public void GetApplication_handles_onEntry_null() appMetadata, null, new NullLogger(), - telemetry.Object + _telemetry.Object ); Application expected = new Application() { @@ -137,7 +137,7 @@ public void GetApplication_second_read_from_cache() appMetadata, null, new NullLogger(), - telemetry.Object + _telemetry.Object ); Application expected = new Application() { @@ -192,7 +192,7 @@ public void GetApplicationMetadata_throws_ApplicationConfigException_if_file_not appMetadata, null, new NullLogger(), - telemetry.Object + _telemetry.Object ); Assert.Throws(() => appResources.GetApplication()); } @@ -208,7 +208,7 @@ public void GetApplicationMetadata_throws_ApplicationConfigException_if_deserial appMetadata, null, new NullLogger(), - telemetry.Object + _telemetry.Object ); Assert.Throws(() => appResources.GetApplication()); } @@ -224,7 +224,7 @@ public void GetApplicationXACMLPolicy_return_policyfile_as_string() appMetadata, null, new NullLogger(), - telemetry.Object + _telemetry.Object ); string expected = "" + Environment.NewLine + "policy"; var actual = appResources.GetApplicationXACMLPolicy(); @@ -242,7 +242,7 @@ public void GetApplicationXACMLPolicy_return_null_if_file_not_found() appMetadata, null, new NullLogger(), - telemetry.Object + _telemetry.Object ); var actual = appResources.GetApplicationXACMLPolicy(); actual.Should().BeNull(); @@ -259,7 +259,7 @@ public void GetApplicationBPMNProcess_return_process_as_string() appMetadata, null, new NullLogger(), - telemetry.Object + _telemetry.Object ); string expected = "" + Environment.NewLine + "process"; var actual = appResources.GetApplicationBPMNProcess(); @@ -277,7 +277,7 @@ public void GetApplicationBPMNProcess_return_null_if_file_not_found() appMetadata, null, new NullLogger(), - telemetry.Object + _telemetry.Object ); var actual = appResources.GetApplicationBPMNProcess(); actual.Should().BeNull(); @@ -292,7 +292,7 @@ private AppSettings GetAppSettings( { AppSettings appSettings = new AppSettings() { - AppBasePath = appBasePath, + AppBasePath = _appBasePath, ConfigurationFolder = subfolder + Path.DirectorySeparatorChar, AuthorizationFolder = string.Empty, ProcessFolder = string.Empty, diff --git a/test/Altinn.App.Core.Tests/Implementation/TextClientTest.cs b/test/Altinn.App.Core.Tests/Implementation/TextClientTest.cs index c3d995ae6..f7bc7bc2f 100644 --- a/test/Altinn.App.Core.Tests/Implementation/TextClientTest.cs +++ b/test/Altinn.App.Core.Tests/Implementation/TextClientTest.cs @@ -3,6 +3,7 @@ using System.Text; using Altinn.App.Core.Configuration; using Altinn.App.Core.Infrastructure.Clients.Storage; +using Altinn.App.Core.Internal.Language; using Altinn.Platform.Storage.Interface.Models; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Caching.Memory; @@ -17,34 +18,34 @@ namespace Altinn.App.PlatformServices.Tests.Implementation; public class TextClientTest { - private readonly Mock> platformSettingsOptions; - private readonly Mock> appSettingsOptions; - private readonly Mock handlerMock; - private readonly Mock contextAccessor; - private readonly Mock> logger; - private readonly IMemoryCache memoryCache; + private readonly Mock> _platformSettingsOptions; + private readonly Mock> _appSettingsOptions; + private readonly Mock _handlerMock; + private readonly Mock _contextAccessor; + private readonly Mock> _logger; + private readonly IMemoryCache _memoryCache; public TextClientTest() { - platformSettingsOptions = new Mock>(); - appSettingsOptions = new Mock>(); - handlerMock = new Mock(MockBehavior.Strict); - contextAccessor = new Mock(); - logger = new Mock>(); + _platformSettingsOptions = new Mock>(); + _appSettingsOptions = new Mock>(); + _handlerMock = new Mock(MockBehavior.Strict); + _contextAccessor = new Mock(); + _logger = new Mock>(); var services = new ServiceCollection(); services.AddMemoryCache(); var serviceProvider = services.BuildServiceProvider(); - memoryCache = serviceProvider.GetService(); + _memoryCache = serviceProvider.GetService(); } [Fact] public async Task GetAppTextNb_SuccessfulCallToStorage() { // Arrange - memoryCache.Remove("org-app-nb"); - TextResource texts = new TextResource { Language = "nb" }; + _memoryCache.Remove("org-app-nb"); + TextResource texts = new TextResource { Language = LanguageConst.Nb }; HttpResponseMessage httpResponseMessage = new HttpResponseMessage { @@ -53,41 +54,41 @@ public async Task GetAppTextNb_SuccessfulCallToStorage() }; InitializeMocks(httpResponseMessage, "texts"); - HttpClient httpClient = new HttpClient(handlerMock.Object); + HttpClient httpClient = new HttpClient(_handlerMock.Object); TextClient target = new TextClient( - appSettingsOptions.Object, - platformSettingsOptions.Object, - logger.Object, - contextAccessor.Object, + _appSettingsOptions.Object, + _platformSettingsOptions.Object, + _logger.Object, + _contextAccessor.Object, httpClient, - memoryCache + _memoryCache ); // Act await target.GetText("org", "app", "nb"); // Assert - handlerMock.VerifyAll(); + _handlerMock.VerifyAll(); } [Fact] public async Task GetAppTextNb_TextSuccessfullyRetrievedFromCache() { // Arrange - memoryCache.Remove("org-app-nb"); - TextResource texts = new TextResource { Language = "nb" }; - memoryCache.Set("org-app-nb", texts); + _memoryCache.Remove("org-app-nb"); + TextResource texts = new TextResource { Language = LanguageConst.Nb }; + _memoryCache.Set("org-app-nb", texts); InitializeMocks(new HttpResponseMessage(), "texts"); - HttpClient httpClient = new HttpClient(handlerMock.Object); + HttpClient httpClient = new HttpClient(_handlerMock.Object); TextClient target = new TextClient( - appSettingsOptions.Object, - platformSettingsOptions.Object, - logger.Object, - contextAccessor.Object, + _appSettingsOptions.Object, + _platformSettingsOptions.Object, + _logger.Object, + _contextAccessor.Object, httpClient, - memoryCache + _memoryCache ); // Act @@ -101,7 +102,7 @@ public async Task GetAppTextNb_TextSuccessfullyRetrievedFromCache() public async Task GetAppTextNb_StorageReturnsError() { // Arrange - memoryCache.Remove("org-app-nb"); + _memoryCache.Remove("org-app-nb"); HttpResponseMessage httpResponseMessage = new HttpResponseMessage { @@ -109,14 +110,14 @@ public async Task GetAppTextNb_StorageReturnsError() }; InitializeMocks(httpResponseMessage, "texts"); - HttpClient httpClient = new HttpClient(handlerMock.Object); + HttpClient httpClient = new HttpClient(_handlerMock.Object); TextClient target = new TextClient( - appSettingsOptions.Object, - platformSettingsOptions.Object, - logger.Object, - contextAccessor.Object, + _appSettingsOptions.Object, + _platformSettingsOptions.Object, + _logger.Object, + _contextAccessor.Object, httpClient, - memoryCache + _memoryCache ); // Act @@ -133,14 +134,14 @@ private void InitializeMocks(HttpResponseMessage httpResponseMessage, string url ApiStorageEndpoint = "http://localhost", SubscriptionKey = "key" }; - platformSettingsOptions.Setup(s => s.Value).Returns(platformSettings); + _platformSettingsOptions.Setup(s => s.Value).Returns(platformSettings); AppSettings appSettings = new AppSettings { RuntimeCookieName = "AltinnStudioRuntime" }; - appSettingsOptions.Setup(s => s.Value).Returns(appSettings); + _appSettingsOptions.Setup(s => s.Value).Returns(appSettings); - contextAccessor.Setup(s => s.HttpContext).Returns(new DefaultHttpContext()); + _contextAccessor.Setup(s => s.HttpContext).Returns(new DefaultHttpContext()); - handlerMock + _handlerMock .Protected() .Setup>( "SendAsync", diff --git a/test/Altinn.App.Core.Tests/Internal/Pdf/PdfServiceTests.cs b/test/Altinn.App.Core.Tests/Internal/Pdf/PdfServiceTests.cs index c2251d74e..6cc21dcaf 100644 --- a/test/Altinn.App.Core.Tests/Internal/Pdf/PdfServiceTests.cs +++ b/test/Altinn.App.Core.Tests/Internal/Pdf/PdfServiceTests.cs @@ -1,18 +1,23 @@ using System.Net; +using System.Security.Claims; using Altinn.App.Common.Tests; using Altinn.App.Core.Configuration; using Altinn.App.Core.Infrastructure.Clients.Pdf; using Altinn.App.Core.Internal.App; using Altinn.App.Core.Internal.Auth; using Altinn.App.Core.Internal.Data; +using Altinn.App.Core.Internal.Language; using Altinn.App.Core.Internal.Pdf; using Altinn.App.Core.Internal.Profile; using Altinn.App.PlatformServices.Tests.Helpers; using Altinn.App.PlatformServices.Tests.Mocks; +using Altinn.Platform.Profile.Models; using Altinn.Platform.Storage.Interface.Models; +using AltinnCore.Authentication.Constants; using FluentAssertions; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Options; +using Microsoft.Extensions.Primitives; using Moq; namespace Altinn.App.PlatformServices.Tests.Internal.Pdf; @@ -26,14 +31,15 @@ public class PdfServiceTests private readonly Mock _httpContextAccessor = new(); private readonly Mock _pdfGeneratorClient = new(); private readonly Mock _profile = new(); - private readonly IOptions _pdfGeneratorSettingsOptions = - Microsoft.Extensions.Options.Options.Create(new() { }); + private readonly IOptions _pdfGeneratorSettingsOptions = Options.Create( + new() { } + ); - private readonly IOptions _generalSettingsOptions = - Microsoft.Extensions.Options.Options.Create(new() { HostName = HostName }); + private readonly IOptions _generalSettingsOptions = Options.Create( + new() { HostName = HostName } + ); - private readonly IOptions _platformSettingsOptions = - Microsoft.Extensions.Options.Options.Create(new() { }); + private readonly IOptions _platformSettingsOptions = Options.Create(new() { }); private readonly Mock _userTokenProvider; @@ -42,9 +48,9 @@ public PdfServiceTests() var resource = new TextResource() { Id = "digdir-not-really-an-app-nb", - Language = "nb", + Language = LanguageConst.Nb, Org = "digdir", - Resources = new List() + Resources = [] }; _appResources .Setup(s => s.GetTexts(It.IsAny(), It.IsAny(), It.IsAny())) @@ -131,15 +137,10 @@ public async Task GenerateAndStorePdf() _pdfGeneratorClient.Setup(s => s.GeneratePdf(It.IsAny(), It.IsAny())); _generalSettingsOptions.Value.ExternalAppBaseUrl = "https://{org}.apps.{hostName}/{org}/{app}"; - var target = new PdfService( - _appResources.Object, - _dataClient.Object, - _httpContextAccessor.Object, - _profile.Object, - _pdfGeneratorClient.Object, - _pdfGeneratorSettingsOptions, - _generalSettingsOptions, - telemetrySink.Object + var target = SetupPdfService( + pdfGeneratorClient: _pdfGeneratorClient, + generalSettingsOptions: _generalSettingsOptions, + telemetrySink: telemetrySink ); Instance instance = @@ -192,14 +193,9 @@ public async Task GenerateAndStorePdf_with_generatedFrom() _generalSettingsOptions.Value.ExternalAppBaseUrl = "https://{org}.apps.{hostName}/{org}/{app}"; - var target = new PdfService( - _appResources.Object, - _dataClient.Object, - _httpContextAccessor.Object, - _profile.Object, - _pdfGeneratorClient.Object, - _pdfGeneratorSettingsOptions, - _generalSettingsOptions + var target = SetupPdfService( + pdfGeneratorClient: _pdfGeneratorClient, + generalSettingsOptions: _generalSettingsOptions ); var dataModelId = Guid.NewGuid(); @@ -250,4 +246,155 @@ public async Task GenerateAndStorePdf_with_generatedFrom() Times.Once ); } + + [Fact] + public async Task GetLanguage_ShouldReturnLanguageFromUserPreference() + { + // Arrange + var profileMock = new Mock(); + profileMock + .Setup(s => s.GetUserProfile(It.IsAny())) + .Returns( + Task.FromResult( + new UserProfile + { + UserId = 123, + ProfileSettingPreference = new ProfileSettingPreference { Language = LanguageConst.En } + } + ) + ); + var user = new ClaimsPrincipal(new ClaimsIdentity([new(AltinnCoreClaimTypes.UserId, "123")], "TestAuthType")); + + var target = SetupPdfService(profile: profileMock); + + // Act + var language = await target.GetLanguage(user); + + // Assert + language.Should().Be(LanguageConst.En); + } + + [Fact] + public async Task GetLanguage_NoLanguageInUserPreference_ShouldReturnBokmål() + { + // Arrange + var profileMock = new Mock(); + profileMock + .Setup(s => s.GetUserProfile(It.IsAny())) + .Returns( + Task.FromResult( + new UserProfile + { + UserId = 123, + ProfileSettingPreference = new ProfileSettingPreference + { + /* No language preference set*/ + } + } + ) + ); + var user = new ClaimsPrincipal(new ClaimsIdentity([new(AltinnCoreClaimTypes.UserId, "123")], "TestAuthType")); + + var target = SetupPdfService(profile: profileMock); + + // Act + var language = await target.GetLanguage(user); + + // Assert + language.Should().Be(LanguageConst.Nb); + } + + [Fact] + public async Task GetLanguage_UserIsNull_ShouldReturnBokmål() + { + // Arrange + ClaimsPrincipal? user = null; + var target = SetupPdfService(); + + // Act + var language = await target.GetLanguage(user); + + // Assert + language.Should().Be(LanguageConst.Nb); + } + + [Fact] + public async Task GetLanguage_UserProfileIsNull_ShouldThrow() + { + // Arrange + var user = new ClaimsPrincipal(new ClaimsIdentity([new(AltinnCoreClaimTypes.UserId, "123")], "TestAuthType")); + + var profileMock = new Mock(); + profileMock.Setup(s => s.GetUserProfile(It.IsAny())).Returns(Task.FromResult(null)); + + var target = SetupPdfService(profile: profileMock); + + // Act + var func = async () => await target.GetLanguage(user); + + // Assert + await func.Should().ThrowAsync().WithMessage("Could not get user profile while getting language"); + } + + [Fact] + public void GetOverridenLanguage_ShouldReturnLanguageFromQuery() + { + // Arrange + var queries = new QueryCollection(new Dictionary { { "lang", LanguageConst.Nb } }); + + // Act + var language = PdfService.GetOverriddenLanguage(queries); + + // Assert + language.Should().Be(LanguageConst.Nb); + } + + [Fact] + public void GetOverridenLanguage_HttpContextIsNull_ShouldReturnNull() + { + // Arrange + QueryCollection? queries = null; + + // Act + var language = PdfService.GetOverriddenLanguage(queries); + + // Assert + language.Should().BeNull(); + } + + [Fact] + public void GetOverridenLanguage_NoLanguageInQuery_ShouldReturnNull() + { + // Arrange + IQueryCollection queries = new QueryCollection(); + + // Act + var language = PdfService.GetOverriddenLanguage(queries); + + // Assert + language.Should().BeNull(); + } + + private PdfService SetupPdfService( + Mock? appResources = null, + Mock? dataClient = null, + Mock? httpContentAccessor = null, + Mock? profile = null, + Mock? pdfGeneratorClient = null, + IOptions? pdfGeneratorSettingsOptions = null, + IOptions? generalSettingsOptions = null, + TelemetrySink? telemetrySink = null + ) + { + return new PdfService( + appResources?.Object ?? _appResources.Object, + dataClient?.Object ?? _dataClient.Object, + httpContentAccessor?.Object ?? _httpContextAccessor.Object, + profile?.Object ?? _profile.Object, + pdfGeneratorClient?.Object ?? _pdfGeneratorClient.Object, + pdfGeneratorSettingsOptions ?? _pdfGeneratorSettingsOptions, + generalSettingsOptions ?? _generalSettingsOptions, + telemetrySink?.Object + ); + } }