Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mlqn committed Jan 7, 2025
1 parent 73e2f93 commit fd717a6
Show file tree
Hide file tree
Showing 23 changed files with 729 additions and 106 deletions.
Original file line number Diff line number Diff line change
@@ -1,101 +1,35 @@
using System.IO;
using System.Linq;
using System.Text.Json.Nodes;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Altinn.Studio.Designer.Events;
using Altinn.Studio.Designer.Hubs.SyncHub;
using Altinn.Studio.Designer.Models;
using Altinn.Studio.Designer.Services.Interfaces;
using MediatR;

namespace Altinn.Studio.Designer.EventHandlers.ProcessTaskIdChanged;

public class ProcessTaskIdChangedLayoutsHandler : INotificationHandler<ProcessTaskIdChangedEvent>
{
private readonly IAltinnGitRepositoryFactory _altinnGitRepositoryFactory;
private readonly IFileSyncHandlerExecutor _fileSyncHandlerExecutor;
private readonly IAppDevelopmentService _appDevelopmentService;

public ProcessTaskIdChangedLayoutsHandler(IAltinnGitRepositoryFactory altinnGitRepositoryFactory,
IFileSyncHandlerExecutor fileSyncHandlerExecutor)
public ProcessTaskIdChangedLayoutsHandler(IFileSyncHandlerExecutor fileSyncHandlerExecutor, IAppDevelopmentService appDevelopmentService)
{
_altinnGitRepositoryFactory = altinnGitRepositoryFactory;
_fileSyncHandlerExecutor = fileSyncHandlerExecutor;
_appDevelopmentService = appDevelopmentService;
}

public async Task Handle(ProcessTaskIdChangedEvent notification, CancellationToken cancellationToken)
{
var repository = _altinnGitRepositoryFactory.GetAltinnAppGitRepository(
notification.EditingContext.Org,
notification.EditingContext.Repo,
notification.EditingContext.Developer);

if (!repository.AppUsesLayoutSets())
{
return;
}

var layoutSetsFile = await repository.GetLayoutSetsFile(cancellationToken);

foreach (string layoutSetName in layoutSetsFile.Sets.Select(layoutSet => layoutSet.Id))
{
string[] layoutNames;
try
{
layoutNames = repository.GetLayoutNames(layoutSetName);
}
catch (FileNotFoundException)
await _fileSyncHandlerExecutor.ExecuteWithExceptionHandlingAndConditionalNotification(
notification.EditingContext,
SyncErrorCodes.LayoutTaskIdSyncError,
"layouts",
async () =>
{
continue;
}

await _fileSyncHandlerExecutor.ExecuteWithExceptionHandlingAndConditionalNotification(
notification.EditingContext,
SyncErrorCodes.LayoutTaskIdSyncError,
$"App/ui/{layoutSetName}/layouts",
async () =>
{
bool hasChanged = false;

foreach (string layoutName in layoutNames)
{
var layout = await repository.GetLayout(layoutSetName, layoutName, cancellationToken);
if (TryChangeLayoutTaskIds(layout, notification.OldId, notification.NewId))
{
await repository.SaveLayout(layoutSetName, layoutName, layout, cancellationToken);
hasChanged = true;
}
}

return hasChanged;
});
}
}

private static bool TryChangeLayoutTaskIds(JsonNode node, string oldId, string newId)
{
bool hasChanged = false;

if (node is JsonObject jsonObject)
{
foreach (var property in jsonObject.ToList())
{
if (property.Key == "taskId" && property.Value?.ToString() == oldId)
{
jsonObject["taskId"] = newId;
hasChanged = true;
}

hasChanged |= TryChangeLayoutTaskIds(property.Value, oldId, newId);
}
}
else if (node is JsonArray jsonArray)
{
foreach (var element in jsonArray)
{
hasChanged |= TryChangeLayoutTaskIds(element, oldId, newId);
}
}

return hasChanged;
List<Reference> referencesToUpdate = [new Reference("task", null, notification.OldId, notification.NewId)];
return await _appDevelopmentService.UpdateLayoutReferences(notification.EditingContext, referencesToUpdate, cancellationToken);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,7 @@ private async Task<bool> UpdateLayoutReferences(AltinnAppGitRepository altinnApp
var deletedLayouts = deletedReferences.Where(item => item.Type == "page").ToList();
var deletedComponents = deletedReferences.Where(item => item.Type == "component").ToList();

var updatedTasks = updatedReferences.Where(item => item.Type == "task").ToList();
var updatedLayoutsSets = updatedReferences.Where(item => item.Type == "layoutSet").ToList();
var updatedLayouts = updatedReferences.Where(item => item.Type == "page").ToList();
var updatedComponents = updatedReferences.Where(item => item.Type == "component").ToList();
Expand Down Expand Up @@ -710,12 +711,11 @@ private async Task<bool> UpdateLayoutReferences(AltinnAppGitRepository altinnApp
string taskId = target["taskId"]?.GetValue<string>();
string layoutSetId = string.IsNullOrEmpty(taskId) ? layoutSet.Id : layoutSets?.FirstOrDefault(item => item.Tasks?.Contains(taskId) ?? false)?.Id;

if (type switch
{
"layoutSet" => deletedLayoutsSetIds.Contains(layoutSetId),
"page" => deletedLayouts.Exists(item => item.LayoutSetName == layoutSetId && item.Id == id),
"component" => deletedComponents.Exists(item => item.LayoutSetName == layoutSetId && item.Id == id)
})
if (
(type == "page" && deletedLayouts.Exists(item => item.LayoutSetName == layoutSetId && item.Id == id))
|| (type == "component" && deletedComponents.Exists(item => item.LayoutSetName == layoutSetId && item.Id == id))
|| deletedLayoutsSetIds.Contains(layoutSetId)
)
{
referencesToDelete.Add(new Reference("component", layoutSet.Id, componentId));
componentList.RemoveAt(i);
Expand All @@ -724,34 +724,30 @@ private async Task<bool> UpdateLayoutReferences(AltinnAppGitRepository altinnApp
else
{
Reference updatedReference = null;

switch (type)
{
case "layoutSet":
updatedReference = updatedLayoutsSets.FirstOrDefault(item => item.Type == type && item.Id == layoutSetId);
if (updatedReference != null)
{
target["taskId"] = updatedReference.NewId;
hasLayoutChanges = true;
}
break;
case "page":
updatedReference = updatedLayouts.FirstOrDefault(item => item.Type == type && item.LayoutSetName == layoutSetId && item.Id == id);
if (updatedReference != null)
{
target["id"] = updatedReference.NewId;
hasLayoutChanges = true;
}
updatedReference = updatedLayouts.FirstOrDefault(item => item.LayoutSetName == layoutSetId && item.Id == id);
break;
case "component":
updatedReference = updatedComponents.FirstOrDefault(item => item.Type == type && item.LayoutSetName == layoutSetId && item.Id == id);
if (updatedReference != null)
{
target["id"] = updatedReference.NewId;
hasLayoutChanges = true;
}
updatedReference = updatedComponents.FirstOrDefault(item => item.LayoutSetName == layoutSetId && item.Id == id);
break;
}
if (updatedReference != null)
{
target["id"] = updatedReference.NewId;
hasLayoutChanges = true;
}

if (!string.IsNullOrEmpty(taskId))
{
updatedReference = updatedTasks.FirstOrDefault(item => item.Id == taskId);
if (updatedReference != null)
{
target["taskId"] = updatedReference.NewId;
hasLayoutChanges = true;
}
}
}

if (component["overrides"] is JsonArray overrideList)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Linq;
using System.Net;
using System.Net.Http;
Expand Down Expand Up @@ -138,6 +139,49 @@ public async Task SaveFormLayoutWithDeletedComponent_DeletesAssociatedSummary2Co
});
}

[Theory]
[InlineData("ttd", "testUser", "component", "Side2", "Input-Om7N3y", "Input-Om7N3y-new")]
public async Task SaveFormLayoutWithUpdatedComponentName_UpdatesAssociatedSummary2Components_ReturnsOk(string org, string developer, string layoutSetName, string layoutName, string componentId, string newComponentId)
{
string actualApp = "app-with-summary2-components";
string app = TestDataHelper.GenerateTestRepoName();
await CopyRepositoryForTest(org, actualApp, developer, app);

string layout = TestDataHelper.GetFileFromRepo(org, app, developer, $"App/ui/{layoutSetName}/layouts/{layoutName}.json");
JsonNode layoutWithUpdatedComponent = JsonNode.Parse(layout);

string url = $"{VersionPrefix(org, app)}/form-layout/{layoutName}?layoutSetName={layoutSetName}";
var payload = new JsonObject
{
["componentIdsChange"] = new JsonArray() {
new JsonObject
{
["oldComponentId"] = componentId,
["newComponentId"] = newComponentId,
}
},
["layout"] = layoutWithUpdatedComponent
};
HttpResponseMessage response = await SendHttpRequest(url, payload);
response.StatusCode.Should().Be(HttpStatusCode.OK);

string expectedApp = "app-with-summary2-components-after-updating-references";

string[] layoutPaths = [
"component/layouts/Side1.json",
"component/layouts/Side2.json",
"component2/layouts/Side1.json",
"component2/layouts/Side2.json"
];

layoutPaths.ToList().ForEach(file =>
{
string actual = TestDataHelper.GetFileFromRepo(org, app, developer, $"App/ui/{file}");
string expected = TestDataHelper.GetFileFromRepo(org, expectedApp, developer, $"App/ui/{file}");
JsonUtils.DeepEquals(actual, expected).Should().BeTrue();
});
}

[Theory]
[InlineData("ttd", "app-with-layoutsets", "testUser", "testLayout", "layoutSet1", "TestData/App/ui/layoutWithUnknownProperties.json")]
public async Task SaveFormLayoutWithNewPageLanguageUpdate_ReturnsOk(string org, string app, string developer, string layoutName, string layoutSetName, string layoutPath)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
using FluentAssertions;
using Microsoft.AspNetCore.Mvc.Testing;
using Xunit;
using System.Linq;
using SharedResources.Tests;

namespace Designer.Tests.Controllers.AppDevelopmentController
{
Expand Down Expand Up @@ -69,5 +71,38 @@ public async Task UpdateFormLayoutName_NonExistingName_ShouldReturnNotFound(stri
response.StatusCode.Should().Be(HttpStatusCode.NotFound);
}

[Theory]
[InlineData("ttd", "testUser", "layout", "Side2", "Side2-new")]
public async Task UpdateFormLayoutName_UpdatesAssociatedSummary2Components_ReturnsOk(string org, string developer, string layoutSetName, string layoutName, string newLayoutName)
{
string actualApp = "app-with-summary2-components";
string app = TestDataHelper.GenerateTestRepoName();
await CopyRepositoryForTest(org, actualApp, developer, app);

string url = $"{VersionPrefix(org, app)}/form-layout-name/{layoutName}?layoutSetName={layoutSetName}";
using var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, url)
{
Content = new StringContent($"\"{newLayoutName}\"", Encoding.UTF8, MediaTypeNames.Application.Json)
};

using var response = await HttpClient.SendAsync(httpRequestMessage);
response.StatusCode.Should().Be(HttpStatusCode.OK);

string expectedApp = "app-with-summary2-components-after-updating-references";

string[] layoutPaths = [
"layout/layouts/Side1.json",
"layout/layouts/Side2.json",
"layout2/layouts/Side1.json",
"layout2/layouts/Side2.json",
];

layoutPaths.ToList().ForEach(file =>
{
string actual = TestDataHelper.GetFileFromRepo(org, app, developer, $"App/ui/{file}");
string expected = TestDataHelper.GetFileFromRepo(org, expectedApp, developer, $"App/ui/{file}");
JsonUtils.DeepEquals(actual, expected).Should().BeTrue();
});
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "https://altinncdn.no/schemas/json/layout/layoutSettings.schema.v1.json",
"pages": {
"order": [
"Side1",
"Side2"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"$schema": "https://altinncdn.no/toolkits/altinn-app-frontend/4/schemas/json/layout/layout.schema.v1.json",
"data": {
"layout": [
{
"target": {
"type": "layoutSet",
"id": "",
"taskId": ""
},
"id": "Summary2-9iG1lB",
"type": "Summary2"
},
{
"target": {
"type": "page",
"id": "Side1",
"taskId": ""
},
"id": "Summary2-R8HsuB",
"type": "Summary2"
},
{
"target": {
"type": "page",
"id": "Side2",
"taskId": ""
},
"id": "Summary2-mL8NjJ",
"type": "Summary2",
"overrides": [
{
"componentId": "Input-Om7N3y-new",
"displayType": "string"
}
]
},
{
"target": {
"type": "component",
"id": "Input-qWr0oa",
"taskId": ""
},
"id": "Summary2-0BV88Q",
"type": "Summary2"
},
{
"target": {
"type": "component",
"id": "Input-Om7N3y-new",
"taskId": ""
},
"id": "Summary2-dTepe0",
"type": "Summary2"
},
{
"id": "NavigationButtons-DfcNol",
"showBackButton": true,
"textResourceBindings": {},
"type": "NavigationButtons"
}
]
}
}
Loading

0 comments on commit fd717a6

Please sign in to comment.