Skip to content

Commit

Permalink
Fix double save in multipart requests (#967)
Browse files Browse the repository at this point in the history
  • Loading branch information
ivarne authored Dec 11, 2024
1 parent 59ff475 commit 383c9e5
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 22 deletions.
34 changes: 17 additions & 17 deletions src/Altinn.App.Api/Controllers/InstancesController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1187,29 +1187,29 @@ string action
_logger.LogInformation("Storing part {partName}", part.Name);
dataMutator.AddBinaryDataElement(dataType.Id, part.ContentType, part.FileName, part.Bytes);
}
}

var taskId = instance.Process?.CurrentTask?.ElementId;
var taskId = instance.Process?.CurrentTask?.ElementId;

if (taskId is null)
throw new InvalidOperationException("There should be a task while initializing data");
if (taskId is null)
throw new InvalidOperationException("There should be a task while initializing data");

var changes = dataMutator.GetDataElementChanges(initializeAltinnRowId: true);
await _patchService.RunDataProcessors(dataMutator, changes, taskId, language);
var changes = dataMutator.GetDataElementChanges(initializeAltinnRowId: true);
await _patchService.RunDataProcessors(dataMutator, changes, taskId, language);

if (dataMutator.GetAbandonResponse() is { } abandonResponse)
{
_logger.LogWarning(
"Data processing failed for one or more data elements, the instance was created, but we try to delete the instance"
);
return abandonResponse;
}

// Update the changes list if it changed in data processors
changes = dataMutator.GetDataElementChanges(initializeAltinnRowId: true);
await dataMutator.UpdateInstanceData(changes);
await dataMutator.SaveChanges(changes);
if (dataMutator.GetAbandonResponse() is { } abandonResponse)
{
_logger.LogWarning(
"Data processing failed for one or more data elements, the instance was created, but we try to delete the instance"
);
return abandonResponse;
}

// Update the changes list if it changed in data processors
changes = dataMutator.GetDataElementChanges(initializeAltinnRowId: true);
await dataMutator.UpdateInstanceData(changes);
await dataMutator.SaveChanges(changes);

return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public async Task PutDataElement_TestSinglePartUpdate_ReturnsOk()
)
)
.Returns(Task.CompletedTask)
.Verifiable(Times.Exactly(1));
.Verifiable(Times.Exactly(2));

// Create instance
var createResponse = await client.PostAsync(
Expand Down Expand Up @@ -171,7 +171,7 @@ public async Task PutDataElement_TestMultiPartUpdateWithCustomDataProcessor_Retu
)
)
.Returns(Task.CompletedTask)
.Verifiable(Times.Exactly(1));
.Verifiable(Times.Exactly(2));

// Run previous test with different setup
// Setup test data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,19 @@ public async Task PostNewInstanceWithContent_EnsureDataIsPresent()
content.Add(
new StringContent(
$$$"""<Skjema><melding><name>{{{testName}}}</name></melding></Skjema>""",
System.Text.Encoding.UTF8,
Encoding.UTF8,
"application/xml"
),
"default"
);
content.Add(
new ByteArrayContent([1, 2, 4]) { Headers = { ContentType = new MediaTypeHeaderValue("application/pdf") } },
name: "9edd53de-f46f-40a1-bb4d-3efb93dc113d"
);
content.Add(
new ByteArrayContent([1, 2, 5]) { Headers = { ContentType = new MediaTypeHeaderValue("image/png") } },
name: "specificFileType"
);

// Create instance
var createResponse = await client.PostAsync(
Expand All @@ -73,15 +81,38 @@ public async Task PostNewInstanceWithContent_EnsureDataIsPresent()

// Verify Data id
var instanceId = createResponseParsed.Id;
createResponseParsed.Data.Should().HaveCount(1, "Create instance should create a data element");
var dataGuid = createResponseParsed.Data.First().Id;
createResponseParsed.Data.Should().HaveCount(3, "We posted 3 data elements");
var dataGuid = createResponseParsed
.Data.Should()
.ContainSingle(d => d.DataType == "default", "we posted 1 default type")
.Which?.Id;

// Verify stored data
var readDataElementResponse = await client.GetAsync($"/{org}/{app}/instances/{instanceId}/data/{dataGuid}");
readDataElementResponse.StatusCode.Should().Be(HttpStatusCode.OK);
var readDataElementResponseContent = await readDataElementResponse.Content.ReadAsStringAsync();
var readDataElementResponseParsed = JsonSerializer.Deserialize<Skjema>(readDataElementResponseContent)!;
readDataElementResponseParsed.Melding!.Name.Should().Be(testName);

// Verify specific file types
var specificFileType = createResponseParsed
.Data.Should()
.ContainSingle(d => d.DataType == "specificFileType")
.Which;
specificFileType.ContentType.Should().Be("image/png");
var pdfContent = await client.GetByteArrayAsync(
$"/{org}/{app}/instances/{instanceId}/data/{specificFileType.Id}"
);
pdfContent.Should().BeEquivalentTo(new byte[] { 1, 2, 5 });

var pdfElement = createResponseParsed
.Data.Should()
.ContainSingle(d => d.ContentType == "application/pdf")
.Which;
pdfElement.DataType.Should().Be("9edd53de-f46f-40a1-bb4d-3efb93dc113d");
var pngContent = await client.GetByteArrayAsync($"/{org}/{app}/instances/{instanceId}/data/{pdfElement.Id}");
pngContent.Should().BeEquivalentTo(new byte[] { 1, 2, 4 });

TestData.DeleteInstanceAndData(org, app, instanceId);
}

Expand Down

0 comments on commit 383c9e5

Please sign in to comment.