mirror of https://github.com/Squidex/squidex.git
4 changed files with 220 additions and 0 deletions
@ -0,0 +1,41 @@ |
|||||
|
// ==========================================================================
|
||||
|
// DefaultMemoryEventNotifierTests.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Squidex.Infrastructure.CQRS.Events |
||||
|
{ |
||||
|
public sealed class DefaultMemoryEventNotifierTests |
||||
|
{ |
||||
|
private readonly DefaultMemoryEventNotifier sut = new DefaultMemoryEventNotifier(new InMemoryPubSub()); |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_invalidate_all_actions() |
||||
|
{ |
||||
|
var handler1Handled = 0; |
||||
|
var handler2Handled = 0; |
||||
|
|
||||
|
sut.Subscribe(() => |
||||
|
{ |
||||
|
handler1Handled++; |
||||
|
}); |
||||
|
|
||||
|
sut.NotifyEventsStored(); |
||||
|
|
||||
|
sut.Subscribe(() => |
||||
|
{ |
||||
|
handler2Handled++; |
||||
|
}); |
||||
|
|
||||
|
sut.NotifyEventsStored(); |
||||
|
|
||||
|
Assert.Equal(2, handler1Handled); |
||||
|
Assert.Equal(1, handler2Handled); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,127 @@ |
|||||
|
// ==========================================================================
|
||||
|
// InvalidatingMemoryCacheTest.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Microsoft.Extensions.Caching.Memory; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Moq; |
||||
|
using Xunit; |
||||
|
|
||||
|
// ReSharper disable RedundantAssignment
|
||||
|
|
||||
|
namespace Squidex.Infrastructure.Caching |
||||
|
{ |
||||
|
public class InvalidatingMemoryCacheTest |
||||
|
{ |
||||
|
internal sealed class MyOptions<T> : IOptions<T> where T : class, new() |
||||
|
{ |
||||
|
public MyOptions(T value) |
||||
|
{ |
||||
|
Value = value; |
||||
|
} |
||||
|
|
||||
|
public T Value { get; } |
||||
|
} |
||||
|
|
||||
|
private readonly Mock<IPubSub> pubsub = new Mock<IPubSub>(); |
||||
|
private readonly Mock<IMemoryCache> cache = new Mock<IMemoryCache>(); |
||||
|
private readonly InvalidatingMemoryCache sut; |
||||
|
|
||||
|
public InvalidatingMemoryCacheTest() |
||||
|
{ |
||||
|
sut = new InvalidatingMemoryCache(cache.Object, pubsub.Object); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_do_nothing_if_cache_does_not_support_invalidation() |
||||
|
{ |
||||
|
new MemoryCache(new MyOptions<MemoryCacheOptions>(new MemoryCacheOptions())).Invalidate("a-key"); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_dispose_inner_on_dispose() |
||||
|
{ |
||||
|
sut.Dispose(); |
||||
|
|
||||
|
cache.Verify(x => x.Dispose(), Times.Once()); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_call_inner_on_remove() |
||||
|
{ |
||||
|
sut.Remove("a-key"); |
||||
|
|
||||
|
cache.Verify(x => x.Remove("a-key"), Times.Once()); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_invalidate_if_key_is_not_a_string() |
||||
|
{ |
||||
|
sut.Invalidate(123); |
||||
|
|
||||
|
pubsub.Verify(x => x.Publish("CacheInvalidations", It.IsAny<string>(), false), Times.Never()); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_invalidate_if_key_is_string() |
||||
|
{ |
||||
|
sut.Invalidate("a-key"); |
||||
|
|
||||
|
pubsub.Verify(x => x.Publish("CacheInvalidations", "a-key", false), Times.Once()); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_invalidate_if_key_is_string_for_cache() |
||||
|
{ |
||||
|
((IMemoryCache)sut).Invalidate("a-key"); |
||||
|
|
||||
|
pubsub.Verify(x => x.Publish("CacheInvalidations", "a-key", false), Times.Once()); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_call_inner_to_create_value() |
||||
|
{ |
||||
|
var cacheEntry = new Mock<ICacheEntry>(); |
||||
|
|
||||
|
cache.Setup(x => x.CreateEntry("a-key")).Returns(cacheEntry.Object); |
||||
|
|
||||
|
var result = sut.CreateEntry("a-key"); |
||||
|
|
||||
|
Assert.Equal(cacheEntry.Object, result); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_use_inner_cache_to_get_value() |
||||
|
{ |
||||
|
object currentOut = 123; |
||||
|
|
||||
|
cache.Setup(x => x.TryGetValue("a-key", out currentOut)).Returns(true); |
||||
|
|
||||
|
object result; |
||||
|
|
||||
|
var exists = sut.TryGetValue("a-key", out result); |
||||
|
|
||||
|
Assert.Equal(123, result); |
||||
|
Assert.True(exists); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_remove_if_invalidated() |
||||
|
{ |
||||
|
var anotherPubsub = new InMemoryPubSub(); |
||||
|
var anotherSut = new InvalidatingMemoryCache(new MemoryCache(new MyOptions<MemoryCacheOptions>(new MemoryCacheOptions())), anotherPubsub); |
||||
|
|
||||
|
anotherSut.Set("a-key", 123); |
||||
|
|
||||
|
Assert.Equal(123, anotherSut.Get<int>("a-key")); |
||||
|
|
||||
|
anotherPubsub.Publish("CacheInvalidations", "a-key", true); |
||||
|
|
||||
|
Assert.Equal(0, anotherSut.Get<int>("a-key")); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,51 @@ |
|||||
|
// ==========================================================================
|
||||
|
// InMemoryPubSubTests.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.Collections.Generic; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Squidex.Infrastructure |
||||
|
{ |
||||
|
public class InMemoryPubSubTests |
||||
|
{ |
||||
|
private readonly InMemoryPubSub sut = new InMemoryPubSub(); |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_publish_to_handlers() |
||||
|
{ |
||||
|
var channel1Events = new List<string>(); |
||||
|
var channel2Events = new List<string>(); |
||||
|
|
||||
|
sut.Subscribe("channel1", x => |
||||
|
{ |
||||
|
channel1Events.Add(x); |
||||
|
}); |
||||
|
|
||||
|
sut.Subscribe("channel1", x => |
||||
|
{ |
||||
|
channel1Events.Add(x); |
||||
|
}); |
||||
|
|
||||
|
sut.Subscribe("channel2", x => |
||||
|
{ |
||||
|
channel2Events.Add(x); |
||||
|
}); |
||||
|
|
||||
|
sut.Publish("channel1", "1", true); |
||||
|
sut.Publish("channel1", "2", true); |
||||
|
sut.Publish("channel1", "3", false); |
||||
|
|
||||
|
sut.Publish("channel2", "a", true); |
||||
|
sut.Publish("channel2", "b", true); |
||||
|
|
||||
|
Assert.Equal(new[] { "1", "1", "2", "2" }, channel1Events.ToArray()); |
||||
|
Assert.Equal(new[] { "a", "b" }, channel2Events.ToArray()); |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue