diff --git a/src/Altinn.App.Api/Controllers/ActionsController.cs b/src/Altinn.App.Api/Controllers/ActionsController.cs
index 2786ee59b..a31b92941 100644
--- a/src/Altinn.App.Api/Controllers/ActionsController.cs
+++ b/src/Altinn.App.Api/Controllers/ActionsController.cs
@@ -213,10 +213,9 @@ await Task.WhenAll(
);
await saveTask;
- var updatedDataModels = changes.FormDataChanges.ToDictionary(
- c => c.DataElementIdentifier.Id,
- c => c.CurrentFormData
- );
+ var updatedDataModels = changes
+ .FormDataChanges.Where(c => c.Type != ChangeType.Deleted)
+ .ToDictionary(c => c.DataElementIdentifier.Id, c => c.CurrentFormData);
return Ok(
new UserActionResponse()
diff --git a/src/Altinn.App.Core/Internal/Data/InstanceDataUnitOfWork.cs b/src/Altinn.App.Core/Internal/Data/InstanceDataUnitOfWork.cs
index 36744dacf..cab697cc2 100644
--- a/src/Altinn.App.Core/Internal/Data/InstanceDataUnitOfWork.cs
+++ b/src/Altinn.App.Core/Internal/Data/InstanceDataUnitOfWork.cs
@@ -147,7 +147,7 @@ public FormDataChange AddFormDataElement(string dataTypeId, object model)
if (modelType.FullName != classRef)
{
throw new InvalidOperationException(
- $"Data object registered for {dataTypeId} is not of type {classRef} as specified in application metadata"
+ $"Tried to save {modelType.FullName} as {dataTypeId}, but applicationmetadata.json specifies {classRef}"
);
}
diff --git a/src/Altinn.App.Core/Models/UserAction/UserActionContext.cs b/src/Altinn.App.Core/Models/UserAction/UserActionContext.cs
index d2caf7c64..441548ab7 100644
--- a/src/Altinn.App.Core/Models/UserAction/UserActionContext.cs
+++ b/src/Altinn.App.Core/Models/UserAction/UserActionContext.cs
@@ -66,7 +66,7 @@ public UserActionContext(
///
/// Access dataElements through this accessor to ensure that changes gets saved in storage and returned to frontend
///
- public IInstanceDataAccessor DataMutator { get; }
+ public IInstanceDataMutator DataMutator { get; }
///
/// The user performing the action
diff --git a/test/Altinn.App.Api.Tests/Controllers/ActionsControllerTests.cs b/test/Altinn.App.Api.Tests/Controllers/ActionsControllerTests.cs
index 28a18fd44..1ed3f22e7 100644
--- a/test/Altinn.App.Api.Tests/Controllers/ActionsControllerTests.cs
+++ b/test/Altinn.App.Api.Tests/Controllers/ActionsControllerTests.cs
@@ -1,16 +1,20 @@
using System.Net;
using System.Net.Http.Headers;
+using System.Net.Http.Json;
using System.Text;
using System.Text.Json;
using Altinn.App.Api.Models;
using Altinn.App.Api.Tests.Data;
+using Altinn.App.Api.Tests.Data.apps.tdd.task_action.config.models;
using Altinn.App.Api.Tests.Utils;
using Altinn.App.Core.Features;
+using Altinn.App.Core.Internal.Data;
using Altinn.App.Core.Models.Process;
using Altinn.App.Core.Models.UserAction;
using FluentAssertions;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
using Xunit.Abstractions;
namespace Altinn.App.Api.Tests.Controllers;
@@ -35,7 +39,6 @@ public async Task Perform_returns_403_if_user_not_authorized()
var app = "task-action";
HttpClient client = GetRootedClient(org, app);
Guid guid = new Guid("b1135209-628e-4a6e-9efd-e4282068ef41");
- TestData.DeleteInstanceAndData(org, app, 1337, guid);
TestData.PrepareInstance(org, app, 1337, guid);
string token = PrincipalUtil.GetToken(1000, null, 3);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
@@ -61,7 +64,6 @@ public async Task Perform_returns_401_if_user_not_authenticated()
var app = "task-action";
HttpClient client = GetRootedClient(org, app);
Guid guid = new Guid("b1135209-628e-4a6e-9efd-e4282068ef41");
- TestData.DeleteInstanceAndData(org, app, 1337, guid);
TestData.PrepareInstance(org, app, 1337, guid);
using var content = new StringContent(
"{\"action\":\"lookup_unauthorized\"}",
@@ -85,7 +87,6 @@ public async Task Perform_returns_401_if_userId_is_null()
var app = "task-action";
HttpClient client = GetRootedClient(org, app);
Guid guid = new Guid("b1135209-628e-4a6e-9efd-e4282068ef41");
- TestData.DeleteInstanceAndData(org, app, 1337, guid);
TestData.PrepareInstance(org, app, 1337, guid);
string token = PrincipalUtil.GetToken(null, null, 3);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
@@ -111,7 +112,6 @@ public async Task Perform_returns_400_if_action_is_null()
var app = "task-action";
HttpClient client = GetRootedClient(org, app);
Guid guid = new Guid("b1135209-628e-4a6e-9efd-e4282068ef41");
- TestData.DeleteInstanceAndData(org, app, 1337, guid);
TestData.PrepareInstance(org, app, 1337, guid);
string token = PrincipalUtil.GetToken(1000, null, 3);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
@@ -133,7 +133,6 @@ public async Task Perform_returns_409_if_process_not_started()
var app = "task-action";
HttpClient client = GetRootedClient(org, app);
Guid guid = new Guid("b1135209-628e-4a6e-9efd-e4282068ef43");
- TestData.DeleteInstanceAndData(org, app, 1337, guid);
TestData.PrepareInstance(org, app, 1337, guid);
string token = PrincipalUtil.GetToken(1000, null, 3);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
@@ -155,7 +154,6 @@ public async Task Perform_returns_409_if_process_ended()
var app = "task-action";
HttpClient client = GetRootedClient(org, app);
Guid guid = new Guid("b1135209-628e-4a6e-9efd-e4282068ef42");
- TestData.DeleteInstanceAndData(org, app, 1337, guid);
TestData.PrepareInstance(org, app, 1337, guid);
string token = PrincipalUtil.GetToken(1000, null, 3);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
@@ -181,7 +179,6 @@ public async Task Perform_returns_200_if_action_succeeded()
var app = "task-action";
HttpClient client = GetRootedClient(org, app);
Guid guid = new Guid("b1135209-628e-4a6e-9efd-e4282068ef41");
- TestData.DeleteInstanceAndData(org, app, 1337, guid);
TestData.PrepareInstance(org, app, 1337, guid);
string token = PrincipalUtil.GetToken(1000, null, 3);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
@@ -234,7 +231,6 @@ public async Task Perform_returns_400_if_action_failed_and_errorType_is_BadReque
var app = "task-action";
HttpClient client = GetRootedClient(org, app);
Guid guid = new Guid("b1135209-628e-4a6e-9efd-e4282068ef41");
- TestData.DeleteInstanceAndData(org, app, 1337, guid);
TestData.PrepareInstance(org, app, 1337, guid);
string token = PrincipalUtil.GetToken(400, null, 3);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
@@ -260,7 +256,6 @@ public async Task Perform_returns_401_if_action_failed_and_errorType_is_Unauthor
var app = "task-action";
HttpClient client = GetRootedClient(org, app);
Guid guid = new Guid("b1135209-628e-4a6e-9efd-e4282068ef41");
- TestData.DeleteInstanceAndData(org, app, 1337, guid);
TestData.PrepareInstance(org, app, 1337, guid);
string token = PrincipalUtil.GetToken(401, null, 3);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
@@ -286,7 +281,6 @@ public async Task Perform_returns_409_if_action_failed_and_errorType_is_Conflict
var app = "task-action";
HttpClient client = GetRootedClient(org, app);
Guid guid = new Guid("b1135209-628e-4a6e-9efd-e4282068ef41");
- TestData.DeleteInstanceAndData(org, app, 1337, guid);
TestData.PrepareInstance(org, app, 1337, guid);
string token = PrincipalUtil.GetToken(409, null, 3);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
@@ -312,7 +306,6 @@ public async Task Perform_returns_500_if_action_failed_and_errorType_is_Internal
var app = "task-action";
HttpClient client = GetRootedClient(org, app);
Guid guid = new Guid("b1135209-628e-4a6e-9efd-e4282068ef41");
- TestData.DeleteInstanceAndData(org, app, 1337, guid);
TestData.PrepareInstance(org, app, 1337, guid);
string token = PrincipalUtil.GetToken(500, null, 3);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
@@ -338,7 +331,6 @@ public async Task Perform_returns_404_if_action_implementation_not_found()
var app = "task-action";
HttpClient client = GetRootedClient(org, app);
Guid guid = new Guid("b1135209-628e-4a6e-9efd-e4282068ef41");
- TestData.DeleteInstanceAndData(org, app, 1337, guid);
TestData.PrepareInstance(org, app, 1337, guid);
string token = PrincipalUtil.GetToken(1001, null, 3);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
@@ -353,6 +345,197 @@ public async Task Perform_returns_404_if_action_implementation_not_found()
response.StatusCode.Should().Be(HttpStatusCode.NotFound);
}
+ [Fact]
+ public async Task PerformFillActionThatMutatesData()
+ {
+ var org = "tdd";
+ var app = "task-action";
+ Guid instanceGuid = new Guid("b1135209-628e-4a6e-9efd-e4282068ef41");
+ int instanceOwner = 1337;
+ TestData.PrepareInstance(org, app, 1337, instanceGuid);
+ OverrideServicesForThisTest = (services) =>
+ {
+ services.AddTransient();
+ };
+ var client = GetRootedClient(org, app, 1337, null);
+ string token = PrincipalUtil.GetToken(1001, null, 3);
+ client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
+
+ // Run buttonId "add"
+ using var content = JsonContent.Create(new { action = "fill", buttonId = "add" });
+ using HttpResponseMessage addResponse = await client.PostAsync(
+ $"/{org}/{app}/instances/{instanceOwner}/{instanceGuid}/actions",
+ content
+ );
+
+ var parsedAddResponse = await VerifyStatusAndDeserialize(addResponse, HttpStatusCode.OK);
+ parsedAddResponse.ClientActions.Should().BeEmpty();
+ parsedAddResponse.Instance.Should().NotBeNull();
+ parsedAddResponse.Instance.Id.Should().Be($"{instanceOwner}/{instanceGuid}");
+ var dataElement = parsedAddResponse.Instance.Data.Should().ContainSingle().Which;
+
+ var schemeElement = parsedAddResponse
+ .UpdatedDataModels.Should()
+ .HaveCount(1)
+ .And.ContainKey(dataElement.Id)
+ .WhoseValue.Should()
+ .BeOfType()
+ .Which;
+ var scheme =
+ schemeElement.Deserialize(_jsonSerializerOptions)
+ ?? throw new Exception("Failed to deserialize Scheme");
+ scheme.TestCustomButtonInput.Should().Be("Hello a");
+
+ // Run buttonId "update"
+ using var updateContent = JsonContent.Create(new { action = "fill", buttonId = "update" });
+ using HttpResponseMessage updateResponse = await client.PostAsync(
+ $"/{org}/{app}/instances/{instanceOwner}/{instanceGuid}/actions",
+ updateContent
+ );
+ var parsedUpdateResponse = await VerifyStatusAndDeserialize(
+ updateResponse,
+ HttpStatusCode.OK
+ );
+ parsedUpdateResponse.ClientActions.Should().BeEmpty();
+ parsedUpdateResponse.Instance.Should().NotBeNull();
+ parsedUpdateResponse.Instance.Id.Should().Be($"{instanceOwner}/{instanceGuid}");
+ var updatedDataElement = parsedUpdateResponse.Instance.Data.Should().ContainSingle().Which;
+ var updatedSchemeElement = parsedUpdateResponse
+ .UpdatedDataModels.Should()
+ .HaveCount(1)
+ .And.ContainKey(updatedDataElement.Id)
+ .WhoseValue.Should()
+ .BeOfType()
+ .Which;
+ var updatedScheme =
+ updatedSchemeElement.Deserialize(_jsonSerializerOptions)
+ ?? throw new Exception("Failed to deserialize Scheme");
+ updatedScheme.TestCustomButtonInput.Should().Be("Hello a");
+ updatedScheme.TestCustomButtonReadOnlyInput.Should().Be("Her kommer det data fra backend");
+
+ TestData
+ .GetDataElementBlobContnet(org, app, instanceOwner, instanceGuid, Guid.Parse(updatedDataElement.Id))
+ .Should()
+ .Contain("Her kommer det data fra backend");
+
+ // Run buttonId "updateObsolete"
+ using var updateObsoleteContent = JsonContent.Create(new { action = "fill", buttonId = "updateObsolete" });
+ using HttpResponseMessage updateObsoleteResponse = await client.PostAsync(
+ $"/{org}/{app}/instances/{instanceOwner}/{instanceGuid}/actions",
+ updateObsoleteContent
+ );
+ var parsedUpdateObsoleteResponse = await VerifyStatusAndDeserialize(
+ updateObsoleteResponse,
+ HttpStatusCode.OK
+ );
+ parsedUpdateObsoleteResponse.ClientActions.Should().BeEmpty();
+ parsedUpdateObsoleteResponse.Instance.Should().NotBeNull();
+ parsedUpdateObsoleteResponse.Instance.Id.Should().Be($"{instanceOwner}/{instanceGuid}");
+ var updatedObsoleteDataElement = parsedUpdateObsoleteResponse.Instance.Data.Should().ContainSingle().Which;
+ var updatedObsoleteSchemeElement = parsedUpdateObsoleteResponse
+ .UpdatedDataModels.Should()
+ .HaveCount(1)
+ .And.ContainKey(updatedObsoleteDataElement.Id)
+ .WhoseValue.Should()
+ .BeOfType()
+ .Which;
+ var updatedObsoleteScheme =
+ updatedObsoleteSchemeElement.Deserialize(_jsonSerializerOptions)
+ ?? throw new Exception("Failed to deserialize Scheme");
+ updatedObsoleteScheme.description.Should().Be("Obsolete data");
+
+ TestData
+ .GetDataElementBlobContnet(org, app, instanceOwner, instanceGuid, Guid.Parse(updatedDataElement.Id))
+ .Should()
+ .Contain("Obsolete data");
+
+ // Run buttonId "delete"
+ using var deleteContent = JsonContent.Create(new { action = "fill", buttonId = "delete" });
+ using HttpResponseMessage deleteResponse = await client.PostAsync(
+ $"/{org}/{app}/instances/{instanceOwner}/{instanceGuid}/actions",
+ deleteContent
+ );
+ var parsedDeleteResponse = await VerifyStatusAndDeserialize(
+ deleteResponse,
+ HttpStatusCode.OK
+ );
+ parsedDeleteResponse.ClientActions.Should().BeEmpty();
+ parsedDeleteResponse.Instance.Should().NotBeNull();
+ parsedDeleteResponse.Instance.Id.Should().Be($"{instanceOwner}/{instanceGuid}");
+ parsedDeleteResponse.Instance.Data.Should().BeEmpty();
+ parsedDeleteResponse.UpdatedDataModels.Should().BeEmpty();
+
+ // Cleanup testdata
+ TestData.DeleteInstanceAndData(org, app, instanceOwner, instanceGuid);
+ }
+
+ [Fact]
+ public async Task PerformFillAction_GetClientActions()
+ {
+ var org = "tdd";
+ var app = "task-action";
+ Guid instanceGuid = new Guid("b1135209-628e-4a6e-9efd-e4282068ef41");
+ int instanceOwner = 1337;
+ TestData.PrepareInstance(org, app, 1337, instanceGuid);
+ OverrideServicesForThisTest = (services) =>
+ {
+ services.AddTransient();
+ };
+ var client = GetRootedClient(org, app, 1337, null);
+ string token = PrincipalUtil.GetToken(1001, null, 3);
+ client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
+
+ // run buttonId "getClientActions"
+ using var getClientActionsContent = JsonContent.Create(new { action = "fill", buttonId = "getClientActions" });
+ using HttpResponseMessage getClientActionsResponse = await client.PostAsync(
+ $"/{org}/{app}/instances/{instanceOwner}/{instanceGuid}/actions",
+ getClientActionsContent
+ );
+ var parsedGetClientActionsResponse = await VerifyStatusAndDeserialize(
+ getClientActionsResponse,
+ HttpStatusCode.OK
+ );
+ parsedGetClientActionsResponse.ClientActions.Should().ContainSingle().Which.Id.Should().Be("nextPage");
+
+ // Cleanup testdata
+ TestData.DeleteInstanceAndData(org, app, instanceOwner, instanceGuid);
+ }
+
+ [Fact]
+ public async Task PerformFillAction_Fail()
+ {
+ var org = "tdd";
+ var app = "task-action";
+ Guid instanceGuid = new Guid("b1135209-628e-4a6e-9efd-e4282068ef41");
+ int instanceOwner = 1337;
+ TestData.PrepareInstance(org, app, 1337, instanceGuid);
+ OverrideServicesForThisTest = (services) =>
+ {
+ services.AddTransient();
+ };
+ var client = GetRootedClient(org, app, 1337, null);
+ string token = PrincipalUtil.GetToken(1001, null, 3);
+ client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
+
+ // Run buttonId "fail"
+ using var failContent = JsonContent.Create(new { action = "fill", buttonId = "fail" });
+ using HttpResponseMessage failResponse = await client.PostAsync(
+ $"/{org}/{app}/instances/{instanceOwner}/{instanceGuid}/actions",
+ failContent
+ );
+ var parsedFailResponse = await VerifyStatusAndDeserialize(
+ failResponse,
+ HttpStatusCode.Conflict
+ );
+ parsedFailResponse.ClientActions.Should().ContainSingle().Which.Id.Should().Be("nextPage");
+ parsedFailResponse.Error.Should().NotBeNull();
+ parsedFailResponse.Error!.Code.Should().Be("machine-readable-error-code");
+ parsedFailResponse.Error!.Message.Should().Be("Her kommer det en feilmelding");
+
+ // Cleanup testdata
+ TestData.DeleteInstanceAndData(org, app, instanceOwner, instanceGuid);
+ }
+
//TODO: replace this assertion with a proper one once fluentassertions has a json compare feature scheduled for v7 https://github.com/fluentassertions/fluentassertions/issues/2205
private void CompareResult(string expectedString, string actualString, Action? mutator = null)
{
@@ -366,6 +549,88 @@ private void CompareResult(string expectedString, string actualString, Action
}
}
+public class FillAction : IUserAction
+{
+ private readonly ILogger _logger;
+ private readonly IDataClient _dataClient;
+
+ public string Id => "fill";
+
+ public FillAction(ILogger logger, IDataClient dataClient)
+ {
+ _logger = logger;
+ _dataClient = dataClient;
+ }
+
+ public async Task HandleAction(UserActionContext context)
+ {
+ _logger.LogInformation("FillAction triggered, with button id: {buttonId}", context.ButtonId);
+
+ switch (context.ButtonId)
+ {
+ case "add":
+ context.DataMutator.AddFormDataElement(
+ "Scheme",
+ new Scheme()
+ {
+ TestCustomButtonReadOnlyInput = "Første runde",
+ TestCustomButtonInput = "Hello a",
+ description = "Første runde"
+ }
+ );
+ break;
+ case "update":
+ var originalDataElement = context.DataMutator.FormDataElements.First(de => de.DataType == "Scheme");
+ var originalData = await context.DataMutator.GetFormData(originalDataElement);
+ var data = (Scheme)originalData;
+
+ data.TestCustomButtonReadOnlyInput = "Her kommer det data fra backend";
+ break;
+ case "updateObsolete":
+ var instanceId = context.Instance.Id;
+ var instanceGuid = Guid.Parse(instanceId.Split('/')[1]);
+ var instanceOwner = int.Parse(instanceId.Split('/')[0]);
+ var dataGuid = Guid.Parse(context.Instance.Data.Single().Id);
+
+ var obsoleteData = (Scheme)
+ await _dataClient.GetFormData(
+ instanceGuid,
+ typeof(Scheme),
+ context.Instance.Org,
+ context.Instance.AppId.Split('/')[1],
+ instanceOwner,
+ dataGuid
+ );
+ obsoleteData.description = "Obsolete data";
+ var result = UserActionResult.SuccessResult(new List());
+ result.AddUpdatedDataModel(dataGuid.ToString(), obsoleteData);
+ return result;
+ case "delete":
+ var elementToDelete = context.DataMutator.FormDataElements.First(de => de.DataType == "Scheme");
+ context.DataMutator.RemoveDataElement(elementToDelete);
+ break;
+ case "getClientActions":
+ return UserActionResult.SuccessResult([new ClientAction() { Id = "nextPage" }]);
+
+ case "fail":
+ return UserActionResult.FailureResult(
+ new ActionError()
+ {
+ Code = "machine-readable-error-code",
+ Message = "Her kommer det en feilmelding",
+ Metadata = new Dictionary() { { "key1", "value1" }, }
+ },
+ [new ClientAction() { Id = "nextPage" }],
+ errorType: ProcessErrorType.Conflict
+ );
+ default:
+ throw new Exception($"Button id {context.ButtonId} not supported");
+ }
+
+ return UserActionResult.SuccessResult(new List());
+ }
+}
+
public class LookupAction : IUserAction
{
public string Id => "lookup";
diff --git a/test/Altinn.App.Api.Tests/Controllers/DataControllerTests.cs b/test/Altinn.App.Api.Tests/Controllers/DataControllerTests.cs
index ca16fa3f5..c19e18e03 100644
--- a/test/Altinn.App.Api.Tests/Controllers/DataControllerTests.cs
+++ b/test/Altinn.App.Api.Tests/Controllers/DataControllerTests.cs
@@ -30,7 +30,6 @@ public async Task PutDataElement_MissingDataType_ReturnsBadRequest()
string token = PrincipalUtil.GetOrgToken("nav", "160694123");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
- TestData.DeleteInstanceAndData(org, app, instanceOwnerPartyId, guid);
TestData.PrepareInstance(org, app, instanceOwnerPartyId, guid);
using var content = new StringContent("{}", System.Text.Encoding.UTF8, "application/json"); // empty valid json
@@ -53,7 +52,6 @@ public async Task PostBinaryElement_ContentTooLarge_ReturnsBadRequest()
string token = PrincipalUtil.GetOrgToken("nav", "160694123");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
- TestData.DeleteInstanceAndData(org, app, instanceOwnerPartyId, guid);
TestData.PrepareInstance(org, app, instanceOwnerPartyId, guid);
using var content = new ByteArrayContent(new byte[1024 * 1024 + 1]); // 1 mb
@@ -93,7 +91,6 @@ public async Task CreateDataElement_BinaryPdf_AnalyserShouldRunOk()
HttpClient client = GetRootedClient(org, app);
Guid guid = new Guid("0fc98a23-fe31-4ef5-8fb9-dd3f479354cd");
- TestData.DeleteInstanceAndData(org, app, 1337, guid);
TestData.PrepareInstance(org, app, 1337, guid);
// Setup the request
@@ -127,7 +124,6 @@ public async Task CreateDataElement_ZeroBytes_BinaryPdf_AnalyserShouldReturnBadR
HttpClient client = GetRootedClient(org, app);
Guid guid = new Guid("0fc98a23-fe31-4ef5-8fb9-dd3f479354cd");
- TestData.DeleteInstanceAndData(org, app, 1337, guid);
TestData.PrepareInstance(org, app, 1337, guid);
// Setup the request
@@ -163,7 +159,6 @@ public async Task CreateDataElement_JpgFakedAsPdf_AnalyserShouldRunAndFail()
HttpClient client = GetRootedClient(org, app);
Guid guid = new Guid("1fc98a23-fe31-4ef5-8fb9-dd3f479354ce");
- TestData.DeleteInstanceAndData(org, app, 1337, guid);
TestData.PrepareInstance(org, app, 1337, guid);
// Setup the request
diff --git a/test/Altinn.App.Api.Tests/Controllers/DataController_LayoutEvaluatorTests.cs b/test/Altinn.App.Api.Tests/Controllers/DataController_LayoutEvaluatorTests.cs
index ef828f916..54239934e 100644
--- a/test/Altinn.App.Api.Tests/Controllers/DataController_LayoutEvaluatorTests.cs
+++ b/test/Altinn.App.Api.Tests/Controllers/DataController_LayoutEvaluatorTests.cs
@@ -74,7 +74,6 @@ public async Task PutDataElement_LegacyLayoutEvaluatorState_ReturnsOk()
Guid dataGuid = Guid.Parse("f3e04c65-aa70-40ec-84df-087cc2583402");
HttpClient client = GetRootedClient(org, app, 1337, instanceOwnerPartyId);
- TestData.DeleteInstanceAndData(org, app, instanceOwnerPartyId, instanceGuid);
TestData.PrepareInstance(org, app, instanceOwnerPartyId, instanceGuid);
// Update data element
diff --git a/test/Altinn.App.Api.Tests/Controllers/DataController_PatchTests.cs b/test/Altinn.App.Api.Tests/Controllers/DataController_PatchTests.cs
index 1426e2f78..1b2c6d88a 100644
--- a/test/Altinn.App.Api.Tests/Controllers/DataController_PatchTests.cs
+++ b/test/Altinn.App.Api.Tests/Controllers/DataController_PatchTests.cs
@@ -66,7 +66,6 @@ public DataControllerPatchTests(WebApplicationFactory factory, ITestOut
services.AddSingleton(_dataProcessorMock.Object);
services.AddSingleton(_formDataValidatorMock.Object);
};
- TestData.DeleteInstanceAndData(Org, App, InstanceOwnerPartyId, _instanceGuid);
TestData.PrepareInstance(Org, App, InstanceOwnerPartyId, _instanceGuid);
}
diff --git a/test/Altinn.App.Api.Tests/Controllers/DataController_PostTests.cs b/test/Altinn.App.Api.Tests/Controllers/DataController_PostTests.cs
index 22de25a8d..c0f1abf72 100644
--- a/test/Altinn.App.Api.Tests/Controllers/DataController_PostTests.cs
+++ b/test/Altinn.App.Api.Tests/Controllers/DataController_PostTests.cs
@@ -33,7 +33,6 @@ public class DataController_PostTests : ApiTestBase, IClassFixture factory, ITestOutputHelper outputHelper)
: base(factory, outputHelper)
{
- TestData.DeleteInstanceAndData(_org, _app, _instanceOwnerPartyId, _instanceGuid);
TestData.PrepareInstance(_org, _app, _instanceOwnerPartyId, _instanceGuid);
OverrideServicesForAllTests = (services) =>
{
diff --git a/test/Altinn.App.Api.Tests/Controllers/ProcessControllerTests.cs b/test/Altinn.App.Api.Tests/Controllers/ProcessControllerTests.cs
index 5a0e5ae51..7c9daba8c 100644
--- a/test/Altinn.App.Api.Tests/Controllers/ProcessControllerTests.cs
+++ b/test/Altinn.App.Api.Tests/Controllers/ProcessControllerTests.cs
@@ -60,7 +60,6 @@ public ProcessControllerTests(WebApplicationFactory factory, ITestOutpu
services.AddSingleton(_dataProcessorMock.Object);
services.AddSingleton(_formDataValidatorMock.Object);
};
- TestData.DeleteInstanceAndData(Org, App, InstanceOwnerPartyId, _instanceGuid);
TestData.PrepareInstance(Org, App, InstanceOwnerPartyId, _instanceGuid);
}
@@ -74,7 +73,6 @@ public async Task Get_ShouldReturnProcessTasks()
HttpClient client = GetRootedClient(org, app, 1337, partyId, 3);
- TestData.DeleteInstanceAndData(org, app, partyId, instanceId);
TestData.PrepareInstance(org, app, partyId, instanceId);
string url = $"/{org}/{app}/instances/{partyId}/{instanceId}/process";
diff --git a/test/Altinn.App.Api.Tests/Controllers/ValidateController_ValidateInstanceTests.cs b/test/Altinn.App.Api.Tests/Controllers/ValidateController_ValidateInstanceTests.cs
index ff823ca8c..e6a4d9ae6 100644
--- a/test/Altinn.App.Api.Tests/Controllers/ValidateController_ValidateInstanceTests.cs
+++ b/test/Altinn.App.Api.Tests/Controllers/ValidateController_ValidateInstanceTests.cs
@@ -51,7 +51,6 @@ ITestOutputHelper outputHelper
services.AddSingleton(_dataProcessorMock.Object);
services.AddSingleton(_formDataValidatorMock.Object);
};
- TestData.DeleteInstanceAndData(Org, App, InstanceOwnerPartyId, InstanceGuid);
TestData.PrepareInstance(Org, App, InstanceOwnerPartyId, InstanceGuid);
}
diff --git a/test/Altinn.App.Api.Tests/CustomWebApplicationFactory.cs b/test/Altinn.App.Api.Tests/CustomWebApplicationFactory.cs
index 8d7b35243..2e5733203 100644
--- a/test/Altinn.App.Api.Tests/CustomWebApplicationFactory.cs
+++ b/test/Altinn.App.Api.Tests/CustomWebApplicationFactory.cs
@@ -215,7 +215,8 @@ private void ConfigureFakeHttpClientHandler(IServiceCollection services)
}
///
- /// Set this in your test class constructor
+ /// Helper to quickly verify the status code and deserialize the content of a response.
+ /// and print the content to output helper
///
protected async Task VerifyStatusAndDeserialize(
HttpResponseMessage response,
@@ -224,7 +225,10 @@ HttpStatusCode expectedStatusCode
{
// Deserialize content and log everything if it fails
var content = await response.Content.ReadAsStringAsync();
- OutputHelper.WriteLine($"Response content: {content}");
+ OutputHelper.WriteLine(
+ $"{response.RequestMessage?.Method} {response.RequestMessage?.RequestUri?.PathAndQuery}"
+ );
+ OutputHelper.WriteLine(JsonUtils.IndentJson(content));
// Verify status code
response.Should().HaveStatusCode(expectedStatusCode);
try
@@ -239,8 +243,6 @@ HttpStatusCode expectedStatusCode
OutputHelper.WriteLine(
$"Failed to deserialize content of {response.RequestMessage?.Method} request to {response.RequestMessage?.RequestUri} as {ReflectionUtils.GetTypeNameWithGenericArguments()}:"
);
-
- OutputHelper.WriteLine(JsonUtils.IndentJson(content));
OutputHelper.WriteLine(string.Empty);
throw;
}
diff --git a/test/Altinn.App.Api.Tests/Data/Instances/tdd/.gitignore b/test/Altinn.App.Api.Tests/Data/Instances/.gitignore
similarity index 64%
rename from test/Altinn.App.Api.Tests/Data/Instances/tdd/.gitignore
rename to test/Altinn.App.Api.Tests/Data/Instances/.gitignore
index 8c777c01b..fa3349399 100644
--- a/test/Altinn.App.Api.Tests/Data/Instances/tdd/.gitignore
+++ b/test/Altinn.App.Api.Tests/Data/Instances/.gitignore
@@ -1,4 +1,4 @@
# Ignore guid.json files
????????-????-????-????-????????????.json
# ignore copied blobs
-*/*/*/blob/????????-????-????-????-????????????
+**/blob/????????-????-????-????-????????????
diff --git a/test/Altinn.App.Api.Tests/Data/Instances/tdd/task-action/1337/b1135209-628e-4a6e-9efd-e4282068ef41.pretest.json b/test/Altinn.App.Api.Tests/Data/Instances/tdd/task-action/1337/b1135209-628e-4a6e-9efd-e4282068ef41.pretest.json
index 69ac2d877..cb13d3a91 100644
--- a/test/Altinn.App.Api.Tests/Data/Instances/tdd/task-action/1337/b1135209-628e-4a6e-9efd-e4282068ef41.pretest.json
+++ b/test/Altinn.App.Api.Tests/Data/Instances/tdd/task-action/1337/b1135209-628e-4a6e-9efd-e4282068ef41.pretest.json
@@ -26,14 +26,5 @@
"isSoftDeleted": false,
"isHardDeleted": false,
"readStatus": "Read"
- },
- "data": [
- {
- "id": "de288942-a8af-4f77-a1f1-6e1ede1cd502",
- "dataType": "default",
- "contentType": "application/xml",
- "size": 0,
- "locked": false
- }
- ]
+ }
}
diff --git a/test/Altinn.App.Api.Tests/Data/TestData.cs b/test/Altinn.App.Api.Tests/Data/TestData.cs
index 88b7d6156..8cdbc3f76 100644
--- a/test/Altinn.App.Api.Tests/Data/TestData.cs
+++ b/test/Altinn.App.Api.Tests/Data/TestData.cs
@@ -96,6 +96,18 @@ Guid dataGuid
return Path.Combine(dataDirectory, $"{dataGuid}.json");
}
+ public static string GetDataElementBlobContnet(
+ string org,
+ string app,
+ int instanceOwnerId,
+ Guid instanceGuid,
+ Guid dataGuid
+ )
+ {
+ string dataElementPath = GetDataBlobPath(org, app, instanceOwnerId, instanceGuid, dataGuid);
+ return File.ReadAllText(dataElementPath);
+ }
+
public static string GetDataBlobPath(string org, string app, int instanceOwnerId, Guid instanceGuid, Guid dataGuid)
{
string dataDirectory = GetDataDirectory(org, app, instanceOwnerId, instanceGuid);
@@ -142,6 +154,7 @@ public static string GetInstancePath(string org, string app, int instanceOwnerId
public static void PrepareInstance(string org, string app, int instanceOwnerId, Guid instanceGuid)
{
+ DeleteInstanceAndData(org, app, instanceOwnerId, instanceGuid);
string instancePath = GetInstancePath(org, app, instanceOwnerId, instanceGuid);
string preInstancePath = instancePath.Replace(".json", ".pretest.json");
@@ -185,7 +198,7 @@ public static void DeleteInstanceAndData(string org, string app, int instanceOwn
}
}
- public static void DeleteDataForInstance(string org, string app, int instanceOwnerId, Guid instanceGuid)
+ private static void DeleteDataForInstance(string org, string app, int instanceOwnerId, Guid instanceGuid)
{
string path = GetDataDirectory(org, app, instanceOwnerId, instanceGuid);
diff --git a/test/Altinn.App.Api.Tests/Data/apps/tdd/task-action/config/applicationmetadata.json b/test/Altinn.App.Api.Tests/Data/apps/tdd/task-action/config/applicationmetadata.json
index 04fdae29e..f5a79437f 100644
--- a/test/Altinn.App.Api.Tests/Data/apps/tdd/task-action/config/applicationmetadata.json
+++ b/test/Altinn.App.Api.Tests/Data/apps/tdd/task-action/config/applicationmetadata.json
@@ -1,6 +1,6 @@
{
- "id": "ttd/task-action",
- "org": "ttd",
+ "id": "tdd/task-action",
+ "org": "tdd",
"title": {
"nb": "task-action"
},
@@ -25,7 +25,7 @@
],
"appLogic": {
"autoCreate": true,
- "classRef": "Altinn.App.Models.Scheme",
+ "classRef": "Altinn.App.Api.Tests.Data.apps.tdd.task_action.config.models.Scheme",
"allowAnonymousOnStateless": false,
"autoDeleteOnProcessEnd": false
},
@@ -50,4 +50,4 @@
"createdBy": "tjololo",
"lastChanged": "2023-05-31T08:03:25.9385925Z",
"lastChangedBy": "tjololo"
-}
\ No newline at end of file
+}
diff --git a/test/Altinn.App.Api.Tests/Data/apps/tdd/task-action/config/models/Scheme.cs b/test/Altinn.App.Api.Tests/Data/apps/tdd/task-action/config/models/Scheme.cs
new file mode 100644
index 000000000..84adfbabd
--- /dev/null
+++ b/test/Altinn.App.Api.Tests/Data/apps/tdd/task-action/config/models/Scheme.cs
@@ -0,0 +1,18 @@
+#pragma warning disable IDE1006 // Naming Styles
+namespace Altinn.App.Api.Tests.Data.apps.tdd.task_action.config.models;
+
+///
+/// Class for the model
+///
+public class Scheme
+{
+ public string? name { get; set; }
+
+ public string? description { get; set; }
+
+ public string? TestCustomButtonInput { get; set; }
+
+ public string? TestCustomButtonReadOnlyInput { get; set; }
+}
+
+#pragma warning restore IDE1006 // Naming Styles