From 33824fcd0d2346fbb3c35b732b283712e70bcfa9 Mon Sep 17 00:00:00 2001 From: Konrad-Simso Date: Thu, 27 Feb 2025 13:22:07 +0100 Subject: [PATCH 1/2] Initial tests for OrgTextsService --- .../Organisation/OrgTextsService.cs | 3 +- .../Services/OrgTextsServiceTests.cs | 230 ++++++++++++++++++ 2 files changed, 231 insertions(+), 2 deletions(-) create mode 100644 backend/tests/Designer.Tests/Services/OrgTextsServiceTests.cs diff --git a/backend/src/Designer/Services/Implementation/Organisation/OrgTextsService.cs b/backend/src/Designer/Services/Implementation/Organisation/OrgTextsService.cs index 6cf1e5de520..9fe731442ae 100644 --- a/backend/src/Designer/Services/Implementation/Organisation/OrgTextsService.cs +++ b/backend/src/Designer/Services/Implementation/Organisation/OrgTextsService.cs @@ -13,7 +13,6 @@ namespace Altinn.Studio.Designer.Services.Implementation.Organisation; public class OrgTextsService : IOrgTextsService { private readonly IAltinnGitRepositoryFactory _altinnGitRepositoryFactory; - private const string Repo = "content"; /// /// Constructor @@ -91,6 +90,6 @@ public async Task UpdateTextsForKeys(string org, string developer, Dictionary(async () => await service.GetText(TargetOrg, Developer, lang)); + } + + [Theory] + [InlineData("org-content-empty", "nb")] + public async Task SaveText_ShouldCreateTextFile(string repo, string lang) + { + // Arrange + TargetOrg = TestDataHelper.GenerateTestOrgName(); + string targetRepo = TestDataHelper.GetOrgContentRepoName(TargetOrg); + await TestDataHelper.CopyOrgForTest(Developer, Org, repo, TargetOrg, targetRepo); + var service = GetOrgTextsService(); + + List newResourceElements = [new() { Id = "newId", Value = "newValue" }]; + TextResource newTextResource = new() { Language = lang, Resources = newResourceElements }; + + // Act + await service.SaveText(TargetOrg, Developer, newTextResource, lang); + + // Assert + string actualContent = TestDataHelper.GetFileFromRepo(TargetOrg, targetRepo, Developer, RelativePath(lang)); + TextResource actualResource = JsonSerializer.Deserialize(actualContent, _jsonOptions); + Assert.Equal(newTextResource.Resources[0].Id, actualResource.Resources[0].Id); + Assert.Equal(newTextResource.Resources[0].Value, actualResource.Resources[0].Value); + } + + [Theory] + [InlineData("org-content", "nb")] + public async Task UpdateTextsForKeys_ShouldUpdateExistingId(string repo, string lang) + { + // Arrange + TargetOrg = TestDataHelper.GenerateTestOrgName(); + string targetRepo = TestDataHelper.GetOrgContentRepoName(TargetOrg); + await TestDataHelper.CopyOrgForTest(Developer, Org, repo, TargetOrg, targetRepo); + var service = GetOrgTextsService(); + + const string editedValue = "edited value!"; + const string editedId = "someId"; + Dictionary newTextIds = new() + { + { editedId, editedValue }, + }; + TextResource expectedTextResources = GetInitialTextResources(); + expectedTextResources.Resources.Find(e => e.Id == editedId).Value = editedValue; + + // Act + await service.UpdateTextsForKeys(TargetOrg, Developer, newTextIds, lang); + + // Assert + string actualContent = TestDataHelper.GetFileFromRepo(TargetOrg, targetRepo, Developer, RelativePath(lang)); + TextResource actualResource = JsonSerializer.Deserialize(actualContent, _jsonOptions); + for (int i = 0; i < actualResource.Resources.Count; i++) + { + Assert.Equal(expectedTextResources.Resources[i].Id, actualResource.Resources[i].Id); + Assert.Equal(expectedTextResources.Resources[i].Value, actualResource.Resources[i].Value); + } + } + + [Theory] + [InlineData("org-content", "nb")] + public async Task UpdateTextsForKeys_ShouldCreateNewIdWhenTextResourceDoesNotExit(string repo, string lang) + { + // Arrange + TargetOrg = TestDataHelper.GenerateTestOrgName(); + string targetRepo = TestDataHelper.GetOrgContentRepoName(TargetOrg); + await TestDataHelper.CopyOrgForTest(Developer, Org, repo, TargetOrg, targetRepo); + var service = GetOrgTextsService(); + + const string newId = "someNewId"; + const string newValue = "someNewValue"; + Dictionary newTextIds = new() + { + { newId, newValue }, + }; + TextResource expectedTextResources = GetInitialTextResources(); + TextResourceElement expectedResourceElement = new() { Id = newId, Value = newValue }; + expectedTextResources.Resources.Add(expectedResourceElement); + + // Act + await service.UpdateTextsForKeys(TargetOrg, Developer, newTextIds, lang); + + // Assert + string actualContent = TestDataHelper.GetFileFromRepo(TargetOrg, targetRepo, Developer, RelativePath(lang)); + TextResource actualResource = JsonSerializer.Deserialize(actualContent, _jsonOptions); + TextResourceElement newResourceElement = actualResource.Resources.Find(e => e.Id == newId); + Assert.Equal(expectedResourceElement.Id, newResourceElement.Id); + Assert.Equal(expectedResourceElement.Value, newResourceElement.Value); + } + + [Theory] + [InlineData("org-content", "nb")] + public async Task UpdateTextsForKeys_ShouldUpdateTextWithVariables(string repo, string lang) + { + // Arrange + TargetOrg = TestDataHelper.GenerateTestOrgName(); + string targetRepo = TestDataHelper.GetOrgContentRepoName(TargetOrg); + await TestDataHelper.CopyOrgForTest(Developer, Org, repo, TargetOrg, targetRepo); + var service = GetOrgTextsService(); + + const string idOfItemToUpdate = "TextUsingVariables"; + const string newValue = "some value with variables number 1 '{0}' and 2 '{1}'"; + Dictionary newTextIds = new() + { + { idOfItemToUpdate, newValue }, + }; + TextResource expectedTextResources = GetInitialTextResources(); + expectedTextResources.Resources.Find(e => e.Id == idOfItemToUpdate).Value = newValue; + TextResourceElement expectedResourceElement = expectedTextResources.Resources.Find(e => e.Id == idOfItemToUpdate); + + // Act + await service.UpdateTextsForKeys(TargetOrg, Developer, newTextIds, lang); + + // Assert + string actualContent = TestDataHelper.GetFileFromRepo(TargetOrg, targetRepo, Developer, RelativePath(lang)); + TextResource actualResource = JsonSerializer.Deserialize(actualContent, _jsonOptions); + TextResourceElement newResourceElement = actualResource.Resources.Find(e => e.Id == idOfItemToUpdate); + Assert.Equal(expectedResourceElement.Id, newResourceElement.Id); + Assert.Equal(expectedResourceElement.Value, newResourceElement.Value); + Assert.Equal(expectedResourceElement.Variables.Count, newResourceElement.Variables.Count); + } + + [Theory] + [InlineData("org-content", "sr")] + public async Task UpdateTextsForKeys_ShouldThrowExceptionWhenLanguageDoesNotExist(string repo, string lang) + { + // Arrange + TargetOrg = TestDataHelper.GenerateTestOrgName(); + string targetRepo = TestDataHelper.GetOrgContentRepoName(TargetOrg); + await TestDataHelper.CopyOrgForTest(Developer, Org, repo, TargetOrg, targetRepo); + var service = GetOrgTextsService(); + + Dictionary newTextIds = new() + { + { "someNewId", "someNewValue" }, + }; + + // Act and assert + await Assert.ThrowsAsync(async () => await service.UpdateTextsForKeys(TargetOrg, Developer, newTextIds, lang)); + } + + private static OrgTextsService GetOrgTextsService() + { + AltinnGitRepositoryFactory altinnGitRepositoryFactory = + new(TestDataHelper.GetTestDataRepositoriesRootDirectory()); + OrgTextsService service = new(altinnGitRepositoryFactory); + + return service; + } + + private static string RelativePath(string language) => $"Texts/resource.{language}.json"; + + public void Dispose() + { + if (!string.IsNullOrEmpty(TargetOrg)) + { + TestDataHelper.DeleteOrgDirectory(Developer, TargetOrg); + } + } + + private static TextResource GetInitialTextResources(string language = "nb") + { + string fileContents = TestDataHelper.GetFileFromRepo(Org, "org-content", Developer, RelativePath(language)); + return JsonSerializer.Deserialize(fileContents, _jsonOptions); + } + + private static readonly JsonSerializerOptions _jsonOptions = new() + { + WriteIndented = true, + Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + PropertyNameCaseInsensitive = true + }; +} From 76e30e4510f2cd41e9ddcb94eee74380063447b0 Mon Sep 17 00:00:00 2001 From: Konrad-Simso Date: Thu, 27 Feb 2025 13:28:39 +0100 Subject: [PATCH 2/2] Refactor, reorder functions. --- .../Services/OrgTextsServiceTests.cs | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/backend/tests/Designer.Tests/Services/OrgTextsServiceTests.cs b/backend/tests/Designer.Tests/Services/OrgTextsServiceTests.cs index 4584d021c22..88c392f62d9 100644 --- a/backend/tests/Designer.Tests/Services/OrgTextsServiceTests.cs +++ b/backend/tests/Designer.Tests/Services/OrgTextsServiceTests.cs @@ -194,6 +194,21 @@ public async Task UpdateTextsForKeys_ShouldThrowExceptionWhenLanguageDoesNotExis await Assert.ThrowsAsync(async () => await service.UpdateTextsForKeys(TargetOrg, Developer, newTextIds, lang)); } + private static TextResource GetInitialTextResources(string language = "nb") + { + string fileContents = TestDataHelper.GetFileFromRepo(Org, "org-content", Developer, RelativePath(language)); + return JsonSerializer.Deserialize(fileContents, _jsonOptions); + } + + private static readonly JsonSerializerOptions _jsonOptions = new() + { + WriteIndented = true, + Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + PropertyNameCaseInsensitive = true + }; + private static OrgTextsService GetOrgTextsService() { AltinnGitRepositoryFactory altinnGitRepositoryFactory = @@ -212,19 +227,4 @@ public void Dispose() TestDataHelper.DeleteOrgDirectory(Developer, TargetOrg); } } - - private static TextResource GetInitialTextResources(string language = "nb") - { - string fileContents = TestDataHelper.GetFileFromRepo(Org, "org-content", Developer, RelativePath(language)); - return JsonSerializer.Deserialize(fileContents, _jsonOptions); - } - - private static readonly JsonSerializerOptions _jsonOptions = new() - { - WriteIndented = true, - Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping, - DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, - PropertyNamingPolicy = JsonNamingPolicy.CamelCase, - PropertyNameCaseInsensitive = true - }; }