Skip to content
Merged
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
26 changes: 14 additions & 12 deletions backend/FwLite/LcmCrdt/Data/MiniLcmRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,20 @@ public async IAsyncEnumerable<Entry> GetEntries(
string? query,
FilterQueryOptions options)
{
if (options.Exemplar is not null)
{
var ws = (await GetWritingSystem(options.Exemplar.WritingSystem, WritingSystemType.Vernacular))?.WsId;
if (ws is null)
throw new NullReferenceException($"writing system {options.Exemplar.WritingSystem} not found");
queryable = queryable.WhereExemplar(ws.Value, options.Exemplar.Value);
}

if (options.Filter?.GridifyFilter != null)
{
// Do this BEFORE doing the FTS, which returns an expression that confuses the gridify query
queryable = queryable.ApplyFiltering(options.Filter.GridifyFilter, config.Value.Mapper);
}

bool sortingHandled = false;
if (!string.IsNullOrEmpty(query))
{
Expand All @@ -176,18 +190,6 @@ public async IAsyncEnumerable<Entry> GetEntries(
}
}

if (options.Exemplar is not null)
{
var ws = (await GetWritingSystem(options.Exemplar.WritingSystem, WritingSystemType.Vernacular))?.WsId;
if (ws is null)
throw new NullReferenceException($"writing system {options.Exemplar.WritingSystem} not found");
queryable = queryable.WhereExemplar(ws.Value, options.Exemplar.Value);
}

if (options.Filter?.GridifyFilter != null)
{
queryable = queryable.ApplyFiltering(options.Filter.GridifyFilter, config.Value.Mapper);
}
return (queryable, sortingHandled);
}

Expand Down
73 changes: 73 additions & 0 deletions backend/FwLite/MiniLcm.Tests/QueryEntryTestsBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,27 @@ public async Task CanFilterToMissingSenses()
results.Select(e => e.LexemeForm["en"]).Distinct().Should().BeEquivalentTo(Apple, Null_LexemeForm);
}

[Fact]
public async Task CanFilterToMissingSenses_AndSearch()
{
var results = await Api.SearchEntries(Apple, new(Filter: new() { GridifyFilter = "Senses=null" })).ToArrayAsync();
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Apple);
}

[Fact]
public async Task CanFilterToNotMissingSenses()
{
var results = await Api.GetEntries(new(Filter: new() { GridifyFilter = "Senses!=null" })).ToArrayAsync();
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Kiwi, Peach, Banana);
}

[Fact]
public async Task CanFilterToNotMissingSenses_AndSearch()
{
var results = await Api.SearchEntries(Banana, new(Filter: new() { GridifyFilter = "Senses!=null" })).ToArrayAsync();
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Banana);
}

[Fact]
public async Task CanFilterToMissingPartOfSpeech()
{
Expand All @@ -115,6 +129,14 @@ public async Task CanFilterToMissingPartOfSpeech()
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Peach);
}

[Fact]
public async Task CanFilterToMissingPartOfSpeech_AndSearch()
{
var results = await Api.SearchEntries(Peach, new(Filter: new() { GridifyFilter = "Senses.PartOfSpeechId=" })).ToArrayAsync();
//does not include entries with no senses
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Peach);
}

[Fact]
public async Task CanFilterToMissingExamples()
{
Expand All @@ -124,13 +146,29 @@ public async Task CanFilterToMissingExamples()
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Peach, Banana);
}

[Fact]
public async Task CanFilterToMissingExamples_AndSearch()
{
var results = await Api.SearchEntries(Banana, new(Filter: new() { GridifyFilter = "Senses.ExampleSentences=null" })).ToArrayAsync();
//Senses.ExampleSentences=null matches entries which have senses but no examples
//it does not include Apple because it has no senses, to include it a filter Senses=null is needed
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Banana);
}

[Fact]
public async Task CanFilterToMissingSemanticDomains()
{
var results = await Api.GetEntries(new(Filter: new() { GridifyFilter = "Senses.SemanticDomains=null" })).ToArrayAsync();
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Peach);
}

[Fact]
public async Task CanFilterToMissingSemanticDomains_AndSearch()
{
var results = await Api.SearchEntries(Peach, new(Filter: new() { GridifyFilter = "Senses.SemanticDomains=null" })).ToArrayAsync();
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Peach);
}

[Fact]
public async Task CanFilterToMissingSemanticDomainsWithEmptyArray()
{
Expand All @@ -153,6 +191,13 @@ public async Task CanFilterToMissingComplexFormTypes()
results.Select(e => e.LexemeForm["en"]).Distinct().Should().BeEquivalentTo(Apple, Banana, Kiwi, Null_LexemeForm);
}

[Fact]
public async Task CanFilterToMissingComplexFormTypes_AndSearch()
{
var results = await Api.SearchEntries(Banana, new(Filter: new() { GridifyFilter = "ComplexFormTypes=null" })).ToArrayAsync();
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Banana);
}

[Fact]
public async Task CanFilterToMissingComplexFormTypesWithEmptyArray()
{
Expand Down Expand Up @@ -189,6 +234,13 @@ public async Task CanFilterLexemeFormContains()
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Banana);
}

[Fact]
public async Task CanFilterLexemeFormContains_AndSearch()
{
var results = await Api.SearchEntries(Banana, new(Filter: new() { GridifyFilter = "LexemeForm[en]=*nan" })).ToArrayAsync();
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Banana);
}

[Fact]
public async Task CanFilterGlossNull()
{
Expand All @@ -205,13 +257,27 @@ public async Task CanFilterGlossEmptyOrNull()
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Peach);
}

[Fact]
public async Task CanFilterGlossEmptyOrNull_AndSearch()
{
var results = await Api.SearchEntries(Peach, new(Filter: new() { GridifyFilter = "Senses.Gloss[en]=" })).ToArrayAsync();
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Peach);
}

[Fact]
public async Task CanFilterGlossEqualsFruit()
{
var results = await Api.GetEntries(new(Filter: new() { GridifyFilter = "Senses.Gloss[en]=Fruit" })).ToArrayAsync();
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Banana, Kiwi);
}

[Fact]
public async Task CanFilterGlossEqualsFruit_AndSearch()
{
var results = await Api.SearchEntries(Banana, new(Filter: new() { GridifyFilter = "Senses.Gloss[en]=Fruit" })).ToArrayAsync();
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Banana);
}

[Fact]
public async Task CanFilterLexemeContainsAAndNoComplexFormTypes()
{
Expand All @@ -226,6 +292,13 @@ public async Task CanFilterExampleSentenceText()
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Banana);
}

[Fact]
public async Task CanFilterExampleSentenceText_AndSearch()
{
var results = await Api.SearchEntries(Banana, new(Filter: new() { GridifyFilter = "Senses.ExampleSentences.Sentence[en]=*phone" })).ToArrayAsync();
results.Select(e => e.LexemeForm["en"]).Should().BeEquivalentTo(Banana);
}

[Fact]
public async Task CanFilterToExampleSentenceWithMissingSentence()
{
Expand Down
Loading