From baae8eeb522097555efcabf8b4410d6f8ef2d482 Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Sun, 17 Dec 2017 12:03:19 +0100 Subject: [PATCH] Core models added. --- .../Apps/AppPattern.cs | 62 ++++++++++++++ .../Apps/AppPatterns.cs | 57 +++++++++++++ .../Apps/Json/AppPatternsConverter.cs | 37 +++++++++ .../Apps/Json/JsonAppPattern.cs | 42 ++++++++++ .../Apps/AppPatternAdded.cs | 25 ++++++ .../Apps/AppPatternDeleted.cs | 21 +++++ .../Apps/AppPatternUpdated.cs | 25 ++++++ .../Model/Apps/AppPatternJsonTests.cs | 44 ++++++++++ .../Model/Apps/AppPatternsTests.cs | 80 +++++++++++++++++++ .../TestData.cs | 1 + 10 files changed, 394 insertions(+) create mode 100644 src/Squidex.Domain.Apps.Core.Model/Apps/AppPattern.cs create mode 100644 src/Squidex.Domain.Apps.Core.Model/Apps/AppPatterns.cs create mode 100644 src/Squidex.Domain.Apps.Core.Model/Apps/Json/AppPatternsConverter.cs create mode 100644 src/Squidex.Domain.Apps.Core.Model/Apps/Json/JsonAppPattern.cs create mode 100644 src/Squidex.Domain.Apps.Events/Apps/AppPatternAdded.cs create mode 100644 src/Squidex.Domain.Apps.Events/Apps/AppPatternDeleted.cs create mode 100644 src/Squidex.Domain.Apps.Events/Apps/AppPatternUpdated.cs create mode 100644 tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppPatternJsonTests.cs create mode 100644 tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppPatternsTests.cs diff --git a/src/Squidex.Domain.Apps.Core.Model/Apps/AppPattern.cs b/src/Squidex.Domain.Apps.Core.Model/Apps/AppPattern.cs new file mode 100644 index 000000000..a893f5f8e --- /dev/null +++ b/src/Squidex.Domain.Apps.Core.Model/Apps/AppPattern.cs @@ -0,0 +1,62 @@ +// ========================================================================== +// AppPattern.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System; +using System.Diagnostics.Contracts; +using Squidex.Infrastructure; + +namespace Squidex.Domain.Apps.Core.Apps +{ + public class AppPattern + { + private readonly Guid id; + private readonly string name; + private readonly string pattern; + private readonly string defaultMessage; + + public Guid Id + { + get { return id; } + } + + public string Name + { + get { return name; } + } + + public string Pattern + { + get { return pattern; } + } + + public string DefaultMessage + { + get { return defaultMessage; } + } + + public AppPattern(Guid id, string name, string pattern, string defaultMessage) + { + Guard.NotNullOrEmpty(name, nameof(name)); + Guard.NotNullOrEmpty(pattern, nameof(pattern)); + + this.id = id; + this.name = name; + this.pattern = pattern; + this.defaultMessage = defaultMessage; + } + + [Pure] + public AppPattern Update(string name, string pattern, string defaultMessage) + { + Guard.NotNullOrEmpty(name, nameof(name)); + Guard.NotNullOrEmpty(pattern, nameof(pattern)); + + return new AppPattern(this.id, name, pattern, defaultMessage); + } + } +} diff --git a/src/Squidex.Domain.Apps.Core.Model/Apps/AppPatterns.cs b/src/Squidex.Domain.Apps.Core.Model/Apps/AppPatterns.cs new file mode 100644 index 000000000..465c2cf67 --- /dev/null +++ b/src/Squidex.Domain.Apps.Core.Model/Apps/AppPatterns.cs @@ -0,0 +1,57 @@ +// ========================================================================== +// AppPatterns.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== +using System; +using System.Collections.Immutable; +using System.Diagnostics.Contracts; +using Squidex.Infrastructure; + +namespace Squidex.Domain.Apps.Core.Apps +{ + public sealed class AppPatterns : DictionaryWrapper + { + public static readonly AppPatterns Empty = new AppPatterns(); + + private AppPatterns() + : base(ImmutableDictionary.Empty) + { + } + + public AppPatterns(ImmutableDictionary inner) + : base(inner) + { + } + + [Pure] + public AppPatterns Add(Guid id, string name, string pattern, string defaultMessage) + { + var newPattern = new AppPattern(id, name, pattern, defaultMessage); + + return new AppPatterns(Inner.Add(id, newPattern)); + } + + [Pure] + public AppPatterns Remove(Guid id) + { + return new AppPatterns(Inner.Remove(id)); + } + + [Pure] + public AppPatterns Update(Guid id, string name, string pattern, string defaultMessage) + { + Guard.NotNullOrEmpty(name, nameof(name)); + Guard.NotNullOrEmpty(pattern, nameof(pattern)); + + if (!TryGetValue(id, out var appPattern)) + { + return this; + } + + return new AppPatterns(Inner.SetItem(id, appPattern.Update(name, pattern, defaultMessage))); + } + } +} diff --git a/src/Squidex.Domain.Apps.Core.Model/Apps/Json/AppPatternsConverter.cs b/src/Squidex.Domain.Apps.Core.Model/Apps/Json/AppPatternsConverter.cs new file mode 100644 index 000000000..2e00fef01 --- /dev/null +++ b/src/Squidex.Domain.Apps.Core.Model/Apps/Json/AppPatternsConverter.cs @@ -0,0 +1,37 @@ +// ========================================================================== +// AppPatternsConverter.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using Newtonsoft.Json; +using Squidex.Infrastructure.Json; + +namespace Squidex.Domain.Apps.Core.Apps.Json +{ + public sealed class AppPatternsConverter : JsonClassConverter + { + protected override void WriteValue(JsonWriter writer, AppPatterns value, JsonSerializer serializer) + { + var json = new Dictionary(value.Count); + + foreach (var client in value) + { + json.Add(client.Key, new JsonAppPattern(client.Value)); + } + + serializer.Serialize(writer, json); + } + + protected override AppPatterns ReadValue(JsonReader reader, Type objectType, JsonSerializer serializer) + { + var json = serializer.Deserialize>(reader); + + return new AppPatterns(json.ToImmutableDictionary(x => x.Key, x => x.Value.ToPattern())); + } + } +} diff --git a/src/Squidex.Domain.Apps.Core.Model/Apps/Json/JsonAppPattern.cs b/src/Squidex.Domain.Apps.Core.Model/Apps/Json/JsonAppPattern.cs new file mode 100644 index 000000000..4b30d9e15 --- /dev/null +++ b/src/Squidex.Domain.Apps.Core.Model/Apps/Json/JsonAppPattern.cs @@ -0,0 +1,42 @@ +// ========================================================================== +// JsonAppPattern.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== +using System; +using Newtonsoft.Json; +using Squidex.Infrastructure.Reflection; + +namespace Squidex.Domain.Apps.Core.Apps.Json +{ + public class JsonAppPattern + { + [JsonProperty] + public Guid Id { get; set; } + + [JsonProperty] + public string Name { get; set; } + + [JsonProperty] + public string Pattern { get; set; } + + [JsonProperty] + public string DefaultMessage { get; set; } + + public JsonAppPattern() + { + } + + public JsonAppPattern(AppPattern pattern) + { + SimpleMapper.Map(pattern, this); + } + + public AppPattern ToPattern() + { + return new AppPattern(Id, Name, Pattern, DefaultMessage); + } + } +} diff --git a/src/Squidex.Domain.Apps.Events/Apps/AppPatternAdded.cs b/src/Squidex.Domain.Apps.Events/Apps/AppPatternAdded.cs new file mode 100644 index 000000000..bbd6fd0be --- /dev/null +++ b/src/Squidex.Domain.Apps.Events/Apps/AppPatternAdded.cs @@ -0,0 +1,25 @@ +// ========================================================================== +// AppPatternAdded.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System; +using Squidex.Infrastructure.EventSourcing; + +namespace Squidex.Domain.Apps.Events.Apps +{ + [EventType(nameof(AppPatternAdded))] + public sealed class AppPatternAdded : AppEvent + { + public Guid Id { get; set; } + + public string Name { get; set; } + + public string Pattern { get; set; } + + public string DefaultMessage { get; set; } + } +} diff --git a/src/Squidex.Domain.Apps.Events/Apps/AppPatternDeleted.cs b/src/Squidex.Domain.Apps.Events/Apps/AppPatternDeleted.cs new file mode 100644 index 000000000..0a595e3d4 --- /dev/null +++ b/src/Squidex.Domain.Apps.Events/Apps/AppPatternDeleted.cs @@ -0,0 +1,21 @@ +// ========================================================================== +// AppPatternDeleted.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System; +using Squidex.Infrastructure.EventSourcing; + +namespace Squidex.Domain.Apps.Events.Apps +{ + [EventType(nameof(AppPatternDeleted))] + public sealed class AppPatternDeleted : AppEvent + { + public Guid Id { get; set; } + + public string Name { get; set; } + } +} diff --git a/src/Squidex.Domain.Apps.Events/Apps/AppPatternUpdated.cs b/src/Squidex.Domain.Apps.Events/Apps/AppPatternUpdated.cs new file mode 100644 index 000000000..1f5908b87 --- /dev/null +++ b/src/Squidex.Domain.Apps.Events/Apps/AppPatternUpdated.cs @@ -0,0 +1,25 @@ +// ========================================================================== +// AppPatternUpdated.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System; +using Squidex.Infrastructure.EventSourcing; + +namespace Squidex.Domain.Apps.Events.Apps +{ + [EventType(nameof(AppPatternUpdated))] + public sealed class AppPatternUpdated : AppEvent + { + public Guid Id { get; set; } + + public string Name { get; set; } + + public string Pattern { get; set; } + + public string DefaultMessage { get; set; } + } +} diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppPatternJsonTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppPatternJsonTests.cs new file mode 100644 index 000000000..3f9d61349 --- /dev/null +++ b/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppPatternJsonTests.cs @@ -0,0 +1,44 @@ +// ========================================================================== +// AppClientJsonTests.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System; +using FluentAssertions; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Squidex.Domain.Apps.Core.Apps; +using Xunit; + +namespace Squidex.Domain.Apps.Core.Model.Apps +{ + public class AppPatternJsonTests + { + private readonly JsonSerializer serializer = TestData.DefaultSerializer(); + + [Fact] + public void Should_serialize_and_deserialize() + { + var patterns = AppPatterns.Empty; + + var guid1 = Guid.NewGuid(); + var guid2 = Guid.NewGuid(); + var guid3 = Guid.NewGuid(); + + patterns = patterns.Add(guid1, "Name1", "Pattern1", "Default"); + patterns = patterns.Add(guid2, "Name2", "Pattern2", "Default"); + patterns = patterns.Add(guid3, "Name3", "Pattern3", "Default"); + + patterns = patterns.Update(guid2, "Name2 Update", "Pattern2 Update", "Default2"); + + patterns = patterns.Remove(guid1); + + var appPatterns = JToken.FromObject(patterns, serializer).ToObject(serializer); + + appPatterns.ShouldBeEquivalentTo(patterns); + } + } +} diff --git a/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppPatternsTests.cs b/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppPatternsTests.cs new file mode 100644 index 000000000..fae8ac4f3 --- /dev/null +++ b/tests/Squidex.Domain.Apps.Core.Tests/Model/Apps/AppPatternsTests.cs @@ -0,0 +1,80 @@ +// ========================================================================== +// AppClientsTests.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System; +using System.Linq; +using FluentAssertions; +using Squidex.Domain.Apps.Core.Apps; +using Xunit; + +#pragma warning disable SA1310 // Field names must not contain underscore + +namespace Squidex.Domain.Apps.Core.Model.Apps +{ + public class AppPatternsTests + { + private readonly AppPatterns defaultPatterns; + private readonly Guid firstId = Guid.NewGuid(); + private readonly Guid id = Guid.NewGuid(); + + public AppPatternsTests() + { + defaultPatterns = AppPatterns.Empty.Add(firstId, "Default", "Default Pattern", "Message"); + + id = Guid.NewGuid(); + } + + [Fact] + public void Should_add_pattern() + { + var patterns = defaultPatterns.Add(id, "NewPattern", "New Pattern", "Message"); + + patterns[id].ShouldBeEquivalentTo(new AppPattern(id, "NewPattern", "New Pattern", "Message")); + } + + [Fact] + public void Should_throw_exception_if_add_pattern_with_same_id() + { + var patterns = defaultPatterns.Add(id, "NewPattern", "New Pattern", "Message"); + + Assert.Throws(() => patterns.Add(id, "NewPattern", "New Pattern", "Message")); + } + + [Fact] + public void Should_update_pattern() + { + var patterns = defaultPatterns.Update(firstId, "UpdatePattern", "Update Pattern", "Message"); + + patterns[firstId].ShouldBeEquivalentTo(new AppPattern(firstId, "UpdatePattern", "Update Pattern", "Message")); + } + + [Fact] + public void Should_return_same_patterns_if_pattern_not_found() + { + var patterns = defaultPatterns.Update(id, "NewPattern", "NewPattern", "Message"); + + Assert.Same(defaultPatterns, patterns); + } + + [Fact] + public void Should_remove_pattern() + { + var patterns = defaultPatterns.Remove(firstId); + + Assert.Empty(patterns); + } + + [Fact] + public void Should_do_nothing_if_remove_pattern_not_found() + { + var patterns = defaultPatterns.Remove(id); + + Assert.NotSame(defaultPatterns, patterns); + } + } +} diff --git a/tests/Squidex.Domain.Apps.Core.Tests/TestData.cs b/tests/Squidex.Domain.Apps.Core.Tests/TestData.cs index a3a97cb50..6c872c678 100644 --- a/tests/Squidex.Domain.Apps.Core.Tests/TestData.cs +++ b/tests/Squidex.Domain.Apps.Core.Tests/TestData.cs @@ -35,6 +35,7 @@ namespace Squidex.Domain.Apps.Core ContractResolver = new ConverterContractResolver( new AppClientsConverter(), new AppContributorsConverter(), + new AppPatternsConverter(), new InstantConverter(), new LanguageConverter(), new LanguagesConfigConverter(),