Skip to content

Commit

Permalink
Finish writing tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ivarne committed Nov 27, 2023
1 parent 5f43aac commit edd91bd
Show file tree
Hide file tree
Showing 2 changed files with 170 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ private async Task<ModelDeserializerResult> DeserializeMultipartAsync(Stream str
string boundary = mediaType.Boundary.Value!.Trim('"');
var reader = new MultipartReader(boundary, stream);
MultipartSection? firstSection = await reader.ReadNextSectionAsync();
if (firstSection?.ContentDisposition?.Contains("name=\"dataModel\"") != true)
if (firstSection?.ContentDisposition?.Contains("name=dataModel") != true)
{
return ModelDeserializerResult.FromError("First entry in multipart serialization must have name=\"dataModel\"");
}
Expand All @@ -81,7 +81,7 @@ private async Task<ModelDeserializerResult> DeserializeMultipartAsync(Stream str
Dictionary<string, string?>? reportedChanges = null;
if (secondSection is not null)
{
if (secondSection?.ContentDisposition?.Contains("name=\"previousValues\"") != true)
if (secondSection?.ContentDisposition?.Contains("name=previousValues") != true)
{
return ModelDeserializerResult.FromError("Second entry in multipart serialization must have name=\"previousValues\"");
}
Expand Down
177 changes: 168 additions & 9 deletions test/Altinn.App.Api.Tests/Controllers/DataController_PutTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
using Microsoft.AspNetCore.Mvc.Testing;
using System.Net.Http.Headers;
using System.Net;
using System.Text.Json;
using Altinn.App.Api.Tests.Data.apps.tdd.contributer_restriction.models;
using Altinn.App.Core.Features;
using Xunit;
using Altinn.App.Core.Helpers;
using Altinn.Platform.Storage.Interface.Models;
using FluentAssertions;
using Microsoft.Extensions.DependencyInjection;
Expand All @@ -20,7 +20,7 @@ public DataController_PutTests(WebApplicationFactory<Program> factory) : base(fa
{
OverrideServicesForAllTests = (services) =>
{
services.AddSingleton<IDataProcessor>(_dataProcessor.Object);
services.AddSingleton(_dataProcessor.Object);
};
}

Expand All @@ -40,7 +40,10 @@ public async Task PutDataElement_TestSinglePartUpdate_ReturnsOk()
await client.PostAsync($"{org}/{app}/instances/?instanceOwnerPartyId={instanceOwnerPartyId}", null);
var createResponseContent = await createResponse.Content.ReadAsStringAsync();
createResponse.StatusCode.Should().Be(HttpStatusCode.Created);
var createResponseParsed = JsonSerializerPermissive.Deserialize<Instance>(createResponseContent);
var createResponseParsed = JsonSerializer.Deserialize<Instance>(createResponseContent, new JsonSerializerOptions()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
})!;
var instanceId = createResponseParsed.Id;

// Create data element (not sure why it isn't created when the instance is created, autoCreate is true)
Expand All @@ -51,24 +54,180 @@ public async Task PutDataElement_TestSinglePartUpdate_ReturnsOk()
var createDataElementResponseContent = await createDataElementResponse.Content.ReadAsStringAsync();
createDataElementResponse.StatusCode.Should().Be(HttpStatusCode.Created);
var createDataElementResponseParsed =
JsonSerializerPermissive.Deserialize<DataElement>(createDataElementResponseContent);
JsonSerializer.Deserialize<DataElement>(createDataElementResponseContent, new JsonSerializerOptions()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
})!;
var dataGuid = createDataElementResponseParsed.Id;

// Update data element
using var updateDataElementContent =
new StringContent("""{"melding":{"name": "Ivar Nesje"}}""", System.Text.Encoding.UTF8, "application/json");
var response = await client.PutAsync($"/{org}/{app}/instances/{instanceId}/data/{dataGuid}", updateDataElementContent);

response.StatusCode.Should().Be(HttpStatusCode.Created);

// 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 =
JsonSerializerPermissive.Deserialize<Skjema>(readDataElementResponseContent);
JsonSerializer.Deserialize<Skjema>(readDataElementResponseContent)!;
readDataElementResponseParsed.Melding.Name.Should().Be("Ivar Nesje");


_dataProcessor.Verify(p => p.ProcessDataRead(It.IsAny<Instance>(), It.Is<Guid>(dataId => dataId == Guid.Parse(dataGuid)), It.IsAny<Skjema>()), Times.Exactly(1));
_dataProcessor.Verify(p => p.ProcessDataWrite(It.IsAny<Instance>(), It.Is<Guid>(dataId => dataId == Guid.Parse(dataGuid)), It.IsAny<Skjema>(), It.IsAny<Dictionary<string, string?>>()), Times.Exactly(1)); // TODO: Shouldn't this be 2 because of the first write?
_dataProcessor.VerifyNoOtherCalls();
}

[Fact]
public async Task PutDataElement_TestMultiPartUpdate_ReturnsOk()
{
// Setup test data
string org = "tdd";
string app = "contributer-restriction";
int instanceOwnerPartyId = 501337;
HttpClient client = GetRootedClient(org, app);
string token = PrincipalUtil.GetToken(1337, 4);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

// Create instance
var createResponse =
await client.PostAsync($"{org}/{app}/instances/?instanceOwnerPartyId={instanceOwnerPartyId}", null);
var createResponseContent = await createResponse.Content.ReadAsStringAsync();
createResponse.StatusCode.Should().Be(HttpStatusCode.Created);
var createResponseParsed = JsonSerializer.Deserialize<Instance>(createResponseContent,
new JsonSerializerOptions()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
})!;
var instanceId = createResponseParsed.Id;

// Create data element (not sure why it isn't created when the instance is created, autoCreate is true)
using var createDataElementContent =
new StringContent("""{"melding":{"name": "Ivar"}}""", System.Text.Encoding.UTF8, "application/json");
var createDataElementResponse =
await client.PostAsync($"/{org}/{app}/instances/{instanceId}/data?dataType=default",
createDataElementContent);
var createDataElementResponseContent = await createDataElementResponse.Content.ReadAsStringAsync();
createDataElementResponse.StatusCode.Should().Be(HttpStatusCode.Created);
var createDataElementResponseParsed =
JsonSerializer.Deserialize<DataElement>(createDataElementResponseContent, new JsonSerializerOptions()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
})!;
var dataGuid = createDataElementResponseParsed.Id;

// Update data element
using var updateDataElementContent = new MultipartFormDataContent();
updateDataElementContent.Add(new StringContent("""{"melding":{"name": "Ivar Nesje"}}""", System.Text.Encoding.UTF8,
"application/json"), "dataModel");
updateDataElementContent.Add(new StringContent("""{"melding.name":"Ivar"}""", System.Text.Encoding.UTF8,
"application/json"), "previousValues");

var response = await client.PutAsync($"/{org}/{app}/instances/{instanceId}/data/{dataGuid}", updateDataElementContent);
var responseContent = await response.Content.ReadAsStringAsync();

Check warning

Code scanning / CodeQL

Useless assignment to local variable Warning test

This assignment to
responseContent
is useless, since its value is never read.
response.StatusCode.Should().Be(HttpStatusCode.OK);

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

// Verify that update response equals the following read response
// responseContent.Should().Be(readDataElementResponseContent);

_dataProcessor.Verify(p=>p.ProcessDataRead(It.IsAny<Instance>(), It.Is<Guid>(dataId => dataId == Guid.Parse(dataGuid)), It.IsAny<Skjema>()), Times.Exactly(1));
_dataProcessor.Verify(p=>p.ProcessDataWrite(It.IsAny<Instance>(), It.Is<Guid>(dataId => dataId == Guid.Parse(dataGuid)), It.IsAny<Skjema>()), Times.Exactly(1)); // TODO: Shouldn't this be 2 because of the first write?
_dataProcessor.Verify(p => p.ProcessDataWrite(It.IsAny<Instance>(), It.Is<Guid>(dataId => dataId == Guid.Parse(dataGuid)), It.IsAny<Skjema>(), It.Is<Dictionary<string, string?>>(d => d.ContainsKey("melding.name"))), Times.Exactly(1)); // TODO: Shouldn't this be 2 because of the first write?
_dataProcessor.VerifyNoOtherCalls();
response.StatusCode.Should().Be(HttpStatusCode.Created);
}

[Fact]
public async Task PutDataElement_TestMultiPartUpdateWithCustomDataProcessor_ReturnsOk()
{
// Run the previous test with a custom data processor
_dataProcessor.Setup(d => d.ProcessDataWrite(It.IsAny<Instance>(), It.IsAny<Guid>(), It.IsAny<object>(), It.IsAny<Dictionary<string, string?>>()))
.Returns((Instance instance, Guid dataGuid, object data, Dictionary<string, string?> previousValues) =>
{
if (data is Skjema skjema)
{
skjema.Melding.Toggle = true;
}
return Task.CompletedTask;
});

// Run previous test with different setup
// Setup test data
string org = "tdd";
string app = "contributer-restriction";
int instanceOwnerPartyId = 501337;
HttpClient client = GetRootedClient(org, app);
string token = PrincipalUtil.GetToken(1337, 4);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

// Create instance
var createResponse =
await client.PostAsync($"{org}/{app}/instances/?instanceOwnerPartyId={instanceOwnerPartyId}", null);
var createResponseContent = await createResponse.Content.ReadAsStringAsync();
createResponse.StatusCode.Should().Be(HttpStatusCode.Created);
var createResponseParsed = JsonSerializer.Deserialize<Instance>(createResponseContent,
new JsonSerializerOptions()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
})!;
var instanceId = createResponseParsed.Id;

// Create data element (not sure why it isn't created when the instance is created, autoCreate is true)
using var createDataElementContent =
new StringContent("""{"melding":{"name": "Ivar"}}""", System.Text.Encoding.UTF8, "application/json");
var createDataElementResponse =
await client.PostAsync($"/{org}/{app}/instances/{instanceId}/data?dataType=default",
createDataElementContent);
var createDataElementResponseContent = await createDataElementResponse.Content.ReadAsStringAsync();
createDataElementResponse.StatusCode.Should().Be(HttpStatusCode.Created);
var createDataElementResponseParsed =
JsonSerializer.Deserialize<DataElement>(createDataElementResponseContent, new JsonSerializerOptions()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
})!;
var dataGuid = createDataElementResponseParsed.Id;

// Verify stored data
var firstReadDataElementResponse = await client.GetAsync($"/{org}/{app}/instances/{instanceId}/data/{dataGuid}");
var firstReadDataElementResponseContent = await firstReadDataElementResponse.Content.ReadAsStringAsync();
var firstReadDataElementResponseParsed =
JsonSerializer.Deserialize<Skjema>(firstReadDataElementResponseContent)!;
firstReadDataElementResponseParsed.Melding.Name.Should().Be("Ivar");
firstReadDataElementResponseParsed.Melding.Toggle.Should().BeFalse();

// Update data element
using var updateDataElementContent = new MultipartFormDataContent();
updateDataElementContent.Add(new StringContent("""{"melding":{"name": "Ivar Nesje"}}""", System.Text.Encoding.UTF8,
"application/json"), "dataModel");
updateDataElementContent.Add(new StringContent("""{"melding.name":"Ivar"}""", System.Text.Encoding.UTF8,
"application/json"), "previousValues");

var response = await client.PutAsync($"/{org}/{app}/instances/{instanceId}/data/{dataGuid}", updateDataElementContent);
var responseContent = await response.Content.ReadAsStringAsync();

Check warning

Code scanning / CodeQL

Useless assignment to local variable Warning test

This assignment to
responseContent
is useless, since its value is never read.
response.StatusCode.Should().Be(HttpStatusCode.OK);

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

// Verify that update response equals the following read response
// responseContent.Should().Be(readDataElementResponseContent);

_dataProcessor.Verify(p=>p.ProcessDataRead(It.IsAny<Instance>(), It.Is<Guid>(dataId => dataId == Guid.Parse(dataGuid)), It.IsAny<Skjema>()), Times.Exactly(2));
_dataProcessor.Verify(p => p.ProcessDataWrite(It.IsAny<Instance>(), It.Is<Guid>(dataId => dataId == Guid.Parse(dataGuid)), It.IsAny<Skjema>(), It.Is<Dictionary<string, string?>>(d => d.ContainsKey("melding.name"))), Times.Exactly(1)); // TODO: Shouldn't this be 2 because of the first write?
_dataProcessor.VerifyNoOtherCalls();

}


}

0 comments on commit edd91bd

Please sign in to comment.