Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into feat/multi-data-model…
Browse files Browse the repository at this point in the history
…-with-validation
  • Loading branch information
ivarne committed Aug 22, 2024
2 parents 79a918b + 1a630c9 commit 1703585
Show file tree
Hide file tree
Showing 33 changed files with 422 additions and 223 deletions.
2 changes: 1 addition & 1 deletion src/Altinn.App.Api/Altinn.App.Api.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="1.9.0" />
<PackageReference Include="Azure.Monitor.OpenTelemetry.Exporter" Version="1.3.0" />
<PackageReference Include="Azure.Identity" Version="1.12.0" />
<PackageReference Include="Azure.Extensions.AspNetCore.Configuration.Secrets" Version="1.3.1" />
<PackageReference Include="Azure.Extensions.AspNetCore.Configuration.Secrets" Version="1.3.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Altinn.App.Core\Altinn.App.Core.csproj" />
Expand Down
3 changes: 2 additions & 1 deletion src/Altinn.App.Api/Controllers/OptionsController.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -84,7 +85,7 @@ [FromQuery] Dictionary<string, string> queryParams
AppOptions appOptions = await _appOptionsService.GetOptionsAsync(
instanceIdentifier,
optionsId,
language ?? "nb",
language ?? LanguageConst.Nb,
queryParams
);

Expand Down
5 changes: 3 additions & 2 deletions src/Altinn.App.Api/Controllers/TextsController.cs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -40,9 +41,9 @@ public async Task<ActionResult<TextResource>> 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)
Expand Down
2 changes: 1 addition & 1 deletion src/Altinn.App.Api/Extensions/HostBuilderExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Altinn.App.Core.Internal.App;
using Altinn.App.Core.Internal.App;
using Azure.Identity;

namespace Altinn.App.Api.Extensions;
Expand Down
2 changes: 1 addition & 1 deletion src/Altinn.App.Api/Helpers/ValidContributorHelper.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Globalization;
using System.Globalization;
using Altinn.Platform.Storage.Interface.Models;

namespace Altinn.App.Api.Helpers;
Expand Down
2 changes: 1 addition & 1 deletion src/Altinn.App.Core/Altinn.App.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<PackageReference Include="JsonPatch.Net" Version="3.1.1" />
<PackageReference Include="JWTCookieAuthentication" Version="3.0.1" />
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.22.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Hybrid" Version="[9.0.0-preview.6.24328.4]" NoWarn="NU5104" />
<PackageReference Include="Microsoft.Extensions.Caching.Hybrid" Version="[9.0.0-preview.7.24406.2]" NoWarn="NU5104" />
<PackageReference Include="Microsoft.FeatureManagement.AspNetCore" Version="3.5.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NetEscapades.EnumGenerators" Version="1.0.0-beta09" PrivateAssets="all" ExcludeAssets="runtime" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public async Task<MaskinportenTokenResponse> GetAccessToken(
HasSetExpiration: false
);
},
token: cancellationToken,
cancellationToken: cancellationToken,
options: _defaultCacheExpiration
);

Expand All @@ -99,7 +99,7 @@ await _tokenCache.SetAsync(
cacheKey,
result,
options: CacheExpiry(result.Expiration),
token: cancellationToken
cancellationToken: cancellationToken
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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
{
Expand Down
8 changes: 8 additions & 0 deletions src/Altinn.App.Core/Internal/Language/LanguageConst.cs
Original file line number Diff line number Diff line change
@@ -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";
}
64 changes: 37 additions & 27 deletions src/Altinn.App.Core/Internal/Pdf/PdfService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand All @@ -85,9 +89,12 @@ public async Task GenerateAndStorePdf(Instance instance, string taskId, Cancella
public async Task<Stream> 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);
}
Expand Down Expand Up @@ -128,14 +135,18 @@ private static Uri BuildUri(string baseUrl, string pagePath, string language)
return new Uri(url);
}

private async Task<string> GetLanguage()
internal async Task<string> 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)
Expand All @@ -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<TextResource?> 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;
Expand All @@ -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);
}
Expand All @@ -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";
}
Expand Down
6 changes: 3 additions & 3 deletions test/Altinn.App.Api.Tests/Altinn.App.Api.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.7" />
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="8.0.7" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.Testing" Version="8.7.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.8" />
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="8.0.8" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.Testing" Version="8.8.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageReference Include="Moq" Version="4.20.70" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.7.0" />
Expand Down
25 changes: 13 additions & 12 deletions test/Altinn.App.Api.Tests/Controllers/DataController_PatchTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,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 App.IntegrationTests.Mocks.Services;
Expand Down Expand Up @@ -41,9 +42,9 @@ public class DataControllerPatchTests : ApiTestBase, IClassFixture<WebApplicatio
private const string App = "contributer-restriction";
private const int UserId = 1337;
private const int InstanceOwnerPartyId = 500600;
private static readonly Guid InstanceGuid = new("0fc98a23-fe31-4ef5-8fb9-dd3f479354cd");
private static readonly string InstanceId = $"{InstanceOwnerPartyId}/{InstanceGuid}";
private static readonly Guid DataGuid = new("fc121812-0336-45fb-a75c-490df3ad5109");
private static readonly Guid _instanceGuid = new("0fc98a23-fe31-4ef5-8fb9-dd3f479354cd");
private static readonly string _instanceId = $"{InstanceOwnerPartyId}/{_instanceGuid}";
private static readonly Guid _dataGuid = new("fc121812-0336-45fb-a75c-490df3ad5109");

// Define mocks
private readonly Mock<IDataProcessor> _dataProcessorMock = new(MockBehavior.Strict);
Expand All @@ -64,8 +65,8 @@ public DataControllerPatchTests(WebApplicationFactory<Program> 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
Expand All @@ -80,7 +81,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}";
Expand Down Expand Up @@ -168,7 +169,7 @@ public async Task ValidName_ReturnsOk()
p =>
p.ProcessDataWrite(
It.IsAny<Instance>(),
It.Is<Guid>(dataId => dataId == DataGuid),
It.Is<Guid>(dataId => dataId == _dataGuid),
It.IsAny<Skjema>(),
It.IsAny<Skjema?>(),
null
Expand Down Expand Up @@ -316,7 +317,7 @@ public async Task NullName_ReturnsOkAndValidationError()
p =>
p.ProcessDataWrite(
It.IsAny<Instance>(),
It.Is<Guid>(dataId => dataId == DataGuid),
It.Is<Guid>(dataId => dataId == _dataGuid),
It.IsAny<Skjema>(),
It.IsAny<Skjema?>(),
null
Expand Down Expand Up @@ -427,7 +428,7 @@ public async Task TestEmptyListAndInsertElement_ReturnsNewModel()
p =>
p.ProcessDataWrite(
It.IsAny<Instance>(),
It.Is<Guid>(dataId => dataId == DataGuid),
It.Is<Guid>(dataId => dataId == _dataGuid),
It.Is<Skjema>(s => s.Melding!.NestedList!.Count == 1),
It.Is<Skjema?>(s => s!.Melding!.NestedList!.Count == 0),
null
Expand Down Expand Up @@ -801,7 +802,7 @@ public async Task RowId_GetsAddedAutomatically()
public async Task DataReadChanges_IsPreservedWhenCallingPatch()
{
_dataProcessorMock
.Setup(p => p.ProcessDataRead(It.IsAny<Instance>(), It.IsAny<Guid>(), It.IsAny<Skjema>(), "nn"))
.Setup(p => p.ProcessDataRead(It.IsAny<Instance>(), It.IsAny<Guid>(), It.IsAny<Skjema>(), LanguageConst.Nn))
.Returns(
(Instance instance, Guid dataGuid, Skjema skjema, string language) =>
{
Expand All @@ -827,7 +828,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);
Expand Down Expand Up @@ -886,7 +887,7 @@ public async Task VerifyLanguageIsPassedToDataProcessor()
p =>
p.ProcessDataWrite(
It.IsAny<Instance>(),
It.Is<Guid>(dataId => dataId == DataGuid),
It.Is<Guid>(dataId => dataId == _dataGuid),
It.IsAny<Skjema>(),
It.IsAny<Skjema?>(),
"es"
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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]
Expand Down
Loading

0 comments on commit 1703585

Please sign in to comment.