|
|
|
@ -28,8 +28,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text |
|
|
|
{ |
|
|
|
context = new SearchContext |
|
|
|
{ |
|
|
|
Languages = new HashSet<string> { "de", "en" }, |
|
|
|
IsDraft = true |
|
|
|
Languages = new HashSet<string> { "de", "en" } |
|
|
|
}; |
|
|
|
|
|
|
|
sut = new TextIndexerGrain(assetStore); |
|
|
|
@ -41,10 +40,16 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text |
|
|
|
sut.OnDeactivateAsync().Wait(); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task Should_throw_exception_for_invalid_query() |
|
|
|
{ |
|
|
|
await Assert.ThrowsAsync<ValidationException>(() => sut.SearchAsync("~hello", context)); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task Should_read_index_and_retrieve() |
|
|
|
{ |
|
|
|
await AddInvariantContent(); |
|
|
|
await AddInvariantContent("Hello", "World", false); |
|
|
|
|
|
|
|
await sut.DeactivateAsync(); |
|
|
|
|
|
|
|
@ -53,11 +58,8 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text |
|
|
|
{ |
|
|
|
await other.ActivateAsync(schemaId); |
|
|
|
|
|
|
|
var foundHello = await other.SearchAsync("Hello", context); |
|
|
|
var foundWorld = await other.SearchAsync("World", context); |
|
|
|
|
|
|
|
Assert.Equal(ids1, foundHello); |
|
|
|
Assert.Equal(ids2, foundWorld); |
|
|
|
await TestSearchAsync(ids1, "Hello", grain: other); |
|
|
|
await TestSearchAsync(ids2, "World", grain: other); |
|
|
|
} |
|
|
|
finally |
|
|
|
{ |
|
|
|
@ -68,104 +70,131 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text |
|
|
|
[Fact] |
|
|
|
public async Task Should_index_invariant_content_and_retrieve() |
|
|
|
{ |
|
|
|
await AddInvariantContent(); |
|
|
|
|
|
|
|
var foundHello = await sut.SearchAsync("Hello", context); |
|
|
|
var foundWorld = await sut.SearchAsync("World", context); |
|
|
|
await AddInvariantContent("Hello", "World", false); |
|
|
|
|
|
|
|
Assert.Equal(ids1, foundHello); |
|
|
|
Assert.Equal(ids2, foundWorld); |
|
|
|
await TestSearchAsync(ids1, "Hello"); |
|
|
|
await TestSearchAsync(ids2, "World"); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task Should_index_invariant_content_and_retrieve_with_fuzzy() |
|
|
|
{ |
|
|
|
await AddInvariantContent(); |
|
|
|
await AddInvariantContent("Hello", "World", false); |
|
|
|
|
|
|
|
var foundHello = await sut.SearchAsync("helo~", context); |
|
|
|
var foundWorld = await sut.SearchAsync("wold~", context); |
|
|
|
|
|
|
|
Assert.Equal(ids1, foundHello); |
|
|
|
Assert.Equal(ids2, foundWorld); |
|
|
|
await TestSearchAsync(ids1, "helo~"); |
|
|
|
await TestSearchAsync(ids2, "wold~"); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task Should_delete_documents_from_index() |
|
|
|
public async Task Should_update_draft_only() |
|
|
|
{ |
|
|
|
await AddInvariantContent(); |
|
|
|
|
|
|
|
await sut.DeleteAsync(ids1[0]); |
|
|
|
await sut.FlushAsync(); |
|
|
|
await AddInvariantContent("Hello", "World", false); |
|
|
|
await AddInvariantContent("Hallo", "Welt", false); |
|
|
|
|
|
|
|
var helloIds = await sut.SearchAsync("Hello", context); |
|
|
|
await TestSearchAsync(null, "Hello", Scope.Draft); |
|
|
|
await TestSearchAsync(null, "Hello", Scope.Published); |
|
|
|
|
|
|
|
var worldIds = await sut.SearchAsync("World", context); |
|
|
|
|
|
|
|
Assert.Empty(helloIds); |
|
|
|
Assert.Equal(ids2, worldIds); |
|
|
|
await TestSearchAsync(ids1, "Hallo", Scope.Draft); |
|
|
|
await TestSearchAsync(null, "Hallo", Scope.Published); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task Should_search_by_field() |
|
|
|
public async Task Should_also_update_published_after_copy() |
|
|
|
{ |
|
|
|
await AddLocalizedContent(); |
|
|
|
await AddInvariantContent("Hello", "World", false); |
|
|
|
|
|
|
|
var emptyGerman = await sut.SearchAsync("de:City", context); |
|
|
|
var emptyEnglish = await sut.SearchAsync("en:Stadt", context); |
|
|
|
await CopyAsync(true); |
|
|
|
|
|
|
|
Assert.Empty(emptyGerman); |
|
|
|
Assert.Empty(emptyEnglish); |
|
|
|
await AddInvariantContent("Hallo", "Welt", false); |
|
|
|
|
|
|
|
await TestSearchAsync(null, "Hello", Scope.Draft); |
|
|
|
await TestSearchAsync(null, "Hello", Scope.Published); |
|
|
|
|
|
|
|
await TestSearchAsync(ids1, "Hallo", Scope.Draft); |
|
|
|
await TestSearchAsync(ids1, "Hallo", Scope.Published); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task Should_index_localized_content_and_retrieve() |
|
|
|
public async Task Should_simulate_content_reversion() |
|
|
|
{ |
|
|
|
await AddLocalizedContent(); |
|
|
|
await AddInvariantContent("Hello", "World", false); |
|
|
|
|
|
|
|
await CopyAsync(true); |
|
|
|
|
|
|
|
await AddInvariantContent("Hallo", "Welt", true); |
|
|
|
|
|
|
|
await TestSearchAsync(null, "Hello", Scope.Draft); |
|
|
|
await TestSearchAsync(ids1, "Hello", Scope.Published); |
|
|
|
|
|
|
|
var german1 = await sut.SearchAsync("Stadt", context); |
|
|
|
var german2 = await sut.SearchAsync("and", context); |
|
|
|
await TestSearchAsync(ids1, "Hallo", Scope.Draft); |
|
|
|
await TestSearchAsync(null, "Hallo", Scope.Published); |
|
|
|
|
|
|
|
var germanStopwordsIds = await sut.SearchAsync("und", context); |
|
|
|
await CopyAsync(false); |
|
|
|
|
|
|
|
Assert.Equal(ids1, german1); |
|
|
|
Assert.Equal(ids1, german2); |
|
|
|
Assert.Equal(ids2, germanStopwordsIds); |
|
|
|
await TestSearchAsync(ids1, "Hello", Scope.Draft); |
|
|
|
await TestSearchAsync(ids1, "Hello", Scope.Published); |
|
|
|
|
|
|
|
var english1 = await sut.SearchAsync("City", context); |
|
|
|
var english2 = await sut.SearchAsync("und", context); |
|
|
|
await TestSearchAsync(null, "Hallo", Scope.Draft); |
|
|
|
await TestSearchAsync(null, "Hallo", Scope.Published); |
|
|
|
|
|
|
|
var englishStopwordsIds = await sut.SearchAsync("and", context); |
|
|
|
await AddInvariantContent("Hallo", "Welt", true); |
|
|
|
|
|
|
|
Assert.Equal(ids2, english1); |
|
|
|
Assert.Equal(ids2, english2); |
|
|
|
Assert.Equal(ids1, englishStopwordsIds); |
|
|
|
await TestSearchAsync(null, "Hello", Scope.Draft); |
|
|
|
await TestSearchAsync(ids1, "Hello", Scope.Published); |
|
|
|
|
|
|
|
await TestSearchAsync(ids1, "Hallo", Scope.Draft); |
|
|
|
await TestSearchAsync(null, "Hallo", Scope.Published); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task Should_throw_exception_for_invalid_query() |
|
|
|
public async Task Should_also_retrieve_published_content_after_copy() |
|
|
|
{ |
|
|
|
await AddInvariantContent(); |
|
|
|
await AddInvariantContent("Hello", "World", false); |
|
|
|
|
|
|
|
await Assert.ThrowsAsync<ValidationException>(() => sut.SearchAsync("~hello", context)); |
|
|
|
await TestSearchAsync(ids1, "Hello", Scope.Draft); |
|
|
|
await TestSearchAsync(null, "Hello", Scope.Published); |
|
|
|
|
|
|
|
await CopyAsync(false); |
|
|
|
|
|
|
|
await TestSearchAsync(ids1, "Hello", Scope.Draft); |
|
|
|
await TestSearchAsync(ids1, "Hello", Scope.Published); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public async Task Should_also_retrieve_published_content_after_copy() |
|
|
|
public async Task Should_delete_documents_from_index() |
|
|
|
{ |
|
|
|
await AddInvariantContent(); |
|
|
|
await AddInvariantContent("Hello", "World", false); |
|
|
|
|
|
|
|
context.IsDraft = false; |
|
|
|
await TestSearchAsync(ids1, "Hello"); |
|
|
|
await TestSearchAsync(ids2, "World"); |
|
|
|
|
|
|
|
var foundHello1 = await sut.SearchAsync("Hello", context); |
|
|
|
await DeleteAsync(ids1[0]); |
|
|
|
|
|
|
|
Assert.Empty(foundHello1); |
|
|
|
await TestSearchAsync(null, "Hello"); |
|
|
|
await TestSearchAsync(ids2, "World"); |
|
|
|
} |
|
|
|
|
|
|
|
await sut.CopyAsync(ids1[0], true); |
|
|
|
await sut.FlushAsync(); |
|
|
|
[Fact] |
|
|
|
public async Task Should_search_by_field() |
|
|
|
{ |
|
|
|
await AddLocalizedContent(); |
|
|
|
|
|
|
|
var foundHello2 = await sut.SearchAsync("Hello", context); |
|
|
|
await TestSearchAsync(null, "de:city"); |
|
|
|
await TestSearchAsync(null, "en:Stadt"); |
|
|
|
} |
|
|
|
|
|
|
|
Assert.Equal(ids1, foundHello2); |
|
|
|
[Fact] |
|
|
|
public async Task Should_index_localized_content_and_retrieve() |
|
|
|
{ |
|
|
|
await AddLocalizedContent(); |
|
|
|
|
|
|
|
await TestSearchAsync(ids1, "Stadt"); |
|
|
|
await TestSearchAsync(ids1, "and"); |
|
|
|
await TestSearchAsync(ids2, "und"); |
|
|
|
|
|
|
|
await TestSearchAsync(ids2, "City"); |
|
|
|
await TestSearchAsync(ids2, "und"); |
|
|
|
await TestSearchAsync(ids1, "and"); |
|
|
|
} |
|
|
|
|
|
|
|
private async Task AddLocalizedContent() |
|
|
|
@ -182,29 +211,54 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text |
|
|
|
new ContentFieldData() |
|
|
|
.AddValue("en", "City and Surroundings und sonstiges")); |
|
|
|
|
|
|
|
await sut.IndexAsync(ids1[0], new IndexData { Data = germanData }, true); |
|
|
|
await sut.IndexAsync(ids2[0], new IndexData { Data = englishData }, true); |
|
|
|
await sut.IndexAsync(ids1[0], new IndexData { DataDraft = germanData }, true); |
|
|
|
await sut.IndexAsync(ids2[0], new IndexData { DataDraft = englishData }, true); |
|
|
|
await sut.FlushAsync(); |
|
|
|
} |
|
|
|
|
|
|
|
private async Task AddInvariantContent() |
|
|
|
private async Task AddInvariantContent(string text1, string text2, bool onlyDraft = false) |
|
|
|
{ |
|
|
|
var data1 = |
|
|
|
new NamedContentData() |
|
|
|
.AddField("test", |
|
|
|
new ContentFieldData() |
|
|
|
.AddValue("iv", "Hello")); |
|
|
|
.AddValue("iv", text1)); |
|
|
|
|
|
|
|
var data2 = |
|
|
|
new NamedContentData() |
|
|
|
.AddField("test", |
|
|
|
new ContentFieldData() |
|
|
|
.AddValue("iv", "World")); |
|
|
|
.AddValue("iv", text2)); |
|
|
|
|
|
|
|
await sut.IndexAsync(ids1[0], new IndexData { Data = data1 }, true); |
|
|
|
await sut.IndexAsync(ids2[0], new IndexData { Data = data2 }, true); |
|
|
|
await sut.IndexAsync(ids1[0], new IndexData { DataDraft = data1 }, onlyDraft); |
|
|
|
await sut.IndexAsync(ids2[0], new IndexData { DataDraft = data2 }, onlyDraft); |
|
|
|
} |
|
|
|
|
|
|
|
await sut.FlushAsync(); |
|
|
|
private async Task DeleteAsync(Guid id) |
|
|
|
{ |
|
|
|
await sut.DeleteAsync(id); |
|
|
|
} |
|
|
|
|
|
|
|
private async Task CopyAsync(bool fromDraft) |
|
|
|
{ |
|
|
|
await sut.CopyAsync(ids1[0], fromDraft); |
|
|
|
await sut.CopyAsync(ids2[0], fromDraft); |
|
|
|
} |
|
|
|
|
|
|
|
private async Task TestSearchAsync(List<Guid> expected, string text, Scope target = Scope.Draft, TextIndexerGrain grain = null) |
|
|
|
{ |
|
|
|
context.Scope = target; |
|
|
|
|
|
|
|
var result = await (grain ?? sut).SearchAsync(text, context); |
|
|
|
|
|
|
|
if (expected != null) |
|
|
|
{ |
|
|
|
Assert.Equal(expected, result); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
Assert.Empty(result); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|