Browse Source

Tests improved

pull/460/head
Sebastian 6 years ago
parent
commit
c4760a2535
  1. 2
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/Text/TextIndexerBenchmark.cs
  2. 230
      backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/Text/TextIndexerGrainTestsBase.cs

2
backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/Text/TextIndexerBenchmark.cs

@ -28,7 +28,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text
sut.ActivateAsync(schemaId).Wait();
}
[Fact(Skip = "Only used for benchmarks")]
[Fact]// (Skip = "Only used for benchmarks")]
public async Task Should_index_many_documents()
{
var text = new Dictionary<string, string>

230
backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/Text/TextIndexerGrainTestsBase.cs

@ -7,23 +7,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using FakeItEasy;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Validation;
using Xunit;
#pragma warning disable SA1115 // Parameter should follow comma
#pragma warning disable RECS0021 // Warns about calls to virtual member functions occuring in the constructor
namespace Squidex.Domain.Apps.Entities.Contents.Text
{
public abstract class TextIndexerGrainTestsBase : IDisposable
public abstract class TextIndexerGrainTestsBase
{
private readonly Guid schemaId = Guid.NewGuid();
private readonly List<Guid> ids1 = new List<Guid> { Guid.NewGuid() };
private readonly List<Guid> ids2 = new List<Guid> { Guid.NewGuid() };
private readonly SearchContext context;
private readonly TextIndexerGrain sut;
public abstract IIndexStorage Storage { get; }
@ -33,176 +33,157 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text
{
Languages = new HashSet<string> { "de", "en" }
};
var factory = new IndexManager(Storage, A.Fake<ISemanticLog>());
sut = new TextIndexerGrain(factory);
sut.ActivateAsync(schemaId).Wait();
}
public void Dispose()
{
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("Hello", "World", false);
await sut.OnDeactivateAsync();
var other = new TextIndexerGrain(new IndexManager(Storage, A.Fake<ISemanticLog>()));
try
{
await other.ActivateAsync(schemaId);
await TestSearchAsync(ids1, "Hello", grain: other);
await TestSearchAsync(ids2, "World", grain: other);
}
finally
await ExecuteAsync(Guid.NewGuid(), async sut =>
{
await other.OnDeactivateAsync();
}
await Assert.ThrowsAsync<ValidationException>(() => sut.SearchAsync("~hello", context));
});
}
[Fact]
public async Task Should_index_invariant_content_and_retrieve()
{
await AddInvariantContent("Hello", "World", false);
await SearchWithGrains(
g => AddInvariantContent(g, "Hello", "World", false),
await TestSearchAsync(ids1, "Hello");
await TestSearchAsync(ids2, "World");
g => TestSearchAsync(g, expected: ids1, text: "Hello"),
g => TestSearchAsync(g, expected: ids2, text: "World"));
}
[Fact]
public async Task Should_index_invariant_content_and_retrieve_with_fuzzy()
{
await AddInvariantContent("Hello", "World", false);
await SearchWithGrains(
g => AddInvariantContent(g, "Hello", "World", false),
await TestSearchAsync(ids1, "helo~");
await TestSearchAsync(ids2, "wold~");
g => TestSearchAsync(g, expected: ids1, text: "helo~"),
g => TestSearchAsync(g, expected: ids2, text: "wold~"));
}
[Fact]
public async Task Should_update_draft_only()
{
await AddInvariantContent("Hello", "World", false);
await AddInvariantContent("Hallo", "Welt", false);
await SearchWithGrains(
g => AddInvariantContent(g, text1: "Hello", text2: "World", onlyDraft: false),
g => AddInvariantContent(g, text1: "Hallo", text2: "Welt", onlyDraft: false),
await TestSearchAsync(null, "Hello", Scope.Draft);
await TestSearchAsync(null, "Hello", Scope.Published);
g => TestSearchAsync(g, expected: null, text: "Hello", target: Scope.Draft),
g => TestSearchAsync(g, expected: null, text: "Hello", target: Scope.Published),
await TestSearchAsync(ids1, "Hallo", Scope.Draft);
await TestSearchAsync(null, "Hallo", Scope.Published);
g => TestSearchAsync(g, expected: ids1, text: "Hallo", target: Scope.Draft),
g => TestSearchAsync(g, expected: null, text: "Hallo", target: Scope.Published));
}
[Fact]
public async Task Should_also_update_published_after_copy()
{
await AddInvariantContent("Hello", "World", false);
await SearchWithGrains(
g => AddInvariantContent(g, text1: "Hello", text2: "World", onlyDraft: false),
await CopyAsync(true);
g => CopyAsync(g, fromDraft: true),
await AddInvariantContent("Hallo", "Welt", false);
g => AddInvariantContent(g, text1: "Hallo", text2: "Welt", onlyDraft: false),
await TestSearchAsync(null, "Hello", Scope.Draft);
await TestSearchAsync(null, "Hello", Scope.Published);
g => TestSearchAsync(g, expected: null, text: "Hello", target: Scope.Draft),
g => TestSearchAsync(g, expected: null, text: "Hello", target: Scope.Published),
await TestSearchAsync(ids1, "Hallo", Scope.Draft);
await TestSearchAsync(ids1, "Hallo", Scope.Published);
g => TestSearchAsync(g, expected: ids1, text: "Hallo", target: Scope.Draft),
g => TestSearchAsync(g, expected: ids1, text: "Hallo", target: Scope.Published));
}
[Fact]
public async Task Should_simulate_content_reversion()
{
await AddInvariantContent("Hello", "World", false);
await SearchWithGrains(
g => AddInvariantContent(g, text1: "Hello", text2: "World", onlyDraft: false),
await CopyAsync(true);
g => CopyAsync(g, fromDraft: true),
await AddInvariantContent("Hallo", "Welt", true);
g => AddInvariantContent(g, text1: "Hallo", text2: "Welt", onlyDraft: true),
await TestSearchAsync(null, "Hello", Scope.Draft);
await TestSearchAsync(ids1, "Hello", Scope.Published);
g => TestSearchAsync(g, expected: null, text: "Hello", target: Scope.Draft),
g => TestSearchAsync(g, expected: ids1, text: "Hello", target: Scope.Published),
await TestSearchAsync(ids1, "Hallo", Scope.Draft);
await TestSearchAsync(null, "Hallo", Scope.Published);
g => TestSearchAsync(g, expected: ids1, text: "Hallo", target: Scope.Draft),
g => TestSearchAsync(g, expected: null, text: "Hallo", target: Scope.Published),
await CopyAsync(false);
g => CopyAsync(g, fromDraft: false),
await TestSearchAsync(ids1, "Hello", Scope.Draft);
await TestSearchAsync(ids1, "Hello", Scope.Published);
g => TestSearchAsync(g, expected: ids1, text: "Hello", target: Scope.Draft),
g => TestSearchAsync(g, expected: ids1, text: "Hello", target: Scope.Published),
await TestSearchAsync(null, "Hallo", Scope.Draft);
await TestSearchAsync(null, "Hallo", Scope.Published);
g => TestSearchAsync(g, expected: null, text: "Hallo", target: Scope.Draft),
g => TestSearchAsync(g, expected: null, text: "Hallo", target: Scope.Published),
await AddInvariantContent("Guten Morgen", "Welt", true);
g => AddInvariantContent(g, text1: "Guten Morgen", text2: "Welt", onlyDraft: true),
await TestSearchAsync(null, "Hello", Scope.Draft);
await TestSearchAsync(ids1, "Hello", Scope.Published);
g => TestSearchAsync(g, expected: null, text: "Hello", target: Scope.Draft),
g => TestSearchAsync(g, expected: ids1, text: "Hello", target: Scope.Published),
await TestSearchAsync(ids1, "Guten Morgen", Scope.Draft);
await TestSearchAsync(null, "Guten Morgen", Scope.Published);
g => TestSearchAsync(g, expected: ids1, text: "Guten Morgen", target: Scope.Draft),
g => TestSearchAsync(g, expected: null, text: "Guten Morgen", target: Scope.Published));
}
[Fact]
public async Task Should_also_retrieve_published_content_after_copy()
{
await AddInvariantContent("Hello", "World", false);
await SearchWithGrains(
g => AddInvariantContent(g, text1: "Hello", text2: "World", onlyDraft: false),
await TestSearchAsync(ids1, "Hello", Scope.Draft);
await TestSearchAsync(null, "Hello", Scope.Published);
g => TestSearchAsync(g, expected: ids1, text: "Hello", target: Scope.Draft),
g => TestSearchAsync(g, expected: null, text: "Hello", target: Scope.Published),
await CopyAsync(true);
g => CopyAsync(g, fromDraft: true),
await TestSearchAsync(ids1, "Hello", Scope.Draft);
await TestSearchAsync(ids1, "Hello", Scope.Published);
g => TestSearchAsync(g, expected: ids1, text: "Hello", target: Scope.Draft),
g => TestSearchAsync(g, expected: ids1, text: "Hello", target: Scope.Published));
}
[Fact]
public async Task Should_delete_documents_from_index()
{
await AddInvariantContent("Hello", "World", false);
await SearchWithGrains(
g => AddInvariantContent(g, text1: "Hello", text2: "World", onlyDraft: false),
await TestSearchAsync(ids1, "Hello");
await TestSearchAsync(ids2, "World");
g => TestSearchAsync(g, expected: ids1, text: "Hello"),
g => TestSearchAsync(g, expected: ids2, text: "World"),
await DeleteAsync(ids1[0]);
g => DeleteAsync(g, id: ids1[0]),
await TestSearchAsync(null, "Hello");
await TestSearchAsync(ids2, "World");
g => TestSearchAsync(g, expected: null, text: "Hello"),
g => TestSearchAsync(g, expected: ids2, text: "World"));
}
[Fact]
public async Task Should_search_by_field()
{
await AddLocalizedContent();
await SearchWithGrains(
g => AddLocalizedContent(g),
await TestSearchAsync(null, "de:city");
await TestSearchAsync(null, "en:Stadt");
g => TestSearchAsync(g, expected: null, text: "de:city"),
g => TestSearchAsync(g, expected: null, text: "en:Stadt"));
}
[Fact]
public async Task Should_index_localized_content_and_retrieve()
{
await AddLocalizedContent();
await SearchWithGrains(
g => AddLocalizedContent(g),
await TestSearchAsync(ids1, "Stadt");
await TestSearchAsync(ids1, "and");
await TestSearchAsync(ids2, "und");
g => TestSearchAsync(g, expected: ids1, text: "Stadt"),
g => TestSearchAsync(g, expected: ids1, text: "and"),
g => TestSearchAsync(g, expected: ids2, text: "und"),
await TestSearchAsync(ids2, "City");
await TestSearchAsync(ids2, "und");
await TestSearchAsync(ids1, "and");
g => TestSearchAsync(g, expected: ids2, text: "City"),
g => TestSearchAsync(g, expected: ids2, text: "und"),
g => TestSearchAsync(g, expected: ids1, text: "and"));
}
private async Task AddLocalizedContent()
private async Task AddLocalizedContent(TextIndexerGrain grain)
{
var germanText = new Dictionary<string, string>
{
@ -214,11 +195,11 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text
["en"] = "City and Surroundings und sonstiges"
};
await sut.IndexAsync(new Update { Id = ids1[0], Text = germanText, OnlyDraft = true });
await sut.IndexAsync(new Update { Id = ids2[0], Text = englishText, OnlyDraft = true });
await grain.IndexAsync(new Update { Id = ids1[0], Text = germanText, OnlyDraft = true });
await grain.IndexAsync(new Update { Id = ids2[0], Text = englishText, OnlyDraft = true });
}
private async Task AddInvariantContent(string text1, string text2, bool onlyDraft = false)
private async Task AddInvariantContent(TextIndexerGrain grain, string text1, string text2, bool onlyDraft = false)
{
var content1 = new Dictionary<string, string>
{
@ -230,26 +211,26 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text
["iv"] = text2
};
await sut.IndexAsync(new Update { Id = ids1[0], Text = content1, OnlyDraft = onlyDraft });
await sut.IndexAsync(new Update { Id = ids2[0], Text = content2, OnlyDraft = onlyDraft });
await grain.IndexAsync(new Update { Id = ids1[0], Text = content1, OnlyDraft = onlyDraft });
await grain.IndexAsync(new Update { Id = ids2[0], Text = content2, OnlyDraft = onlyDraft });
}
private async Task DeleteAsync(Guid id)
private async Task DeleteAsync(TextIndexerGrain grain, Guid id)
{
await sut.DeleteAsync(id);
await grain.DeleteAsync(id);
}
private async Task CopyAsync(bool fromDraft)
private async Task CopyAsync(TextIndexerGrain grain, bool fromDraft)
{
await sut.CopyAsync(ids1[0], fromDraft);
await sut.CopyAsync(ids2[0], fromDraft);
await grain.CopyAsync(ids1[0], fromDraft);
await grain.CopyAsync(ids2[0], fromDraft);
}
private async Task TestSearchAsync(List<Guid>? expected, string text, Scope target = Scope.Draft, TextIndexerGrain? grain = null)
private async Task TestSearchAsync(TextIndexerGrain grain, List<Guid>? expected, string text, Scope target = Scope.Draft)
{
context.Scope = target;
var result = await (grain ?? sut).SearchAsync(text, context);
var result = await grain.SearchAsync(text, context);
if (expected != null)
{
@ -260,5 +241,44 @@ namespace Squidex.Domain.Apps.Entities.Contents.Text
Assert.Empty(result);
}
}
private async Task SearchWithGrains(params Func<TextIndexerGrain, Task>[] actions)
{
for (var i = 0; i < actions.Length; i++)
{
var schemaId = Guid.NewGuid();
await ExecuteAsync(schemaId, async sut =>
{
foreach (var action in actions.Take(i))
{
await action(sut);
}
});
await ExecuteAsync(schemaId, async sut =>
{
foreach (var action in actions.Skip(i))
{
await action(sut);
}
});
}
}
private async Task ExecuteAsync(Guid id, Func<TextIndexerGrain, Task> action)
{
var sut = new TextIndexerGrain(new IndexManager(Storage, A.Fake<ISemanticLog>()));
try
{
await sut.ActivateAsync(id);
await action(sut);
}
finally
{
await sut.OnDeactivateAsync();
}
}
}
}

Loading…
Cancel
Save