Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: tests for OrgTextsService #14834

Open
wants to merge 2 commits into
base: org-library-mvp
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ namespace Altinn.Studio.Designer.Services.Implementation.Organisation;
public class OrgTextsService : IOrgTextsService
{
private readonly IAltinnGitRepositoryFactory _altinnGitRepositoryFactory;
private const string Repo = "content";

/// <summary>
/// Constructor
Expand Down Expand Up @@ -91,6 +90,6 @@ public async Task UpdateTextsForKeys(string org, string developer, Dictionary<st

private static string GetStaticContentRepo(string org)
{
return $"{org}-{Repo}";
return $"{org}-content";
}
}
230 changes: 230 additions & 0 deletions backend/tests/Designer.Tests/Services/OrgTextsServiceTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Altinn.Studio.Designer.Factories;
using Altinn.Studio.Designer.Models;
using Altinn.Studio.Designer.Services.Implementation.Organisation;
using Designer.Tests.Utils;
using LibGit2Sharp;
using SharedResources.Tests;
using Xunit;
using TextResource = Altinn.Studio.Designer.Models.TextResource;

namespace Designer.Tests.Services;

public class OrgTextsServiceTests : IDisposable
{
private string TargetOrg { get; set; }

private const string Org = "ttd";
private const string Developer = "testUser";

[Theory]
[InlineData("org-content", "nb")]
public async Task GetText_ShouldReturnAllTexts(string repo, string lang)
{
// Arrange
TargetOrg = TestDataHelper.GenerateTestOrgName();
string targetRepo = TestDataHelper.GetOrgContentRepoName(TargetOrg);
await TestDataHelper.CopyOrgForTest(Developer, Org, repo, TargetOrg, targetRepo);
var service = GetOrgTextsService();

TextResource expectedTextResource = GetInitialTextResources();
string expectedTextResourceJson = JsonSerializer.Serialize(expectedTextResource, _jsonOptions);

// Act
TextResource fetchedTexts = await service.GetText(TargetOrg, Developer, lang);

// Assert
Assert.Equal(lang, fetchedTexts.Language);
string actualContent = JsonSerializer.Serialize(fetchedTexts, _jsonOptions);
Assert.True(JsonUtils.DeepEquals(expectedTextResourceJson, actualContent));
}

[Theory]
[InlineData("org-content", "sr")]
public async Task GetText_ShouldReturnNotFoundException_WhenFileDoesNotExist(string repo, string lang)
{
// Arrange
TargetOrg = TestDataHelper.GenerateTestOrgName();
string targetRepo = TestDataHelper.GetOrgContentRepoName(TargetOrg);
await TestDataHelper.CopyOrgForTest(Developer, Org, repo, TargetOrg, targetRepo);
var service = GetOrgTextsService();

// Act and assert
await Assert.ThrowsAsync<NotFoundException>(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<TextResourceElement> 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<TextResource>(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<string, string> 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<TextResource>(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<string, string> 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<TextResource>(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<string, string> 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<TextResource>(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<string, string> newTextIds = new()
{
{ "someNewId", "someNewValue" },
};

// Act and assert
await Assert.ThrowsAsync<NotFoundException>(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<TextResource>(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 =
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);
}
}
}