diff --git a/src/Altinn.App.Core/Infrastructure/Clients/Storage/InstanceClient.cs b/src/Altinn.App.Core/Infrastructure/Clients/Storage/InstanceClient.cs index 085c83933..26d493c13 100644 --- a/src/Altinn.App.Core/Infrastructure/Clients/Storage/InstanceClient.cs +++ b/src/Altinn.App.Core/Infrastructure/Clients/Storage/InstanceClient.cs @@ -12,6 +12,7 @@ using Altinn.App.Core.Models; using Altinn.Platform.Storage.Interface.Models; using Microsoft.AspNetCore.WebUtilities; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Microsoft.Extensions.Primitives; @@ -25,62 +26,75 @@ namespace Altinn.App.Core.Infrastructure.Clients.Storage; public class InstanceClient : IInstanceClient { private readonly ILogger _logger; - private readonly IUserTokenProvider _userTokenProvider; private readonly HttpClient _client; private readonly Telemetry? _telemetry; + private readonly IAuthenticationTokenResolver _authenticationTokenResolver; + private readonly AuthenticationMethod _defaultAuthenticationMethod = StorageAuthenticationMethod.CurrentUser(); /// /// Initializes a new instance of the class. /// /// the platform settings - /// the logger - /// Get user token from httpContext /// A HttpClient that can be used to perform HTTP requests against the platform. - /// Telemetry for traces and metrics. + /// The service provider public InstanceClient( IOptions platformSettings, - ILogger logger, - IUserTokenProvider userTokenProvider, HttpClient httpClient, - Telemetry? telemetry = null + IServiceProvider serviceProvider ) { - _logger = logger; - _userTokenProvider = userTokenProvider; + _authenticationTokenResolver = serviceProvider.GetRequiredService(); + _logger = serviceProvider.GetRequiredService>(); + _telemetry = serviceProvider.GetService(); + httpClient.BaseAddress = new Uri(platformSettings.Value.ApiStorageEndpoint); httpClient.DefaultRequestHeaders.Add(General.SubscriptionKeyHeaderName, platformSettings.Value.SubscriptionKey); httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml")); _client = httpClient; - _telemetry = telemetry; } /// - public async Task GetInstance(string app, string org, int instanceOwnerPartyId, Guid instanceId) + public async Task GetInstance( + string app, + string org, + int instanceOwnerPartyId, + Guid instanceId, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ) { using var activity = _telemetry?.StartGetInstanceByGuidActivity(instanceId); string instanceIdentifier = $"{instanceOwnerPartyId}/{instanceId}"; - string apiUrl = $"instances/{instanceIdentifier}"; - string token = _userTokenProvider.GetUserToken(); + + JwtToken token = await _authenticationTokenResolver.GetAccessToken( + authenticationMethod ?? _defaultAuthenticationMethod, + cancellationToken: cancellationToken + ); HttpResponseMessage response = await _client.GetAsync(token, apiUrl); + if (response.StatusCode == HttpStatusCode.OK) { - string instanceData = await response.Content.ReadAsStringAsync(); + string instanceData = await response.Content.ReadAsStringAsync(cancellationToken); // ! TODO: this null-forgiving operator should be fixed/removed for the next major release Instance instance = JsonConvert.DeserializeObject(instanceData)!; return instance; } else { - _logger.LogError($"Unable to fetch instance with instance id {instanceId}"); + _logger.LogError("Unable to fetch instance with instance id {InstanceId}", instanceId); throw await PlatformHttpException.CreateAsync(response); } } /// - public async Task GetInstance(Instance instance) + public async Task GetInstance( + Instance instance, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ) { Guid instanceGuid = Guid.Parse(instance.Id.Split("/")[1]); using var activity = _telemetry?.StartGetInstanceByInstanceActivity(instanceGuid); @@ -88,16 +102,24 @@ public async Task GetInstance(Instance instance) string org = instance.Org; int instanceOwnerPartyId = int.Parse(instance.InstanceOwner.PartyId, CultureInfo.InvariantCulture); - return await GetInstance(app, org, instanceOwnerPartyId, instanceGuid); + return await GetInstance(app, org, instanceOwnerPartyId, instanceGuid, cancellationToken: cancellationToken); } /// - public async Task> GetInstances(Dictionary queryParams) + public async Task> GetInstances( + Dictionary queryParams, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ) { using var activity = _telemetry?.StartGetInstancesActivity(); var apiUrl = QueryHelpers.AddQueryString("instances", queryParams); - string token = _userTokenProvider.GetUserToken(); + JwtToken token = await _authenticationTokenResolver.GetAccessToken( + authenticationMethod ?? _defaultAuthenticationMethod, + cancellationToken: cancellationToken + ); + QueryResponse queryResponse = await QueryInstances(token, apiUrl); if (queryResponse.Count == 0) @@ -135,35 +157,48 @@ private async Task> QueryInstances(string token, string } /// - public async Task UpdateProcess(Instance instance) + public async Task UpdateProcess( + Instance instance, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ) { using var activity = _telemetry?.StartUpdateProcessActivity(instance); ProcessState processState = instance.Process; - string apiUrl = $"instances/{instance.Id}/process"; - string token = _userTokenProvider.GetUserToken(); + + JwtToken token = await _authenticationTokenResolver.GetAccessToken( + authenticationMethod ?? _defaultAuthenticationMethod, + cancellationToken: cancellationToken + ); string processStateString = JsonConvert.SerializeObject(processState); - _logger.LogInformation($"update process state: {processStateString}"); + _logger.LogInformation("update process state: {ProcessStateString}", processStateString); StringContent httpContent = new(processStateString, Encoding.UTF8, "application/json"); HttpResponseMessage response = await _client.PutAsync(token, apiUrl, httpContent); + if (response.StatusCode == HttpStatusCode.OK) { - string instanceData = await response.Content.ReadAsStringAsync(); + string instanceData = await response.Content.ReadAsStringAsync(cancellationToken); // ! TODO: this null-forgiving operator should be fixed/removed for the next major release Instance updatedInstance = JsonConvert.DeserializeObject(instanceData)!; return updatedInstance; } else { - _logger.LogError($"Unable to update instance process with instance id {instance.Id}"); + _logger.LogError("Unable to update instance process with instance id {InstanceId}", instance.Id); throw await PlatformHttpException.CreateAsync(response); } } /// - public async Task UpdateProcessAndEvents(Instance instance, List events) + public async Task UpdateProcessAndEvents( + Instance instance, + List events, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ) { using var activity = _telemetry?.StartUpdateProcessActivity(instance, events.Count); ProcessState processState = instance.Process; @@ -172,35 +207,50 @@ public async Task UpdateProcessAndEvents(Instance instance, List(instanceData) - ?? throw new Exception("Could not deserialize instance"); + ?? throw new JsonException("Could not deserialize instance"); return updatedInstance; } else { - _logger.LogError($"Unable to update instance process with instance id {instance.Id}"); + _logger.LogError("Unable to update instance process with instance id {InstanceId}", instance.Id); throw await PlatformHttpException.CreateAsync(response); } } /// - public async Task CreateInstance(string org, string app, Instance instanceTemplate) + public async Task CreateInstance( + string org, + string app, + Instance instanceTemplate, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ) { using var activity = _telemetry?.StartCreateInstanceActivity(); string apiUrl = $"instances?appId={org}/{app}"; - string token = _userTokenProvider.GetUserToken(); + + JwtToken token = await _authenticationTokenResolver.GetAccessToken( + authenticationMethod ?? _defaultAuthenticationMethod, + cancellationToken: cancellationToken + ); StringContent content = new(JsonConvert.SerializeObject(instanceTemplate), Encoding.UTF8, "application/json"); HttpResponseMessage response = await _client.PostAsync(token, apiUrl, content); @@ -209,30 +259,41 @@ public async Task CreateInstance(string org, string app, Instance inst { // ! TODO: this null-forgiving operator should be fixed/removed for the next major release Instance createdInstance = JsonConvert.DeserializeObject( - await response.Content.ReadAsStringAsync() + await response.Content.ReadAsStringAsync(cancellationToken) )!; _telemetry?.InstanceCreated(createdInstance); return createdInstance; } _logger.LogError( - $"Unable to create instance {response.StatusCode} - {await response.Content.ReadAsStringAsync()}" + "Unable to create instance {StatusCode} - {Response}", + response.StatusCode, + await response.Content.ReadAsStringAsync(cancellationToken) ); throw await PlatformHttpException.CreateAsync(response); } /// - public async Task AddCompleteConfirmation(int instanceOwnerPartyId, Guid instanceGuid) + public async Task AddCompleteConfirmation( + int instanceOwnerPartyId, + Guid instanceGuid, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ) { using var activity = _telemetry?.StartCompleteConfirmationActivity(instanceGuid, instanceOwnerPartyId); string apiUrl = $"instances/{instanceOwnerPartyId}/{instanceGuid}/complete"; - string token = _userTokenProvider.GetUserToken(); + + JwtToken token = await _authenticationTokenResolver.GetAccessToken( + authenticationMethod ?? _defaultAuthenticationMethod, + cancellationToken: cancellationToken + ); HttpResponseMessage response = await _client.PostAsync(token, apiUrl, new StringContent(string.Empty)); if (response.StatusCode == HttpStatusCode.OK) { - string instanceData = await response.Content.ReadAsStringAsync(); + string instanceData = await response.Content.ReadAsStringAsync(cancellationToken); // ! TODO: this null-forgiving operator should be fixed/removed for the next major release Instance instance = JsonConvert.DeserializeObject(instanceData)!; _telemetry?.InstanceCompleted(instance); @@ -243,24 +304,37 @@ public async Task AddCompleteConfirmation(int instanceOwnerPartyId, Gu } /// - public async Task UpdateReadStatus(int instanceOwnerPartyId, Guid instanceGuid, string readStatus) + public async Task UpdateReadStatus( + int instanceOwnerPartyId, + Guid instanceGuid, + string readStatus, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ) { using var activity = _telemetry?.StartUpdateReadStatusActivity(instanceGuid, instanceOwnerPartyId); string apiUrl = $"instances/{instanceOwnerPartyId}/{instanceGuid}/readstatus?status={readStatus}"; - string token = _userTokenProvider.GetUserToken(); + + JwtToken token = await _authenticationTokenResolver.GetAccessToken( + authenticationMethod ?? _defaultAuthenticationMethod, + cancellationToken: cancellationToken + ); HttpResponseMessage response = await _client.PutAsync(token, apiUrl, new StringContent(string.Empty)); if (response.StatusCode == HttpStatusCode.OK) { - string instanceData = await response.Content.ReadAsStringAsync(); + string instanceData = await response.Content.ReadAsStringAsync(cancellationToken); // ! TODO: this null-forgiving operator should be fixed/removed for the next major release Instance instance = JsonConvert.DeserializeObject(instanceData)!; return instance; } _logger.LogError( - $"Could not update read status for instance {instanceOwnerPartyId}/{instanceGuid}. Request failed with status code {response.StatusCode}" + "Could not update read status for instance {InstanceOwnerPartyId}/{InstanceGuid}. Request failed with status code {StatusCode}", + instanceOwnerPartyId, + instanceGuid, + response.StatusCode ); #nullable disable return null; @@ -268,11 +342,21 @@ public async Task UpdateReadStatus(int instanceOwnerPartyId, Guid inst } /// - public async Task UpdateSubstatus(int instanceOwnerPartyId, Guid instanceGuid, Substatus substatus) + public async Task UpdateSubstatus( + int instanceOwnerPartyId, + Guid instanceGuid, + Substatus substatus, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ) { using var activity = _telemetry?.StartUpdateSubStatusActivity(instanceGuid, instanceOwnerPartyId); string apiUrl = $"instances/{instanceOwnerPartyId}/{instanceGuid}/substatus"; - string token = _userTokenProvider.GetUserToken(); + + JwtToken token = await _authenticationTokenResolver.GetAccessToken( + authenticationMethod ?? _defaultAuthenticationMethod, + cancellationToken: cancellationToken + ); HttpResponseMessage response = await _client.PutAsync( token, @@ -282,7 +366,7 @@ public async Task UpdateSubstatus(int instanceOwnerPartyId, Guid insta if (response.StatusCode == HttpStatusCode.OK) { - string instanceData = await response.Content.ReadAsStringAsync(); + string instanceData = await response.Content.ReadAsStringAsync(cancellationToken); // ! TODO: this null-forgiving operator should be fixed/removed for the next major release Instance instance = JsonConvert.DeserializeObject(instanceData)!; return instance; @@ -295,12 +379,18 @@ public async Task UpdateSubstatus(int instanceOwnerPartyId, Guid insta public async Task UpdatePresentationTexts( int instanceOwnerPartyId, Guid instanceGuid, - PresentationTexts presentationTexts + PresentationTexts presentationTexts, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default ) { using var activity = _telemetry?.StartUpdatePresentationTextActivity(instanceGuid, instanceOwnerPartyId); string apiUrl = $"instances/{instanceOwnerPartyId}/{instanceGuid}/presentationtexts"; - string token = _userTokenProvider.GetUserToken(); + + JwtToken token = await _authenticationTokenResolver.GetAccessToken( + authenticationMethod ?? _defaultAuthenticationMethod, + cancellationToken: cancellationToken + ); HttpResponseMessage response = await _client.PutAsync( token, @@ -310,7 +400,7 @@ PresentationTexts presentationTexts if (response.StatusCode == HttpStatusCode.OK) { - string instanceData = await response.Content.ReadAsStringAsync(); + string instanceData = await response.Content.ReadAsStringAsync(cancellationToken); // ! TODO: this null-forgiving operator should be fixed/removed for the next major release Instance instance = JsonConvert.DeserializeObject(instanceData)!; return instance; @@ -320,11 +410,21 @@ PresentationTexts presentationTexts } /// - public async Task UpdateDataValues(int instanceOwnerPartyId, Guid instanceGuid, DataValues dataValues) + public async Task UpdateDataValues( + int instanceOwnerPartyId, + Guid instanceGuid, + DataValues dataValues, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ) { using var activity = _telemetry?.StartUpdateDataValuesActivity(instanceGuid, instanceOwnerPartyId); string apiUrl = $"instances/{instanceOwnerPartyId}/{instanceGuid}/datavalues"; - string token = _userTokenProvider.GetUserToken(); + + JwtToken token = await _authenticationTokenResolver.GetAccessToken( + authenticationMethod ?? _defaultAuthenticationMethod, + cancellationToken: cancellationToken + ); HttpResponseMessage response = await _client.PutAsync( token, @@ -334,7 +434,7 @@ public async Task UpdateDataValues(int instanceOwnerPartyId, Guid inst if (response.StatusCode == HttpStatusCode.OK) { - string instanceData = await response.Content.ReadAsStringAsync(); + string instanceData = await response.Content.ReadAsStringAsync(cancellationToken); // ! TODO: this null-forgiving operator should be fixed/removed for the next major release Instance instance = JsonConvert.DeserializeObject(instanceData)!; return instance; @@ -344,17 +444,27 @@ public async Task UpdateDataValues(int instanceOwnerPartyId, Guid inst } /// - public async Task DeleteInstance(int instanceOwnerPartyId, Guid instanceGuid, bool hard) + public async Task DeleteInstance( + int instanceOwnerPartyId, + Guid instanceGuid, + bool hard, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ) { using var activity = _telemetry?.StartDeleteInstanceActivity(instanceGuid, instanceOwnerPartyId); string apiUrl = $"instances/{instanceOwnerPartyId}/{instanceGuid}?hard={hard}"; - string token = _userTokenProvider.GetUserToken(); + + JwtToken token = await _authenticationTokenResolver.GetAccessToken( + authenticationMethod ?? _defaultAuthenticationMethod, + cancellationToken: cancellationToken + ); HttpResponseMessage response = await _client.DeleteAsync(token, apiUrl); if (response.StatusCode == HttpStatusCode.OK) { - string instanceData = await response.Content.ReadAsStringAsync(); + string instanceData = await response.Content.ReadAsStringAsync(cancellationToken); // ! TODO: this null-forgiving operator should be fixed/removed for the next major release Instance instance = JsonConvert.DeserializeObject(instanceData)!; _telemetry?.InstanceDeleted(instance); diff --git a/src/Altinn.App.Core/Internal/Instances/IInstanceClient.cs b/src/Altinn.App.Core/Internal/Instances/IInstanceClient.cs index 9c1fecc0f..4f9487e10 100644 --- a/src/Altinn.App.Core/Internal/Instances/IInstanceClient.cs +++ b/src/Altinn.App.Core/Internal/Instances/IInstanceClient.cs @@ -1,3 +1,4 @@ +using Altinn.App.Core.Features; using Altinn.App.Core.Models; using Altinn.Platform.Storage.Interface.Models; using Microsoft.Extensions.Primitives; @@ -12,27 +13,51 @@ public interface IInstanceClient /// /// Gets the instance /// - Task GetInstance(string app, string org, int instanceOwnerPartyId, Guid instanceId); + Task GetInstance( + string app, + string org, + int instanceOwnerPartyId, + Guid instanceId, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ); /// /// Gets the instance anew. Instance must have set appId, instanceOwner.PartyId and Id. /// - Task GetInstance(Instance instance); + Task GetInstance( + Instance instance, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ); /// /// Gets a list of instances based on a dictionary of provided query parameters. /// - Task> GetInstances(Dictionary queryParams); + Task> GetInstances( + Dictionary queryParams, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ); /// /// Updates the process model of the instance and returns the updated instance. /// - Task UpdateProcess(Instance instance); + Task UpdateProcess( + Instance instance, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ); /// /// Updates the process model of the instance and the instance events and returns the updated instance. /// - Task UpdateProcessAndEvents(Instance instance, List events); + Task UpdateProcessAndEvents( + Instance instance, + List events, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ); /// /// Creates an instance of an application with no data. @@ -40,8 +65,16 @@ public interface IInstanceClient /// Unique identifier of the organisation responsible for the app. /// Application identifier which is unique within an organisation. /// the instance template to create (must have instanceOwner with partyId, personNumber or organisationNumber set) + /// An optional specification of the authentication method to use for requests + /// An optional cancellation token /// The created instance - Task CreateInstance(string org, string app, Instance instanceTemplate); + Task CreateInstance( + string org, + string app, + Instance instanceTemplate, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ); /// /// Add complete confirmation. @@ -53,8 +86,15 @@ public interface IInstanceClient /// /// The party id of the instance owner. /// The id of the instance to confirm as complete. + /// An optional specification of the authentication method to use for requests + /// An optional cancellation token /// Returns the updated instance. - Task AddCompleteConfirmation(int instanceOwnerPartyId, Guid instanceGuid); + Task AddCompleteConfirmation( + int instanceOwnerPartyId, + Guid instanceGuid, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ); /// /// Update read status. @@ -62,8 +102,16 @@ public interface IInstanceClient /// The party id of the instance owner. /// The id of the instance to confirm as complete. /// The new instance read status. + /// An optional specification of the authentication method to use for requests + /// An optional cancellation token /// Returns the updated instance. - Task UpdateReadStatus(int instanceOwnerPartyId, Guid instanceGuid, string readStatus); + Task UpdateReadStatus( + int instanceOwnerPartyId, + Guid instanceGuid, + string readStatus, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ); /// /// Update substatus. @@ -71,8 +119,16 @@ public interface IInstanceClient /// The party id of the instance owner. /// The id of the instance to be updated. /// The new substatus. + /// An optional specification of the authentication method to use for requests + /// An optional cancellation token /// Returns the updated instance. - Task UpdateSubstatus(int instanceOwnerPartyId, Guid instanceGuid, Substatus substatus); + Task UpdateSubstatus( + int instanceOwnerPartyId, + Guid instanceGuid, + Substatus substatus, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ); /// /// Update presentation texts. @@ -83,11 +139,15 @@ public interface IInstanceClient /// The party id of the instance owner. /// The id of the instance to update presentation texts for. /// The presentation texts + /// An optional specification of the authentication method to use for requests + /// An optional cancellation token /// Returns the updated instance. Task UpdatePresentationTexts( int instanceOwnerPartyId, Guid instanceGuid, - PresentationTexts presentationTexts + PresentationTexts presentationTexts, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default ); /// @@ -99,8 +159,16 @@ PresentationTexts presentationTexts /// The party id of the instance owner. /// The id of the instance to update data values for. /// The data values + /// An optional specification of the authentication method to use for requests + /// An optional cancellation token /// Returns the updated instance. - Task UpdateDataValues(int instanceOwnerPartyId, Guid instanceGuid, DataValues dataValues); + Task UpdateDataValues( + int instanceOwnerPartyId, + Guid instanceGuid, + DataValues dataValues, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ); /// /// Update data data values. @@ -110,11 +178,24 @@ PresentationTexts presentationTexts /// /// The instance /// The data value (null unsets the value) + /// An optional specification of the authentication method to use for requests + /// An optional cancellation token /// Returns the updated instance. - async Task UpdateDataValues(Instance instance, Dictionary dataValues) + async Task UpdateDataValues( + Instance instance, + Dictionary dataValues, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ) { var id = new InstanceIdentifier(instance); - return await UpdateDataValues(id.InstanceOwnerPartyId, id.InstanceGuid, new DataValues { Values = dataValues }); + return await UpdateDataValues( + id.InstanceOwnerPartyId, + id.InstanceGuid, + new DataValues { Values = dataValues }, + authenticationMethod, + cancellationToken + ); } /// @@ -126,10 +207,23 @@ async Task UpdateDataValues(Instance instance, DictionaryThe instance /// The key of the DataValues collection to be updated. /// The data value (null unsets the value) + /// An optional specification of the authentication method to use for requests + /// An optional cancellation token /// Returns the updated instance. - async Task UpdateDataValue(Instance instance, string key, string? value) + async Task UpdateDataValue( + Instance instance, + string key, + string? value, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ) { - return await UpdateDataValues(instance, new Dictionary { { key, value } }); + return await UpdateDataValues( + instance, + new Dictionary { { key, value } }, + authenticationMethod, + cancellationToken + ); } /// @@ -138,6 +232,14 @@ async Task UpdateDataValue(Instance instance, string key, string? valu /// The party id of the instance owner. /// The id of the instance to delete. /// Boolean to indicate if instance should be hard deleted. + /// An optional specification of the authentication method to use for requests + /// An optional cancellation token /// Returns the deleted instance. - Task DeleteInstance(int instanceOwnerPartyId, Guid instanceGuid, bool hard); + Task DeleteInstance( + int instanceOwnerPartyId, + Guid instanceGuid, + bool hard, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ); } diff --git a/test/Altinn.App.Api.Tests/Controllers/FileScanControllerTests.cs b/test/Altinn.App.Api.Tests/Controllers/FileScanControllerTests.cs index a0ae2f1ec..c9094eca6 100644 --- a/test/Altinn.App.Api.Tests/Controllers/FileScanControllerTests.cs +++ b/test/Altinn.App.Api.Tests/Controllers/FileScanControllerTests.cs @@ -1,4 +1,5 @@ using Altinn.App.Api.Controllers; +using Altinn.App.Core.Features; using Altinn.App.Core.Internal.Instances; using Altinn.Platform.Storage.Interface.Models; using FluentAssertions; @@ -68,7 +69,16 @@ Guid instanceId var instanceClientMock = new Mock(); instanceClientMock - .Setup(e => e.GetInstance(app, org, instanceOwnerPartyId, instanceId)) + .Setup(e => + e.GetInstance( + app, + org, + instanceOwnerPartyId, + instanceId, + It.IsAny(), + It.IsAny() + ) + ) .Returns(Task.FromResult(instance)); return instanceClientMock; diff --git a/test/Altinn.App.Api.Tests/Controllers/InstancesController_ActiveInstancesTests.cs b/test/Altinn.App.Api.Tests/Controllers/InstancesController_ActiveInstancesTests.cs index b9ccb89ce..fa7a47239 100644 --- a/test/Altinn.App.Api.Tests/Controllers/InstancesController_ActiveInstancesTests.cs +++ b/test/Altinn.App.Api.Tests/Controllers/InstancesController_ActiveInstancesTests.cs @@ -1,5 +1,6 @@ using Altinn.App.Api.Controllers; using Altinn.App.Api.Models; +using Altinn.App.Core.Features; using Altinn.App.Core.Internal.Instances; using Altinn.App.Core.Internal.Profile; using Altinn.App.Core.Internal.Registers; @@ -28,7 +29,13 @@ public async Task EmptySearchResult_ReturnsOkResult() fixture .Mock() - .Setup(c => c.GetInstances(It.IsAny>())) + .Setup(c => + c.GetInstances( + It.IsAny>(), + It.IsAny(), + It.IsAny() + ) + ) .ReturnsAsync(instances); // Act @@ -42,7 +49,13 @@ public async Task EmptySearchResult_ReturnsOkResult() fixture .Mock() - .Verify(c => c.GetInstances(It.Is>(query => query.ContainsKey("appId")))); + .Verify(c => + c.GetInstances( + It.Is>(query => query.ContainsKey("appId")), + It.IsAny(), + It.IsAny() + ) + ); fixture.VerifyNoOtherCalls(); } @@ -80,7 +93,13 @@ public async Task UnknownUser_ReturnsEmptyString() fixture .Mock() - .Setup(c => c.GetInstances(It.IsAny>())) + .Setup(c => + c.GetInstances( + It.IsAny>(), + It.IsAny(), + It.IsAny() + ) + ) .ReturnsAsync(instances); // _profile.Setup(p=>p.GetUserProfile(12345)).ReturnsAsync(default(UserProfile)!); @@ -95,7 +114,13 @@ public async Task UnknownUser_ReturnsEmptyString() fixture .Mock() - .Verify(c => c.GetInstances(It.Is>(query => query.ContainsKey("appId")))); + .Verify(c => + c.GetInstances( + It.Is>(query => query.ContainsKey("appId")), + It.IsAny(), + It.IsAny() + ) + ); fixture.Mock().Verify(p => p.GetUserProfile(12345)); fixture.VerifyNoOtherCalls(); } @@ -133,7 +158,13 @@ public async Task UserProfilePartyIsNull_ReturnsEmptyString() fixture .Mock() - .Setup(c => c.GetInstances(It.IsAny>())) + .Setup(c => + c.GetInstances( + It.IsAny>(), + It.IsAny(), + It.IsAny() + ) + ) .ReturnsAsync(instances); fixture.Mock().Setup(p => p.GetUserProfile(12345)).ReturnsAsync(new UserProfile()); @@ -148,7 +179,13 @@ public async Task UserProfilePartyIsNull_ReturnsEmptyString() fixture .Mock() - .Verify(c => c.GetInstances(It.Is>(query => query.ContainsKey("appId")))); + .Verify(c => + c.GetInstances( + It.Is>(query => query.ContainsKey("appId")), + It.IsAny(), + It.IsAny() + ) + ); fixture.Mock().Verify(p => p.GetUserProfile(12345)); fixture.VerifyNoOtherCalls(); } @@ -184,7 +221,13 @@ public async Task KnownUser_ReturnsUserName() fixture .Mock() - .Setup(c => c.GetInstances(It.IsAny>())) + .Setup(c => + c.GetInstances( + It.IsAny>(), + It.IsAny(), + It.IsAny() + ) + ) .ReturnsAsync(instances); fixture .Mock() @@ -202,7 +245,13 @@ public async Task KnownUser_ReturnsUserName() fixture .Mock() - .Verify(c => c.GetInstances(It.Is>(query => query.ContainsKey("appId")))); + .Verify(c => + c.GetInstances( + It.Is>(query => query.ContainsKey("appId")), + It.IsAny(), + It.IsAny() + ) + ); fixture.Mock().Verify(p => p.GetUserProfile(12345)); fixture.VerifyNoOtherCalls(); } @@ -239,7 +288,13 @@ public async Task LastChangedBy9digits_LooksForOrg() fixture .Mock() - .Setup(c => c.GetInstances(It.IsAny>())) + .Setup(c => + c.GetInstances( + It.IsAny>(), + It.IsAny(), + It.IsAny() + ) + ) .ReturnsAsync(instances); fixture .Mock() @@ -257,7 +312,13 @@ public async Task LastChangedBy9digits_LooksForOrg() fixture .Mock() - .Verify(c => c.GetInstances(It.Is>(query => query.ContainsKey("appId")))); + .Verify(c => + c.GetInstances( + It.Is>(query => query.ContainsKey("appId")), + It.IsAny(), + It.IsAny() + ) + ); fixture.Mock().Verify(er => er.GetOrganization("123456789")); fixture.VerifyNoOtherCalls(); } @@ -293,7 +354,13 @@ public async Task LastChangedBy9digits_FindsOrg() fixture .Mock() - .Setup(c => c.GetInstances(It.IsAny>())) + .Setup(c => + c.GetInstances( + It.IsAny>(), + It.IsAny(), + It.IsAny() + ) + ) .ReturnsAsync(instances); fixture .Mock() @@ -311,7 +378,13 @@ public async Task LastChangedBy9digits_FindsOrg() fixture .Mock() - .Verify(c => c.GetInstances(It.Is>(query => query.ContainsKey("appId")))); + .Verify(c => + c.GetInstances( + It.Is>(query => query.ContainsKey("appId")), + It.IsAny(), + It.IsAny() + ) + ); fixture.Mock().Verify(er => er.GetOrganization("123456789")); fixture.VerifyNoOtherCalls(); } diff --git a/test/Altinn.App.Api.Tests/Controllers/InstancesController_CopyInstanceTests.cs b/test/Altinn.App.Api.Tests/Controllers/InstancesController_CopyInstanceTests.cs index 68f2a991b..097d9879b 100644 --- a/test/Altinn.App.Api.Tests/Controllers/InstancesController_CopyInstanceTests.cs +++ b/test/Altinn.App.Api.Tests/Controllers/InstancesController_CopyInstanceTests.cs @@ -155,7 +155,16 @@ public async Task CopyInstance_InstanceNotArchived_ReturnsBadRequest() .ReturnsAsync(CreateXacmlResponse("Permit")); fixture .Mock() - .Setup(i => i.GetInstance(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(i => + i.GetInstance( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny() + ) + ) .ReturnsAsync(instance); // Act @@ -203,7 +212,16 @@ public async Task CopyInstance_InstanceDoesNotExists_ReturnsBadRequest() .ReturnsAsync(CreateXacmlResponse("Permit")); fixture .Mock() - .Setup(i => i.GetInstance(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(i => + i.GetInstance( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny() + ) + ) .ThrowsAsync(platformHttpException); // Act @@ -251,7 +269,16 @@ public async Task CopyInstance_PlatformReturnsError_ThrowsException() .ReturnsAsync(CreateXacmlResponse("Permit")); fixture .Mock() - .Setup(i => i.GetInstance(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(i => + i.GetInstance( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny() + ) + ) .ThrowsAsync(platformHttpException); // Act @@ -298,7 +325,16 @@ public async Task CopyInstance_InstantiationValidationFails_ReturnsForbidden() .ReturnsAsync(CreateXacmlResponse("Permit")); fixture .Mock() - .Setup(i => i.GetInstance(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(i => + i.GetInstance( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny() + ) + ) .ReturnsAsync(instance); fixture .Mock() @@ -363,13 +399,39 @@ public async Task CopyInstance_EverythingIsFine_ReturnsRedirect() .ReturnsAsync(CreateXacmlResponse("Permit")); fixture .Mock() - .Setup(i => i.GetInstance(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(i => + i.GetInstance( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny() + ) + ) .ReturnsAsync(instance); fixture .Mock() - .Setup(i => i.CreateInstance(It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(i => + i.CreateInstance( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny() + ) + ) + .ReturnsAsync(instance); + fixture + .Mock() + .Setup(i => + i.GetInstance( + It.IsAny(), + It.IsAny(), + It.IsAny() + ) + ) .ReturnsAsync(instance); - fixture.Mock().Setup(i => i.GetInstance(It.IsAny())).ReturnsAsync(instance); fixture .Mock() .Setup(v => v.Validate(It.IsAny())) @@ -494,13 +556,39 @@ public async Task CopyInstance_WithBinaryData_CopiesBothFormAndBinaryData() .ReturnsAsync(CreateXacmlResponse("Permit")); fixture .Mock() - .Setup(i => i.GetInstance(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(i => + i.GetInstance( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny() + ) + ) .ReturnsAsync(instance); fixture .Mock() - .Setup(i => i.CreateInstance(It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(i => + i.CreateInstance( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny() + ) + ) + .ReturnsAsync(instance); + fixture + .Mock() + .Setup(i => + i.GetInstance( + It.IsAny(), + It.IsAny(), + It.IsAny() + ) + ) .ReturnsAsync(instance); - fixture.Mock().Setup(i => i.GetInstance(It.IsAny())).ReturnsAsync(instance); fixture .Mock() .Setup(v => v.Validate(It.IsAny())) @@ -713,13 +801,39 @@ public async Task CopyInstance_WithExcludedBinaryDataType_SkipsExcludedType() .ReturnsAsync(CreateXacmlResponse("Permit")); fixture .Mock() - .Setup(i => i.GetInstance(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(i => + i.GetInstance( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny() + ) + ) + .ReturnsAsync(instance); + fixture + .Mock() + .Setup(i => + i.CreateInstance( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny() + ) + ) .ReturnsAsync(instance); fixture .Mock() - .Setup(i => i.CreateInstance(It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(i => + i.GetInstance( + It.IsAny(), + It.IsAny(), + It.IsAny() + ) + ) .ReturnsAsync(instance); - fixture.Mock().Setup(i => i.GetInstance(It.IsAny())).ReturnsAsync(instance); fixture .Mock() .Setup(v => v.Validate(It.IsAny())) @@ -931,13 +1045,39 @@ public async Task CopyInstance_IncludeAttachmentsIsTrue_CopiesBinaryData() .ReturnsAsync(CreateXacmlResponse("Permit")); fixture .Mock() - .Setup(i => i.GetInstance(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(i => + i.GetInstance( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny() + ) + ) + .ReturnsAsync(instance); + fixture + .Mock() + .Setup(i => + i.CreateInstance( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny() + ) + ) .ReturnsAsync(instance); fixture .Mock() - .Setup(i => i.CreateInstance(It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(i => + i.GetInstance( + It.IsAny(), + It.IsAny(), + It.IsAny() + ) + ) .ReturnsAsync(instance); - fixture.Mock().Setup(i => i.GetInstance(It.IsAny())).ReturnsAsync(instance); fixture .Mock() .Setup(v => v.Validate(It.IsAny())) @@ -1115,13 +1255,39 @@ public async Task CopyInstance_OnlyBinaryData_NotCopiedByDefault() .ReturnsAsync(CreateXacmlResponse("Permit")); fixture .Mock() - .Setup(i => i.GetInstance(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(i => + i.GetInstance( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny() + ) + ) + .ReturnsAsync(instance); + fixture + .Mock() + .Setup(i => + i.CreateInstance( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny() + ) + ) .ReturnsAsync(instance); fixture .Mock() - .Setup(i => i.CreateInstance(It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(i => + i.GetInstance( + It.IsAny(), + It.IsAny(), + It.IsAny() + ) + ) .ReturnsAsync(instance); - fixture.Mock().Setup(i => i.GetInstance(It.IsAny())).ReturnsAsync(instance); fixture .Mock() .Setup(v => v.Validate(It.IsAny())) diff --git a/test/Altinn.App.Api.Tests/Controllers/PdfControllerTests.cs b/test/Altinn.App.Api.Tests/Controllers/PdfControllerTests.cs index ea986badc..1173ca9d1 100644 --- a/test/Altinn.App.Api.Tests/Controllers/PdfControllerTests.cs +++ b/test/Altinn.App.Api.Tests/Controllers/PdfControllerTests.cs @@ -48,7 +48,16 @@ public class PdfControllerTests public PdfControllerTests() { _instanceClient - .Setup(a => a.GetInstance(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(a => + a.GetInstance( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny() + ) + ) .Returns( Task.FromResult( new Instance() diff --git a/test/Altinn.App.Api.Tests/Controllers/SigningControllerTests.cs b/test/Altinn.App.Api.Tests/Controllers/SigningControllerTests.cs index 6a6802198..ffcaf0766 100644 --- a/test/Altinn.App.Api.Tests/Controllers/SigningControllerTests.cs +++ b/test/Altinn.App.Api.Tests/Controllers/SigningControllerTests.cs @@ -2,6 +2,7 @@ using Altinn.App.Api.Controllers; using Altinn.App.Api.Models; using Altinn.App.Core.Configuration; +using Altinn.App.Core.Features; using Altinn.App.Core.Features.Auth; using Altinn.App.Core.Features.Signing.Models; using Altinn.App.Core.Features.Signing.Services; @@ -72,7 +73,16 @@ public SigningControllerTests(ITestOutputHelper output) _serviceCollection.AddFakeLoggingWithXunit(output); _instanceClientMock - .Setup(x => x.GetInstance(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(x => + x.GetInstance( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny() + ) + ) .ReturnsAsync( new Instance { @@ -596,7 +606,16 @@ public async Task GetAuthorizedOrganizations_TaskTypeIsNotSigning_Returns_BadReq var controller = sp.GetRequiredService(); _instanceClientMock - .Setup(x => x.GetInstance(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(x => + x.GetInstance( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny() + ) + ) .ReturnsAsync( new Instance { @@ -697,7 +716,16 @@ public async Task GetDataElements_WhenTaskTypeIsSigning_Returns_ExpectedDataElem }; _instanceClientMock - .Setup(x => x.GetInstance(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(x => + x.GetInstance( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny() + ) + ) .ReturnsAsync(instance); // Act @@ -733,7 +761,16 @@ public async Task GetDataElements_WhenTaskTypeIsNotSigning_Returns_BadRequest() var controller = sp.GetRequiredService(); _instanceClientMock - .Setup(x => x.GetInstance(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(x => + x.GetInstance( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny() + ) + ) .ReturnsAsync( new Instance { @@ -806,7 +843,16 @@ public async Task GetDataElements_WhenNoMatchingDataTypes_Returns_EmptyList() }; _instanceClientMock - .Setup(x => x.GetInstance(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(x => + x.GetInstance( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny() + ) + ) .ReturnsAsync(instance); // Act diff --git a/test/Altinn.App.Api.Tests/Controllers/ValidateControllerTests.cs b/test/Altinn.App.Api.Tests/Controllers/ValidateControllerTests.cs index d8d8019bb..c045c4dd6 100644 --- a/test/Altinn.App.Api.Tests/Controllers/ValidateControllerTests.cs +++ b/test/Altinn.App.Api.Tests/Controllers/ValidateControllerTests.cs @@ -61,7 +61,16 @@ public async Task ValidateInstance_returns_NotFound_when_GetInstance_returns_nul { // Arrange _instanceMock - .Setup(i => i.GetInstance(App, Org, InstanceOwnerPartyId, _instanceId)) + .Setup(i => + i.GetInstance( + App, + Org, + InstanceOwnerPartyId, + _instanceId, + It.IsAny(), + It.IsAny() + ) + ) .Returns(Task.FromResult(null!)); // Act @@ -81,7 +90,16 @@ public async Task ValidateInstance_throws_ValidationException_when_Instance_Proc Instance instance = new Instance { Id = "instanceId", Process = null }; _instanceMock - .Setup(i => i.GetInstance(App, Org, InstanceOwnerPartyId, _instanceId)) + .Setup(i => + i.GetInstance( + App, + Org, + InstanceOwnerPartyId, + _instanceId, + It.IsAny(), + It.IsAny() + ) + ) .Returns(Task.FromResult(instance)); // Act @@ -106,7 +124,16 @@ public async Task ValidateInstance_throws_ValidationException_when_Instance_Proc }; _instanceMock - .Setup(i => i.GetInstance(App, Org, InstanceOwnerPartyId, _instanceId)) + .Setup(i => + i.GetInstance( + App, + Org, + InstanceOwnerPartyId, + _instanceId, + It.IsAny(), + It.IsAny() + ) + ) .Returns(Task.FromResult(instance)); // Act @@ -149,7 +176,16 @@ public async Task ValidateInstance_returns_OK_with_messages() }; _instanceMock - .Setup(i => i.GetInstance(App, Org, InstanceOwnerPartyId, _instanceId)) + .Setup(i => + i.GetInstance( + App, + Org, + InstanceOwnerPartyId, + _instanceId, + It.IsAny(), + It.IsAny() + ) + ) .Returns(Task.FromResult(instance)); _validationMock @@ -182,7 +218,16 @@ public async Task ValidateInstance_returns_403_when_not_authorized() PlatformHttpException exception = await PlatformHttpException.CreateAsync(updateProcessResult); _instanceMock - .Setup(i => i.GetInstance(App, Org, InstanceOwnerPartyId, _instanceId)) + .Setup(i => + i.GetInstance( + App, + Org, + InstanceOwnerPartyId, + _instanceId, + It.IsAny(), + It.IsAny() + ) + ) .Returns(Task.FromResult(instance)); _validationMock @@ -215,7 +260,16 @@ public async Task ValidateInstance_throws_PlatformHttpException_when_not_403() PlatformHttpException exception = await PlatformHttpException.CreateAsync(updateProcessResult); _instanceMock - .Setup(i => i.GetInstance(App, Org, InstanceOwnerPartyId, _instanceId)) + .Setup(i => + i.GetInstance( + App, + Org, + InstanceOwnerPartyId, + _instanceId, + It.IsAny(), + It.IsAny() + ) + ) .Returns(Task.FromResult(instance)); _validationMock diff --git a/test/Altinn.App.Api.Tests/Controllers/ValidateControllerValidateDataTests.cs b/test/Altinn.App.Api.Tests/Controllers/ValidateControllerValidateDataTests.cs index 2189c7255..f594f333a 100644 --- a/test/Altinn.App.Api.Tests/Controllers/ValidateControllerValidateDataTests.cs +++ b/test/Altinn.App.Api.Tests/Controllers/ValidateControllerValidateDataTests.cs @@ -240,7 +240,16 @@ public async Task TestValidateData(ValidateDataTestScenario testScenario) private void SetupMocks(string app, string org, int instanceOwnerId, ValidateDataTestScenario testScenario) { _instanceMock - .Setup(i => i.GetInstance(app, org, instanceOwnerId, testScenario.InstanceId)) + .Setup(i => + i.GetInstance( + app, + org, + instanceOwnerId, + testScenario.InstanceId, + It.IsAny(), + It.IsAny() + ) + ) .Returns(Task.FromResult(testScenario.ReceivedInstance)!); if (testScenario.ReceivedApplication != null) { diff --git a/test/Altinn.App.Api.Tests/Mocks/InstanceClientMockSi.cs b/test/Altinn.App.Api.Tests/Mocks/InstanceClientMockSi.cs index 7d188dc32..dd673ad5b 100644 --- a/test/Altinn.App.Api.Tests/Mocks/InstanceClientMockSi.cs +++ b/test/Altinn.App.Api.Tests/Mocks/InstanceClientMockSi.cs @@ -1,6 +1,7 @@ using System.Text.Json; using Altinn.App.Api.Tests.Data; using Altinn.App.Core.Extensions; +using Altinn.App.Core.Features; using Altinn.App.Core.Helpers; using Altinn.App.Core.Internal.Instances; using Altinn.Platform.Storage.Interface.Models; @@ -33,7 +34,13 @@ public InstanceClientMockSi(ILogger logger, IHttpContextAccesso _httpContextAccessor = httpContextAccessor; } - public async Task CreateInstance(string org, string app, Instance instance) + public async Task CreateInstance( + string org, + string app, + Instance instance, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ) { string partyId = instance.InstanceOwner.PartyId; Guid instanceGuid = Guid.NewGuid(); @@ -60,7 +67,11 @@ public async Task CreateInstance(string org, string app, Instance inst } /// - public async Task GetInstance(Instance instance) + public async Task GetInstance( + Instance instance, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ) { string app = instance.AppId.Split("/")[1]; string org = instance.Org; @@ -70,7 +81,14 @@ public async Task GetInstance(Instance instance) return await GetInstance(app, org, instanceOwnerId, instanceGuid); } - public async Task GetInstance(string app, string org, int instanceOwnerPartyId, Guid instanceId) + public async Task GetInstance( + string app, + string org, + int instanceOwnerPartyId, + Guid instanceId, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ) { Instance instance = await GetTestInstance(app, org, instanceOwnerPartyId, instanceId); @@ -85,7 +103,11 @@ public async Task GetInstance(string app, string org, int instanceOwne return instance; } - public async Task UpdateProcess(Instance instance) + public async Task UpdateProcess( + Instance instance, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ) { ProcessState process = instance.Process; @@ -117,9 +139,14 @@ public async Task UpdateProcess(Instance instance) return storedInstance; } - public Task UpdateProcessAndEvents(Instance instance, List events) + public Task UpdateProcessAndEvents( + Instance instance, + List events, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ) { - return UpdateProcess(instance); + return UpdateProcess(instance, cancellationToken: cancellationToken); } private static async Task GetTestInstance(string app, string org, int instanceOwnerId, Guid instanceId) @@ -201,7 +228,12 @@ public Task> GetActiveInstances(int instanceOwnerPartyId) throw new NotImplementedException(); } - public async Task AddCompleteConfirmation(int instanceOwnerPartyId, Guid instanceGuid) + public async Task AddCompleteConfirmation( + int instanceOwnerPartyId, + Guid instanceGuid, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ) { string org; string app; @@ -228,7 +260,13 @@ public async Task AddCompleteConfirmation(int instanceOwnerPartyId, Gu return instance; } - public async Task UpdateReadStatus(int instanceOwnerPartyId, Guid instanceGuid, string readStatus) + public async Task UpdateReadStatus( + int instanceOwnerPartyId, + Guid instanceGuid, + string readStatus, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ) { if (!Enum.TryParse(readStatus, true, out ReadStatus newStatus)) { @@ -254,7 +292,13 @@ public async Task UpdateReadStatus(int instanceOwnerPartyId, Guid inst return storedInstance; } - public async Task UpdateSubstatus(int instanceOwnerPartyId, Guid instanceGuid, Substatus substatus) + public async Task UpdateSubstatus( + int instanceOwnerPartyId, + Guid instanceGuid, + Substatus substatus, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ) { DateTime creationTime = DateTime.UtcNow; @@ -288,7 +332,9 @@ public async Task UpdateSubstatus(int instanceOwnerPartyId, Guid insta public async Task UpdatePresentationTexts( int instanceOwnerPartyId, Guid instanceGuid, - PresentationTexts presentationTexts + PresentationTexts presentationTexts, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default ) { string instancePath = GetInstancePath(instanceOwnerPartyId, instanceGuid); @@ -326,7 +372,13 @@ PresentationTexts presentationTexts return storedInstance; } - public async Task UpdateDataValues(int instanceOwnerPartyId, Guid instanceGuid, DataValues dataValues) + public async Task UpdateDataValues( + int instanceOwnerPartyId, + Guid instanceGuid, + DataValues dataValues, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ) { string instancePath = GetInstancePath(instanceOwnerPartyId, instanceGuid); if (!File.Exists(instancePath)) @@ -363,7 +415,13 @@ public async Task UpdateDataValues(int instanceOwnerPartyId, Guid inst return storedInstance; } - public async Task DeleteInstance(int instanceOwnerPartyId, Guid instanceGuid, bool hard) + public async Task DeleteInstance( + int instanceOwnerPartyId, + Guid instanceGuid, + bool hard, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ) { string instancePath = GetInstancePath(instanceOwnerPartyId, instanceGuid); if (!File.Exists(instancePath)) @@ -395,7 +453,11 @@ public async Task DeleteInstance(int instanceOwnerPartyId, Guid instan /// /// Searches through all instance documents (including pretest) /// - public async Task> GetInstances(Dictionary queryParams) + public async Task> GetInstances( + Dictionary queryParams, + StorageAuthenticationMethod? authenticationMethod = null, + CancellationToken cancellationToken = default + ) { List validQueryParams = new() { diff --git a/test/Altinn.App.Core.Tests/Features/Action/SigningUserActionTests.cs b/test/Altinn.App.Core.Tests/Features/Action/SigningUserActionTests.cs index 456e739ec..6033d3dc4 100644 --- a/test/Altinn.App.Core.Tests/Features/Action/SigningUserActionTests.cs +++ b/test/Altinn.App.Core.Tests/Features/Action/SigningUserActionTests.cs @@ -109,7 +109,9 @@ public static Fixture Create( var instanceClientMock = new Mock(); instanceClientMock - .Setup(x => x.GetInstance(_instance)) + .Setup(x => + x.GetInstance(_instance, It.IsAny(), It.IsAny()) + ) .ReturnsAsync(() => { if (signatureWasAdded) diff --git a/test/Altinn.App.Core.Tests/Features/Action/UniqueSignatureAuthorizerTests.cs b/test/Altinn.App.Core.Tests/Features/Action/UniqueSignatureAuthorizerTests.cs index 77e7e2e1b..0dd645520 100644 --- a/test/Altinn.App.Core.Tests/Features/Action/UniqueSignatureAuthorizerTests.cs +++ b/test/Altinn.App.Core.Tests/Features/Action/UniqueSignatureAuthorizerTests.cs @@ -174,7 +174,14 @@ public async Task AuthorizeAction_returns_true_if_other_user_has_signed_previous ); _processReaderMock.Verify(p => p.GetFlowElement("Task_2")); _instanceClientMock.Verify(i => - i.GetInstance("xunit-app", "ttd", 500001, Guid.Parse("abba2e90-f86f-4881-b0e8-38334408bcb4")) + i.GetInstance( + "xunit-app", + "ttd", + 500001, + Guid.Parse("abba2e90-f86f-4881-b0e8-38334408bcb4"), + It.IsAny(), + It.IsAny() + ) ); _appMetadataMock.Verify(a => a.GetApplicationMetadata()); _dataClientMock.Verify(d => @@ -231,7 +238,14 @@ public async Task AuthorizeAction_returns_false_if_same_user_has_signed_previous ); _processReaderMock.Verify(p => p.GetFlowElement("Task_2")); _instanceClientMock.Verify(i => - i.GetInstance("xunit-app", "ttd", 500001, Guid.Parse("abba2e90-f86f-4881-b0e8-38334408bcb4")) + i.GetInstance( + "xunit-app", + "ttd", + 500001, + Guid.Parse("abba2e90-f86f-4881-b0e8-38334408bcb4"), + It.IsAny(), + It.IsAny() + ) ); _appMetadataMock.Verify(a => a.GetApplicationMetadata()); _dataClientMock.Verify(d => @@ -332,7 +346,14 @@ public async Task AuthorizeAction_returns_true_if_dataelement_not_of_type_SignDo ); _processReaderMock.Verify(p => p.GetFlowElement("Task_2")); _instanceClientMock.Verify(i => - i.GetInstance("xunit-app", "ttd", 500001, Guid.Parse("abba2e90-f86f-4881-b0e8-38334408bcb4")) + i.GetInstance( + "xunit-app", + "ttd", + 500001, + Guid.Parse("abba2e90-f86f-4881-b0e8-38334408bcb4"), + It.IsAny(), + It.IsAny() + ) ); _appMetadataMock.Verify(a => a.GetApplicationMetadata()); _dataClientMock.Verify(d => @@ -392,7 +413,14 @@ public async Task AuthorizeAction_returns_true_if_signdumcument_is_missing_signe ); _processReaderMock.Verify(p => p.GetFlowElement("Task_2")); _instanceClientMock.Verify(i => - i.GetInstance("xunit-app", "ttd", 500001, Guid.Parse("abba2e90-f86f-4881-b0e8-38334408bcb4")) + i.GetInstance( + "xunit-app", + "ttd", + 500001, + Guid.Parse("abba2e90-f86f-4881-b0e8-38334408bcb4"), + It.IsAny(), + It.IsAny() + ) ); _appMetadataMock.Verify(a => a.GetApplicationMetadata()); _dataClientMock.Verify(d => @@ -452,7 +480,14 @@ public async Task AuthorizeAction_returns_true_if_signdumcument_is_missing_signe ); _processReaderMock.Verify(p => p.GetFlowElement("Task_2")); _instanceClientMock.Verify(i => - i.GetInstance("xunit-app", "ttd", 500001, Guid.Parse("abba2e90-f86f-4881-b0e8-38334408bcb4")) + i.GetInstance( + "xunit-app", + "ttd", + 500001, + Guid.Parse("abba2e90-f86f-4881-b0e8-38334408bcb4"), + It.IsAny(), + It.IsAny() + ) ); _appMetadataMock.Verify(a => a.GetApplicationMetadata()); _dataClientMock.Verify(d => @@ -512,7 +547,14 @@ public async Task AuthorizeAction_returns_true_if_signdumcument_signee_userid_is ); _processReaderMock.Verify(p => p.GetFlowElement("Task_2")); _instanceClientMock.Verify(i => - i.GetInstance("xunit-app", "ttd", 500001, Guid.Parse("abba2e90-f86f-4881-b0e8-38334408bcb4")) + i.GetInstance( + "xunit-app", + "ttd", + 500001, + Guid.Parse("abba2e90-f86f-4881-b0e8-38334408bcb4"), + It.IsAny(), + It.IsAny() + ) ); _appMetadataMock.Verify(a => a.GetApplicationMetadata()); _dataClientMock.Verify(d => @@ -539,7 +581,16 @@ private UniqueSignatureAuthorizer CreateUniqueSignatureAuthorizer( _applicationMetadata = new ApplicationMetadata("ttd/xunit-app"); _appMetadataMock.Setup(a => a.GetApplicationMetadata()).ReturnsAsync(_applicationMetadata); _instanceClientMock - .Setup(i => i.GetInstance(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .Setup(i => + i.GetInstance( + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny() + ) + ) .ReturnsAsync( new Instance() { diff --git a/test/Altinn.App.Core.Tests/Internal/Process/ProcessEventHandlingTests.cs b/test/Altinn.App.Core.Tests/Internal/Process/ProcessEventHandlingTests.cs index 6b6743637..0909398e8 100644 --- a/test/Altinn.App.Core.Tests/Internal/Process/ProcessEventHandlingTests.cs +++ b/test/Altinn.App.Core.Tests/Internal/Process/ProcessEventHandlingTests.cs @@ -113,7 +113,17 @@ public async Task UpdateProcessAndDispatchEvents_StartEvent_instance_updated_and }, }, }; - fixture.Mock().Setup(i => i.UpdateProcessAndEvents(instance, events)).ReturnsAsync(instance); + fixture + .Mock() + .Setup(i => + i.UpdateProcessAndEvents( + instance, + events, + It.IsAny(), + It.IsAny() + ) + ) + .ReturnsAsync(instance); Dictionary prefill = new Dictionary(); // Act @@ -122,7 +132,18 @@ public async Task UpdateProcessAndDispatchEvents_StartEvent_instance_updated_and // Assert result.Should().Be(instance); - fixture.Mock().Verify(i => i.UpdateProcessAndEvents(instance, events), Times.Once); + fixture + .Mock() + .Verify( + i => + i.UpdateProcessAndEvents( + instance, + events, + It.IsAny(), + It.IsAny() + ), + Times.Once + ); fixture.Mock().VerifyNoOtherCalls(); fixture.Mock().VerifyNoOtherCalls(); fixture.Mock().VerifyNoOtherCalls(); @@ -157,7 +178,17 @@ public async Task UpdateProcessAndDispatchEvents_StartTask_instance_updated_and_ }, }, }; - fixture.Mock().Setup(i => i.UpdateProcessAndEvents(instance, events)).ReturnsAsync(instance); + fixture + .Mock() + .Setup(i => + i.UpdateProcessAndEvents( + instance, + events, + It.IsAny(), + It.IsAny() + ) + ) + .ReturnsAsync(instance); Dictionary prefill = new Dictionary(); // Act @@ -166,7 +197,18 @@ public async Task UpdateProcessAndDispatchEvents_StartTask_instance_updated_and_ // Assert result.Should().Be(instance); - fixture.Mock().Verify(i => i.UpdateProcessAndEvents(instance, events), Times.Once); + fixture + .Mock() + .Verify( + i => + i.UpdateProcessAndEvents( + instance, + events, + It.IsAny(), + It.IsAny() + ), + Times.Once + ); fixture.Mock().VerifyNoOtherCalls(); fixture.Mock().VerifyNoOtherCalls(); fixture.Mock().VerifyNoOtherCalls(); @@ -207,7 +249,17 @@ public async Task UpdateProcessAndDispatchEvents_StartTask_data_instance_updated }, }, }; - fixture.Mock().Setup(i => i.UpdateProcessAndEvents(instance, events)).ReturnsAsync(instance); + fixture + .Mock() + .Setup(i => + i.UpdateProcessAndEvents( + instance, + events, + It.IsAny(), + It.IsAny() + ) + ) + .ReturnsAsync(instance); Dictionary prefill = new Dictionary(); // Act @@ -216,7 +268,18 @@ public async Task UpdateProcessAndDispatchEvents_StartTask_data_instance_updated // Assert result.Should().Be(instance); - fixture.Mock().Verify(i => i.UpdateProcessAndEvents(instance, events), Times.Once); + fixture + .Mock() + .Verify( + i => + i.UpdateProcessAndEvents( + instance, + events, + It.IsAny(), + It.IsAny() + ), + Times.Once + ); fixture.Mock().VerifyNoOtherCalls(); fixture.Mock().VerifyNoOtherCalls(); fixture.Mock().VerifyNoOtherCalls(); @@ -257,7 +320,17 @@ public async Task UpdateProcessAndDispatchEvents_EndTask_confirmation_instance_u }, }, }; - fixture.Mock().Setup(i => i.UpdateProcessAndEvents(instance, events)).ReturnsAsync(instance); + fixture + .Mock() + .Setup(i => + i.UpdateProcessAndEvents( + instance, + events, + It.IsAny(), + It.IsAny() + ) + ) + .ReturnsAsync(instance); Dictionary prefill = new Dictionary(); // Act @@ -266,7 +339,18 @@ public async Task UpdateProcessAndDispatchEvents_EndTask_confirmation_instance_u // Assert result.Should().Be(instance); - fixture.Mock().Verify(i => i.UpdateProcessAndEvents(instance, events), Times.Once); + fixture + .Mock() + .Verify( + i => + i.UpdateProcessAndEvents( + instance, + events, + It.IsAny(), + It.IsAny() + ), + Times.Once + ); fixture.Mock().VerifyNoOtherCalls(); fixture.Mock().VerifyNoOtherCalls(); fixture.Mock().VerifyNoOtherCalls(); @@ -307,7 +391,17 @@ public async Task UpdateProcessAndDispatchEvents_AbandonTask_feedback_instance_u }, }, }; - fixture.Mock().Setup(i => i.UpdateProcessAndEvents(instance, events)).ReturnsAsync(instance); + fixture + .Mock() + .Setup(i => + i.UpdateProcessAndEvents( + instance, + events, + It.IsAny(), + It.IsAny() + ) + ) + .ReturnsAsync(instance); Dictionary prefill = new Dictionary(); // Act @@ -316,7 +410,18 @@ public async Task UpdateProcessAndDispatchEvents_AbandonTask_feedback_instance_u // Assert result.Should().Be(instance); - fixture.Mock().Verify(i => i.UpdateProcessAndEvents(instance, events), Times.Once); + fixture + .Mock() + .Verify( + i => + i.UpdateProcessAndEvents( + instance, + events, + It.IsAny(), + It.IsAny() + ), + Times.Once + ); fixture.Mock().VerifyNoOtherCalls(); fixture.Mock().VerifyNoOtherCalls(); fixture.Mock().VerifyNoOtherCalls(); @@ -377,7 +482,17 @@ public async Task UpdateProcessAndDispatchEvents_EndEvent_confirmation_instance_ fixture.Mock().Setup(x => x.GetApplicationMetadata()).ReturnsAsync(applicationMetadata); - fixture.Mock().Setup(i => i.UpdateProcessAndEvents(instance, events)).ReturnsAsync(instance); + fixture + .Mock() + .Setup(i => + i.UpdateProcessAndEvents( + instance, + events, + It.IsAny(), + It.IsAny() + ) + ) + .ReturnsAsync(instance); Dictionary prefill = new Dictionary(); // Act @@ -387,7 +502,18 @@ public async Task UpdateProcessAndDispatchEvents_EndEvent_confirmation_instance_ // Assert result.Should().Be(instance); fixture.Mock().Verify(a => a.OnEndAppEvent("EndEvent", instance), Times.Once); - fixture.Mock().Verify(i => i.UpdateProcessAndEvents(instance, events), Times.Once); + fixture + .Mock() + .Verify( + i => + i.UpdateProcessAndEvents( + instance, + events, + It.IsAny(), + It.IsAny() + ), + Times.Once + ); fixture.Mock().VerifyNoOtherCalls(); fixture.Mock().VerifyNoOtherCalls(); fixture.Mock().VerifyNoOtherCalls(); @@ -413,7 +539,17 @@ public async Task UpdateProcessAndDispatchEvents_EndEvent_confirmation_instance_ }; List? events = null; - fixture.Mock().Setup(i => i.UpdateProcessAndEvents(instance, new())).ReturnsAsync(instance); + fixture + .Mock() + .Setup(i => + i.UpdateProcessAndEvents( + instance, + new(), + It.IsAny(), + It.IsAny() + ) + ) + .ReturnsAsync(instance); Dictionary prefill = new Dictionary(); // Act @@ -422,7 +558,18 @@ public async Task UpdateProcessAndDispatchEvents_EndEvent_confirmation_instance_ // Assert result.Should().Be(instance); - fixture.Mock().Verify(i => i.UpdateProcessAndEvents(instance, new()), Times.Once); + fixture + .Mock() + .Verify( + i => + i.UpdateProcessAndEvents( + instance, + new(), + It.IsAny(), + It.IsAny() + ), + Times.Once + ); fixture.Mock().VerifyNoOtherCalls(); fixture.Mock().VerifyNoOtherCalls(); fixture.Mock().VerifyNoOtherCalls(); diff --git a/test/Altinn.App.Core.Tests/Internal/Process/ServiceTasks/EformidlingServiceTaskTests.cs b/test/Altinn.App.Core.Tests/Internal/Process/ServiceTasks/EformidlingServiceTaskTests.cs index fec05427e..366c3c767 100644 --- a/test/Altinn.App.Core.Tests/Internal/Process/ServiceTasks/EformidlingServiceTaskTests.cs +++ b/test/Altinn.App.Core.Tests/Internal/Process/ServiceTasks/EformidlingServiceTaskTests.cs @@ -1,5 +1,6 @@ using Altinn.App.Core.Configuration; using Altinn.App.Core.EFormidling.Interface; +using Altinn.App.Core.Features; using Altinn.App.Core.Internal.App; using Altinn.App.Core.Internal.Instances; using Altinn.App.Core.Internal.Process.ServiceTasks; @@ -38,7 +39,9 @@ public async Task Execute_EFormidlingIsEnabledAndSendAfterTaskIdMatchesCurrentTa }; var instance = new Instance(); _appMetadata.Setup(x => x.GetApplicationMetadata()).ReturnsAsync(applicationMetadata); - _instanceClient.Setup(x => x.GetInstance(instance)).ReturnsAsync(instance); + _instanceClient + .Setup(x => x.GetInstance(instance, It.IsAny(), It.IsAny())) + .ReturnsAsync(instance); _eFormidlingService.Setup(x => x.SendEFormidlingShipment(instance)).Returns(Task.CompletedTask); var eformidlingServiceTask = GetEformidlingServiceTask(appSettings, _eFormidlingService.Object); @@ -47,7 +50,10 @@ public async Task Execute_EFormidlingIsEnabledAndSendAfterTaskIdMatchesCurrentTa // Assert _appMetadata.Verify(x => x.GetApplicationMetadata(), Times.Once); - _instanceClient.Verify(x => x.GetInstance(instance), Times.Once); + _instanceClient.Verify( + x => x.GetInstance(instance, It.IsAny(), It.IsAny()), + Times.Once + ); _eFormidlingService.Verify(x => x.SendEFormidlingShipment(instance), Times.Once); _appMetadata.VerifyNoOtherCalls(); _instanceClient.VerifyNoOtherCalls();