Skip to content

Commit

Permalink
Merge branch 'master' into codecov-v4
Browse files Browse the repository at this point in the history
  • Loading branch information
jmgrady authored Apr 10, 2024
2 parents 326a96c + 94f89f9 commit ce06efe
Show file tree
Hide file tree
Showing 219 changed files with 3,273 additions and 1,243 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/backend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:
run: dotnet test Backend.Tests/Backend.Tests.csproj
shell: bash
- name: Upload coverage artifact
uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
with:
if-no-files-found: error
name: coverage
Expand Down Expand Up @@ -86,7 +86,7 @@ jobs:
- name: Checkout repository
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Download coverage artifact
uses: actions/download-artifact@87c55149d96e628cc2ef7e6fc2aab372015aec85 # v4.1.3
uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4
with:
name: coverage
- name: Upload coverage report
Expand Down Expand Up @@ -138,7 +138,7 @@ jobs:
- name: Autobuild
uses: github/codeql-action/autobuild@8a470fddafa5cbb6266ee11b37ef4d8aae19c571 # v3.24.6
- name: Upload artifacts if build failed
uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
if: ${{ failure() }}
with:
name: tracer-logs
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/combine_deploy_image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
- name: Set up QEMU
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@0d103c3126aa41d772a8362f6aa67afac040f80c # v3.1.0
uses: docker/setup-buildx-action@2b51285047da1547ffb1b2203d8be4c0af6b1f20 # v3.2.0
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@010d0da01d0b5a38af31e9c3470dbfdabdecca3a # v4.0.1
with:
Expand All @@ -54,7 +54,7 @@ jobs:
username: ${{ secrets.AWS_ACCESS_KEY_ID }}
password: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- name: Build combine_deploy
uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0
uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0
with:
context: "{{defaultContext}}:deploy"
push: true
Expand Down
13 changes: 13 additions & 0 deletions .github/workflows/commit_message_check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: commit-message-lint

on:
pull_request:
branches: [master]

permissions: # added using https://github.com/step-security/secure-workflows
contents: read
pull-requests: write

jobs:
commit-message-lint:
uses: sillsdev/FieldWorks/.github/workflows/CommitMessage.yml@3a4f3bade83de0228b80c3662faadb651b2ff110
4 changes: 2 additions & 2 deletions .github/workflows/frontend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ jobs:
env:
CI: true
- name: Upload coverage artifact
uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
with:
if-no-files-found: error
name: coverage
Expand Down Expand Up @@ -96,7 +96,7 @@ jobs:
- name: Checkout repository
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Download coverage artifact
uses: actions/download-artifact@87c55149d96e628cc2ef7e6fc2aab372015aec85 # v4.1.3
uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4
with:
name: coverage
- name: Upload coverage report
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/scorecards.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
with:
name: SARIF file
path: results.sarif
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ src/resources/dictionaries/*.txt
deploy/scripts/semantic_domains/json/*.json
database/semantic_domains/*

# Combine installer
installer/combine-installer.run
installer/makeself-*
installer/README.pdf

# Kubernetes Configuration files
**/site_files/
**/charts/*.tgz
Expand Down
6 changes: 3 additions & 3 deletions Backend.Tests/Backend.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="NUnit" Version="4.0.1" />
<PackageReference Include="NUnit" Version="4.1.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
<PackageReference Include="coverlet.collector" Version="6.0.1"/>
<PackageReference Include="coverlet.msbuild" Version="6.0.1"/>
<PackageReference Include="coverlet.collector" Version="6.0.2"/>
<PackageReference Include="coverlet.msbuild" Version="6.0.2"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Backend\BackendFramework.csproj" />
Expand Down
18 changes: 18 additions & 0 deletions Backend.Tests/Controllers/SemanticDomainControllerTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using Backend.Tests.Mocks;
using BackendFramework.Controllers;
using BackendFramework.Interfaces;
Expand Down Expand Up @@ -39,6 +40,23 @@ public void Setup()
_semDomController = new SemanticDomainController(_semDomRepository);
}

[Test]
public void GetAllSemanticDomainNamesFound()
{
var treeNodes = new List<SemanticDomainTreeNode> { new(_semDom) };
((SemanticDomainRepositoryMock)_semDomRepository).SetNextResponse(treeNodes);
var names = ((OkObjectResult)_semDomController.GetAllSemanticDomainNames(Lang).Result).Value;
Assert.That(names, Has.Count.EqualTo(1));
Assert.That(((Dictionary<string, string>)names!)[Id], Is.EqualTo(Name));
}

[Test]
public void GetAllSemanticDomainNamesNotFound()
{
var names = ((OkObjectResult)_semDomController.GetAllSemanticDomainNames(Lang).Result).Value;
Assert.That(names, Has.Count.EqualTo(0));
}

[Test]
public void GetSemanticDomainFullDomainFound()
{
Expand Down
71 changes: 71 additions & 0 deletions Backend.Tests/Controllers/WordControllerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,34 @@ public void Setup()
_projId = _projRepo.Create(new Project { Name = "WordControllerTests" }).Result!.Id;
}

[Test]
public async Task TestAreInFrontier()
{
var wordNotInFrontier = await _wordRepo.Add(Util.RandomWord(_projId));
var emptyResult = await _wordController.AreInFrontier(_projId, new() { wordNotInFrontier.Id, "non-id" });
Assert.That(((ObjectResult)emptyResult).Value, Is.Empty);

var wordInFrontier = await _wordRepo.AddFrontier(Util.RandomWord(_projId));
var nonemptyResult = await _wordController.AreInFrontier(_projId, new() { wordInFrontier.Id, "non-id" });
Assert.That(((OkObjectResult)nonemptyResult).Value, Is.EqualTo(new List<string> { wordInFrontier.Id }));
}

[Test]
public async Task TestAreInFrontierNoPermission()
{
var wordInFrontier = await _wordRepo.AddFrontier(Util.RandomWord(_projId));
_wordController.ControllerContext.HttpContext = PermissionServiceMock.UnauthorizedHttpContext();
var result = await _wordController.AreInFrontier(_projId, new() { wordInFrontier.Id });
Assert.That(result, Is.InstanceOf<ForbidResult>());
}

[Test]
public async Task TestAreInFrontierMissingProject()
{
var result = await _wordController.AreInFrontier(MissingId, new());
Assert.That(result, Is.InstanceOf<NotFoundObjectResult>());
}

[Test]
public async Task TestDeleteFrontierWord()
{
Expand Down Expand Up @@ -266,6 +294,49 @@ public async Task TestGetDuplicateIdMissingProject()
Assert.That(result, Is.InstanceOf<NotFoundObjectResult>());
}

[Test]
public async Task TestRevertWords()
{
var frontierWord0 = await _wordRepo.Create(Util.RandomWord(_projId));
var frontierWord1 = await _wordRepo.AddFrontier(Util.RandomWord(_projId));
var nonFrontierWord0 = await _wordRepo.Add(Util.RandomWord(_projId));
var nonFrontierWord1 = await _wordRepo.Add(Util.RandomWord(_projId));
var nonFrontierWord2 = await _wordRepo.Add(Util.RandomWord(_projId));

var result = await _wordController.RevertWords(_projId, new()
{
["non-id"] = frontierWord1.Id, // Cannot revert with key not a word
[nonFrontierWord1.Id] = nonFrontierWord2.Id, // Cannot revert with value not in frontier
[nonFrontierWord0.Id] = frontierWord0.Id, // Can revert
});
var reverted = (Dictionary<string, string>)((OkObjectResult)result).Value!;
Assert.That(reverted, Has.Count.EqualTo(1));
var frontierIds = (await _wordRepo.GetFrontier(_projId)).Select(w => w.Id).ToList();
Assert.That(frontierIds, Has.Count.EqualTo(2));
Assert.That(frontierIds, Does.Contain(frontierWord1.Id));
Assert.That(frontierIds, Does.Contain(reverted[frontierWord0.Id]));
}

[Test]
public async Task TestRevertWordsNoPermission()
{
_wordController.ControllerContext.HttpContext = PermissionServiceMock.UnauthorizedHttpContext();

var oldWord = await _wordRepo.Add(Util.RandomWord(_projId));
var newWord = await _wordRepo.Create(Util.RandomWord(_projId));
var result = await _wordController.RevertWords(_projId, new() { [oldWord.Id] = newWord.Id });
Assert.That(result, Is.InstanceOf<ForbidResult>());
}

[Test]
public async Task TestRevertWordsMissingProject()
{
var oldWord = await _wordRepo.Add(Util.RandomWord(_projId));
var newWord = await _wordRepo.Create(Util.RandomWord(_projId));
var result = await _wordController.RevertWords(MissingId, new() { [oldWord.Id] = newWord.Id });
Assert.That(result, Is.InstanceOf<NotFoundObjectResult>());
}

[Test]
public async Task TestUpdateDuplicate()
{
Expand Down
18 changes: 1 addition & 17 deletions Backend.Tests/Mocks/SemanticDomainRepositoryMock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,10 @@ namespace Backend.Tests.Mocks
public class SemanticDomainRepositoryMock : ISemanticDomainRepository
{
private object? _responseObj;
private List<string>? _validLangs;

public Task<List<SemanticDomainTreeNode>?> GetAllSemanticDomainTreeNodes(string lang)
{
if (_validLangs is null)
{
return Task.FromResult((List<SemanticDomainTreeNode>?)_responseObj);
}

List<SemanticDomainTreeNode>? semDoms = null;
if (_validLangs.Contains(lang))
{
semDoms = new() { new(new SemanticDomain { Lang = lang }) };
}
return Task.FromResult(semDoms);
return Task.FromResult((List<SemanticDomainTreeNode>?)_responseObj);
}

public Task<SemanticDomainFull?> GetSemanticDomainFull(string id, string lang)
Expand All @@ -44,10 +33,5 @@ internal void SetNextResponse(object? response)
{
_responseObj = response;
}

internal void SetValidLangs(List<string>? validLangs)
{
_validLangs = validLangs;
}
}
}
32 changes: 0 additions & 32 deletions Backend.Tests/Services/LiftServiceTests.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
using System.Collections.Generic;
using System.IO;
using Backend.Tests.Mocks;
using BackendFramework.Interfaces;
using BackendFramework.Models;
using BackendFramework.Services;
using NUnit.Framework;

Expand Down Expand Up @@ -64,34 +61,5 @@ public void StoreRetrieveDeleteImportTest()
Assert.That(_liftService.DeleteImport(UserId), Is.True);
Assert.That(_liftService.RetrieveImport(UserId), Is.Null);
}

[Test]
public void CreateLiftRangesTest()
{
List<SemanticDomain> frDoms = new() { new() { Lang = "fr" }, new() };
List<SemanticDomain> ptDoms = new() { new(), new() { Lang = "pt" } };
List<SemanticDomain> zzDoms = new() { new() { Lang = "zz" } };
List<Word> projWords = new()
{
// First semantic domain of the second sense of a word
new() { Senses = new() { new(), new() { SemanticDomains = frDoms } } },
// Second semantic domain of the first sense of a word
new() { Senses = new() { new() { SemanticDomains = ptDoms }, new() } },
// Semantic domain with unsupported language
new() { Senses = new() { new() { SemanticDomains = zzDoms } } }
};

((SemanticDomainRepositoryMock)_semDomRepo).SetValidLangs(new() { "en", "fr", "pt" });
var langs = _liftService.CreateLiftRanges(projWords, new(), FileName).Result;
Assert.That(langs, Has.Count.EqualTo(2));
Assert.That(langs, Does.Contain("fr"));
Assert.That(langs, Does.Contain("pt"));

var liftRangesText = File.ReadAllText(FileName);
Assert.That(liftRangesText, Does.Not.Contain("\"en\""));
Assert.That(liftRangesText, Does.Contain("\"fr\""));
Assert.That(liftRangesText, Does.Contain("\"pt\""));
Assert.That(liftRangesText, Does.Not.Contain("\"zz\""));
}
}
}
4 changes: 2 additions & 2 deletions Backend/BackendFramework.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@
<PackageReference Include="RelaxNG" Version="3.2.3" >
<NoWarn>NU1701</NoWarn>
</PackageReference>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.27" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.28" />
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="6.35.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.35.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="MongoDB.Driver" Version="2.24.0" />
<PackageReference Include="MailKit" Version="4.3.0" />
<PackageReference Include="MailKit" Version="4.4.0" />
<PackageReference Include="Xabe.FFmpeg" Version="5.2.6"/>

<!-- SIL Maintained Dependencies. -->
Expand Down
15 changes: 15 additions & 0 deletions Backend/Controllers/SemanticDomainController.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using BackendFramework.Interfaces;
using BackendFramework.Models;
Expand All @@ -19,6 +21,19 @@ public SemanticDomainController(ISemanticDomainRepository semDomRepo)
_semDomRepo = semDomRepo;
}

/// <summary>
/// Returns a dictionary mapping domain ids to names in the specified language (fallback: "en").
/// </summary>
[HttpGet("allDomainNames", Name = "GetAllSemanticDomainNames")]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(Dictionary<string, string>))]
public async Task<IActionResult> GetAllSemanticDomainNames(string lang)
{
var semDoms = await _semDomRepo.GetAllSemanticDomainTreeNodes(lang)
?? await _semDomRepo.GetAllSemanticDomainTreeNodes("en")
?? new();
return Ok(semDoms.ToDictionary(x => x.Id, x => x.Name));
}

/// <summary> Returns <see cref="SemanticDomainFull"/> with specified id and in specified language </summary>
[HttpGet("domainFull", Name = "GetSemanticDomainFull")]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(SemanticDomainFull))]
Expand Down
Loading

0 comments on commit ce06efe

Please sign in to comment.