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

Validate WritingSystemIds on creation #1230

Merged
merged 13 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from 6 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
@@ -1,4 +1,4 @@
using MiniLcm.Models;
using MiniLcm.Models;
using Soenneker.Utils.AutoBogus.Context;
using Soenneker.Utils.AutoBogus.Override;

Expand All @@ -16,7 +16,8 @@ public override void Generate(AutoFakerOverrideContext context)
var wordsArray = context.Faker.Random.WordsArray(1, 4);
foreach (var word in wordsArray)
{
target[context.Faker.Random.String(2, 'a', 'z')] = word;
var ws = context.Faker.Random.ArrayElement(MiniLcm.Tests.WritingSystemCodes.ValidTwoLetterCodes);
target[ws] = word;
}
}
}
6 changes: 5 additions & 1 deletion backend/FwLite/LcmCrdt.Tests/DataModelSnapshotTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using SIL.Harmony.Changes;
using SIL.Harmony.Entities;
using Soenneker.Utils.AutoBogus;
using Soenneker.Utils.AutoBogus.Config;

namespace LcmCrdt.Tests;

Expand Down Expand Up @@ -76,7 +77,10 @@ public async Task VerifyIObjectWithIdModels()
[Fact]
public void VerifyIObjectWithIdsMatchAdapterGetObjectTypeName()
{
var faker = new AutoFaker();
var faker = new AutoFaker(new AutoFakerConfig()
{
Overrides = [new MultiStringOverride()]
});
var jsonSerializerOptions = _crdtConfig.JsonSerializerOptions;
var types = jsonSerializerOptions.GetTypeInfo(typeof(IObjectWithId)).PolymorphismOptions?.DerivedTypes ?? [];
using (new AssertionScope())
Expand Down
6 changes: 5 additions & 1 deletion backend/FwLite/LcmCrdt.Tests/EntityCopyMethodTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ namespace LcmCrdt.Tests;

public class EntityCopyMethodTests
{
private readonly AutoFaker _autoFaker = new(new AutoFakerConfig());
private readonly AutoFaker _autoFaker = new(new AutoFakerConfig()
{
Overrides = [new MultiStringOverride()]
});

public static IEnumerable<object[]> GetEntityTypes()
{
var crdtConfig = new CrdtConfig();
Expand Down
5 changes: 3 additions & 2 deletions backend/FwLite/LcmCrdt.Tests/MultiStringOverride.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using MiniLcm.Models;
using MiniLcm.Models;
using Soenneker.Utils.AutoBogus.Context;
using Soenneker.Utils.AutoBogus.Override;

Expand All @@ -16,7 +16,8 @@ public override void Generate(AutoFakerOverrideContext context)
var wordsArray = context.Faker.Random.WordsArray(1, 4);
foreach (var word in wordsArray)
{
target[context.Faker.Random.String(2, 'a', 'z')] = word;
var ws = context.Faker.Random.ArrayElement(WritingSystemCodes.ValidTwoLetterCodes);
target[ws] = word;
}
}
}
190 changes: 190 additions & 0 deletions backend/FwLite/MiniLcm.Tests/WritingSystemCodes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
namespace MiniLcm.Tests;

public static class WritingSystemCodes
{
public static string[] ValidTwoLetterCodes = [
hahn-kev marked this conversation as resolved.
Show resolved Hide resolved
"aa",
"ab",
"ae",
"af",
"ak",
"am",
"an",
"ar",
"as",
"av",
"ay",
"az",
"ba",
"be",
"bg",
"bi",
"bm",
"bn",
"bo",
"br",
"bs",
"ca",
"ce",
"ch",
"co",
"cr",
"cs",
"cu",
"cv",
"cy",
"da",
"de",
"dv",
"dz",
"ee",
"el",
"en",
"eo",
"es",
"et",
"eu",
"fa",
"ff",
"fi",
"fj",
"fo",
"fr",
"fy",
"ga",
"gd",
"gl",
"gn",
"gu",
"gv",
"ha",
"he",
"hi",
"ho",
"hr",
"ht",
"hu",
"hy",
"hz",
"{{",
"id",
"ie",
"ig",
"ii",
"ik",
"io",
"is",
"it",
"iu",
"ja",
"jv",
"ka",
"kg",
"ki",
"kj",
"kk",
"kl",
"km",
"kn",
"ko",
"kr",
"ks",
"ku",
"kv",
"kw",
"ky",
"la",
"lb",
"lg",
"li",
"ln",
"lo",
"lt",
"lu",
"lv",
"mg",
"mh",
"#m",
"mk",
"ml",
"mn",
"mr",
"ms",
"mt",
"my",
"na",
"#n",
"nd",
"ne",
"ng",
"nl",
"nn",
"no",
"nr",
"nv",
"ny",
"oc",
"oj",
"om",
"or",
"os",
"pa",
"pi",
"pl",
"ps",
"pt",
"qu",
"rm",
"rn",
"ro",
"ru",
"rw",
"sa",
"sc",
"sd",
"se",
"sg",
"si",
"sk",
"sl",
"sm",
"sn",
"so",
"sq",
"sr",
"ss",
"st",
"su",
"sv",
"sw",
"ta",
"te",
"tg",
"th",
"ti",
"tk",
"tl",
"tn",
"to",
"tr",
"ts",
"tt",
"tw",
"ty",
"ug",
"uk",
"ur",
"uz",
"ve",
"vi",
"#v",
"wa",
"wo",
"xh",
"yi",
"yo",
"za",
"zh",
"zu",
];
}
28 changes: 28 additions & 0 deletions backend/FwLite/MiniLcm.Tests/WritingSystemTestsBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,32 @@ public async Task GetWritingSystems_ReturnsExemplars()
var writingSystems = await Api.GetWritingSystems();
writingSystems.Vernacular.Should().Contain(ws => ws.Exemplars.Any());
}

[Theory]
[InlineData("en")]
[InlineData("th")]
[InlineData("en-Zxxx-x-audio")]
public void ValidWritingSystemId_ShouldNotThrow(string code)
{
var ws = new WritingSystemId(code);
ws.Should().NotBeNull();
}

[Theory]
[InlineData("gx")]
[InlineData("oo")]
[InlineData("eng")] // Three-letter codes not allowed when there's a valid two-letter code
[InlineData("eng-Zxxx-x-audio")]
[InlineData("nonsense")]
public void InvalidWritingSystemId_ShouldThrow(string code)
{
Assert.Throws<ArgumentException>(() => new WritingSystemId(code));
}

[Fact]
public void DefaultWritingSystemId_IsValid()
{
var ws = new WritingSystemId("default");
ws.Should().NotBeNull();
}
}
1 change: 1 addition & 0 deletions backend/FwLite/MiniLcm/MiniLcm.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="SIL.WritingSystems" Version="14.2.0-beta*" />
<PackageReference Include="System.Text.Json" Version="8.0.5" />
<PackageReference Include="SystemTextJsonPatch" Version="3.2.1" />
</ItemGroup>
Expand Down
18 changes: 17 additions & 1 deletion backend/FwLite/MiniLcm/Models/WritingSystemId.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using SIL.WritingSystems;

namespace MiniLcm.Models;

Expand All @@ -26,11 +27,26 @@ public override void WriteAsPropertyName(Utf8JsonWriter writer, WritingSystemId
}

[JsonConverter(typeof(WritingSystemIdJsonConverter))]
public readonly record struct WritingSystemId(string Code): ISpanFormattable, ISpanParsable<WritingSystemId>
public readonly record struct WritingSystemId: ISpanFormattable, ISpanParsable<WritingSystemId>
{
public string Code { get; init; }

public WritingSystemId(string code)
{
if (code == "default" || IetfLanguageTag.IsValid(code))
{
Code = code;
}
else
{
throw new ArgumentException($"Invalid writing system ID {code}", nameof(code));
}
}

public static implicit operator string(WritingSystemId ws) => ws.Code;
public static implicit operator WritingSystemId(string code) => new(code);
public static implicit operator WritingSystemId(ReadOnlySpan<char> code) => new(new string(code));

public override string ToString()
{
return Code;
Expand Down
Loading