diff --git a/src/Altinn.App.Core/Internal/Data/CachedInstanceDataAccessor.cs b/src/Altinn.App.Core/Internal/Data/CachedInstanceDataAccessor.cs index 4e598c22e..33eb8ca20 100644 --- a/src/Altinn.App.Core/Internal/Data/CachedInstanceDataAccessor.cs +++ b/src/Altinn.App.Core/Internal/Data/CachedInstanceDataAccessor.cs @@ -18,8 +18,6 @@ namespace Altinn.App.Core.Internal.Data; internal sealed class CachedInstanceDataAccessor : IInstanceDataMutator { // DataClient needs a few arguments to fetch data - private readonly string _org; - private readonly string _app; private readonly Guid _instanceGuid; private readonly int _instanceOwnerPartyId; @@ -60,12 +58,13 @@ public CachedInstanceDataAccessor( ModelSerializationService modelSerializationService ) { - var splitApp = instance.AppId.Split("/"); - _org = splitApp[0]; - _app = splitApp[1]; - var splitId = instance.Id.Split("/"); - _instanceOwnerPartyId = int.Parse(splitId[0], CultureInfo.InvariantCulture); - _instanceGuid = Guid.Parse(splitId[1]); + if (instance.Id is not null) + { + var splitId = instance.Id.Split("/"); + _instanceOwnerPartyId = int.Parse(splitId[0], CultureInfo.InvariantCulture); + _instanceGuid = Guid.Parse(splitId[1]); + } + Instance = instance; _dataClient = dataClient; _appMetadata = appMetadata; @@ -93,18 +92,27 @@ public async Task GetFormData(DataElementIdentifier dataElementIdentifie } /// - public async Task> GetBinaryData(DataElementIdentifier dataElementIdentifier) => - await _binaryCache.GetOrCreate( + public async Task> GetBinaryData(DataElementIdentifier dataElementIdentifier) + { + if (_instanceOwnerPartyId == 0 || _instanceGuid == Guid.Empty) + { + throw new InvalidOperationException("Cannot access instance data before it has been created"); + } + + var appMetadata = await _appMetadata.GetApplicationMetadata(); + + return await _binaryCache.GetOrCreate( dataElementIdentifier, async () => await _dataClient.GetDataBytes( - _org, - _app, + appMetadata.AppIdentifier.Org, + appMetadata.AppIdentifier.App, _instanceOwnerPartyId, _instanceGuid, dataElementIdentifier.Guid ) ); + } /// public DataElement GetDataElement(DataElementIdentifier dataElementIdentifier) @@ -230,6 +238,11 @@ public List GetDataElementChanges(bool initializeAltinnRowId) internal async Task UpdateInstanceData(List changes) { + if (_instanceOwnerPartyId == 0 || _instanceGuid == Guid.Empty) + { + throw new InvalidOperationException("Cannot access instance data before it has been created"); + } + var tasks = new List(); ConcurrentBag createdDataElements = new(); // We need to create data elements here, so that we can set them correctly on the instance @@ -258,14 +271,16 @@ async Task InsertBinaryData() tasks.Add(InsertBinaryData()); } + var appMetadata = await _appMetadata.GetApplicationMetadata(); + // Delete data elements foreach (var dataElementId in _dataElementsToDelete) { async Task DeleteData() { await _dataClient.DeleteData( - _org, - _app, + appMetadata.AppIdentifier.Org, + appMetadata.AppIdentifier.App, _instanceOwnerPartyId, _instanceGuid, dataElementId.Guid, diff --git a/test/Altinn.App.Core.Tests/Internal/Process/ProcessEngineTest.cs b/test/Altinn.App.Core.Tests/Internal/Process/ProcessEngineTest.cs index c41ef277c..26663f420 100644 --- a/test/Altinn.App.Core.Tests/Internal/Process/ProcessEngineTest.cs +++ b/test/Altinn.App.Core.Tests/Internal/Process/ProcessEngineTest.cs @@ -13,6 +13,7 @@ using Altinn.App.Core.Internal.Process.Elements; using Altinn.App.Core.Internal.Process.ProcessTasks; using Altinn.App.Core.Internal.Profile; +using Altinn.App.Core.Models; using Altinn.App.Core.Models.Process; using Altinn.App.Core.Models.UserAction; using Altinn.Platform.Profile.Models; @@ -457,6 +458,7 @@ public async Task Next_returns_unsuccessful_unauthorized_when_action_handler_ret [Fact] public async Task Next_moves_instance_to_next_task_and_produces_instanceevents() { + _appMetadataMock.Setup(x => x.GetApplicationMetadata()).ReturnsAsync(new ApplicationMetadata("org/app")); var expectedInstance = new Instance() { Id = _instanceId, @@ -604,6 +606,7 @@ public async Task Next_moves_instance_to_next_task_and_produces_instanceevents() [Fact] public async Task Next_moves_instance_to_next_task_and_produces_abandon_instanceevent_when_action_reject() { + _appMetadataMock.Setup(x => x.GetApplicationMetadata()).ReturnsAsync(new ApplicationMetadata("org/app")); var expectedInstance = new Instance() { Id = _instanceId, @@ -752,6 +755,7 @@ public async Task Next_moves_instance_to_next_task_and_produces_abandon_instance [Fact] public async Task Next_moves_instance_to_end_event_and_ends_proces() { + _appMetadataMock.Setup(x => x.GetApplicationMetadata()).ReturnsAsync(new ApplicationMetadata("org/app")); var expectedInstance = new Instance() { Id = _instanceId, diff --git a/test/Altinn.App.Core.Tests/Internal/Process/ProcessTasks/Common/ProcessTaskFinalizerTests.cs b/test/Altinn.App.Core.Tests/Internal/Process/ProcessTasks/Common/ProcessTaskFinalizerTests.cs index 2348aff1f..337e85df8 100644 --- a/test/Altinn.App.Core.Tests/Internal/Process/ProcessTasks/Common/ProcessTaskFinalizerTests.cs +++ b/test/Altinn.App.Core.Tests/Internal/Process/ProcessTasks/Common/ProcessTaskFinalizerTests.cs @@ -70,6 +70,7 @@ public async Task Finalize_WithValidInputs_ShouldCallCorrectMethods() await _processTaskFinalizer.Finalize(instance.Process.CurrentTask.ElementId, instance); // Assert - _appMetadataMock.Verify(x => x.GetApplicationMetadata(), Times.Once); + // Called once in Finalize and once in CachedInstanceDataAccessor.UpdateInstanceData + _appMetadataMock.Verify(x => x.GetApplicationMetadata(), Times.Exactly(2)); } }