Browse Source

Tests for rules.

pull/206/head
Sebastian Stehle 8 years ago
parent
commit
0b381df408
  1. 3
      src/Squidex.Domain.Apps.Entities/SquidexCommand.cs
  2. 27
      src/Squidex.Infrastructure/Commands/IAggregate.cs
  3. 2
      tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppDomainObjectTests.cs
  4. 48
      tests/Squidex.Domain.Apps.Entities.Tests/Rules/Guards/Actions/WebhookActionTests.cs
  5. 167
      tests/Squidex.Domain.Apps.Entities.Tests/Rules/Guards/GuardRuleTests.cs
  6. 84
      tests/Squidex.Domain.Apps.Entities.Tests/Rules/Guards/Triggers/ContentChangedTriggerTests.cs
  7. 116
      tests/Squidex.Domain.Apps.Entities.Tests/Rules/RuleCommandMiddlewareTests.cs
  8. 249
      tests/Squidex.Domain.Apps.Entities.Tests/Rules/RuleDomainObjectTests.cs

3
src/Squidex.Domain.Apps.Entities/SquidexCommand.cs

@ -6,7 +6,6 @@
// All rights reserved. // All rights reserved.
// ========================================================================== // ==========================================================================
using System.Security.Claims;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands; using Squidex.Infrastructure.Commands;
@ -14,8 +13,6 @@ namespace Squidex.Domain.Apps.Entities
{ {
public abstract class SquidexCommand : ICommand public abstract class SquidexCommand : ICommand
{ {
public ClaimsPrincipal Principal { get; set; }
public RefToken Actor { get; set; } public RefToken Actor { get; set; }
public long? ExpectedVersion { get; set; } public long? ExpectedVersion { get; set; }

27
src/Squidex.Infrastructure/Commands/IAggregate.cs

@ -1,27 +0,0 @@
// ==========================================================================
// IAggregate.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using System;
using System.Collections.Generic;
using Squidex.Infrastructure.EventSourcing;
namespace Squidex.Infrastructure.Commands
{
public interface IAggregate
{
Guid Id { get; }
int Version { get; }
void ApplyEvent(Envelope<IEvent> @event);
void ClearUncommittedEvents();
ICollection<Envelope<IEvent>> GetUncomittedEvents();
}
}

2
tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppDomainObjectTests.cs

@ -273,6 +273,8 @@ namespace Squidex.Domain.Apps.Entities.Apps
sut.UpdateLanguage(CreateCommand(new UpdateLanguage { Language = Language.DE, Fallback = new List<Language> { Language.EN } })); sut.UpdateLanguage(CreateCommand(new UpdateLanguage { Language = Language.DE, Fallback = new List<Language> { Language.EN } }));
Assert.True(sut.State.LanguagesConfig.Contains(Language.DE));
sut.GetUncomittedEvents() sut.GetUncomittedEvents()
.ShouldHaveSameEvents( .ShouldHaveSameEvents(
CreateEvent(new AppLanguageUpdated { Language = Language.DE, Fallback = new List<Language> { Language.EN } }) CreateEvent(new AppLanguageUpdated { Language = Language.DE, Fallback = new List<Language> { Language.EN } })

48
tests/Squidex.Domain.Apps.Entities.Tests/Rules/Guards/Actions/WebhookActionTests.cs

@ -0,0 +1,48 @@
// ==========================================================================
// WebhookActionTests.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using System;
using System.Threading.Tasks;
using Squidex.Domain.Apps.Core.Rules.Actions;
using Xunit;
namespace Squidex.Domain.Apps.Entities.Rules.Guards.Actions
{
public sealed class WebhookActionTests
{
[Fact]
public async Task Should_add_error_if_url_is_null()
{
var action = new WebhookAction { Url = null };
var errors = await RuleActionValidator.ValidateAsync(action);
Assert.NotEmpty(errors);
}
[Fact]
public async Task Should_add_error_if_url_is_relative()
{
var action = new WebhookAction { Url = new Uri("/invalid", UriKind.Relative) };
var errors = await RuleActionValidator.ValidateAsync(action);
Assert.NotEmpty(errors);
}
[Fact]
public async Task Should_not_add_error_if_url_is_absolute()
{
var action = new WebhookAction { Url = new Uri("https://squidex.io", UriKind.Absolute) };
var errors = await RuleActionValidator.ValidateAsync(action);
Assert.Empty(errors);
}
}
}

167
tests/Squidex.Domain.Apps.Entities.Tests/Rules/Guards/GuardRuleTests.cs

@ -0,0 +1,167 @@
// ==========================================================================
// GuardRuleTests.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using System;
using System.Collections.Immutable;
using System.Threading.Tasks;
using FakeItEasy;
using Squidex.Domain.Apps.Core.Rules;
using Squidex.Domain.Apps.Core.Rules.Actions;
using Squidex.Domain.Apps.Core.Rules.Triggers;
using Squidex.Domain.Apps.Entities.Rules.Commands;
using Squidex.Domain.Apps.Entities.Schemas;
using Squidex.Infrastructure;
using Xunit;
#pragma warning disable SA1310 // Field names must not contain underscore
namespace Squidex.Domain.Apps.Entities.Rules.Guards
{
public class GuardRuleTests
{
private readonly Uri validUrl = new Uri("https://squidex.io");
private readonly Rule rule_0 = new Rule(new ContentChangedTrigger(), new WebhookAction());
private readonly NamedId<Guid> appId = new NamedId<Guid>(Guid.NewGuid(), "my-app");
private readonly IAppProvider appProvider = A.Fake<IAppProvider>();
public GuardRuleTests()
{
A.CallTo(() => appProvider.GetSchemaAsync(appId.Name, A<Guid>.Ignored, false))
.Returns(A.Fake<ISchemaEntity>());
}
[Fact]
public async Task CanCreate_should_throw_exception_if_trigger_null()
{
var command = CreateCommand(new CreateRule
{
Trigger = null,
Action = new WebhookAction
{
Url = validUrl
}
});
await Assert.ThrowsAsync<ValidationException>(() => GuardRule.CanCreate(command, appProvider));
}
[Fact]
public async Task CanCreate_should_throw_exception_if_action_null()
{
var command = CreateCommand(new CreateRule
{
Trigger = new ContentChangedTrigger
{
Schemas = ImmutableList<ContentChangedTriggerSchema>.Empty
},
Action = null
});
await Assert.ThrowsAsync<ValidationException>(() => GuardRule.CanCreate(command, appProvider));
}
[Fact]
public async Task CanCreate_should_not_throw_exception_if_trigger_and_action_valid()
{
var command = CreateCommand(new CreateRule
{
Trigger = new ContentChangedTrigger
{
Schemas = ImmutableList<ContentChangedTriggerSchema>.Empty
},
Action = new WebhookAction
{
Url = validUrl
}
});
await GuardRule.CanCreate(command, appProvider);
}
[Fact]
public async Task CanUpdate_should_throw_exception_if_action_and_trigger_are_null()
{
var command = new UpdateRule();
await Assert.ThrowsAsync<ValidationException>(() => GuardRule.CanUpdate(command, appProvider));
}
[Fact]
public async Task CanUpdate_should_not_throw_exception_if_trigger_and_action_valid()
{
var command = CreateCommand(new UpdateRule
{
Trigger = new ContentChangedTrigger
{
Schemas = ImmutableList<ContentChangedTriggerSchema>.Empty
},
Action = new WebhookAction
{
Url = validUrl
}
});
await GuardRule.CanUpdate(command, appProvider);
}
[Fact]
public void CanEnable_should_throw_exception_if_rule_enabled()
{
var command = new EnableRule();
var rule_1 = rule_0.Enable();
Assert.Throws<ValidationException>(() => GuardRule.CanEnable(command, rule_1));
}
[Fact]
public void CanEnable_should_not_throw_exception_if_rule_disabled()
{
var command = new EnableRule();
var rule_1 = rule_0.Disable();
GuardRule.CanEnable(command, rule_1);
}
[Fact]
public void CanDisable_should_throw_exception_if_rule_disabled()
{
var command = new DisableRule();
var rule_1 = rule_0.Disable();
Assert.Throws<ValidationException>(() => GuardRule.CanDisable(command, rule_1));
}
[Fact]
public void CanDisable_should_not_throw_exception_if_rule_enabled()
{
var command = new DisableRule();
var rule_1 = rule_0.Enable();
GuardRule.CanDisable(command, rule_1);
}
[Fact]
public void CanDelete_should_not_throw_exception()
{
var command = new DeleteRule();
GuardRule.CanDelete(command);
}
private T CreateCommand<T>(T command) where T : AppCommand
{
command.AppId = appId;
return command;
}
}
}

84
tests/Squidex.Domain.Apps.Entities.Tests/Rules/Guards/Triggers/ContentChangedTriggerTests.cs

@ -0,0 +1,84 @@
// ==========================================================================
// ContentChangedTriggerTests.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using System;
using System.Collections.Immutable;
using System.Threading.Tasks;
using FakeItEasy;
using Squidex.Domain.Apps.Core.Rules.Triggers;
using Squidex.Domain.Apps.Entities;
using Squidex.Domain.Apps.Entities.Schemas;
using Xunit;
namespace Squidex.Domain.Apps.Entities.Rules.Guards.Triggers
{
public class ContentChangedTriggerTests
{
private readonly IAppProvider appProvider = A.Fake<IAppProvider>();
private readonly string appName = "my-app";
[Fact]
public async Task Should_add_error_if_schemas_ids_are_not_valid()
{
A.CallTo(() => appProvider.GetSchemaAsync(appName, A<Guid>.Ignored, false))
.Returns(Task.FromResult<ISchemaEntity>(null));
var trigger = new ContentChangedTrigger
{
Schemas = ImmutableList.Create(
new ContentChangedTriggerSchema()
)
};
var errors = await RuleTriggerValidator.ValidateAsync(appName, trigger, appProvider);
Assert.NotEmpty(errors);
}
[Fact]
public async Task Should_not_add_error_if_schemas_is_null()
{
var trigger = new ContentChangedTrigger();
var errors = await RuleTriggerValidator.ValidateAsync(appName, trigger, appProvider);
Assert.Empty(errors);
}
[Fact]
public async Task Should_not_add_error_if_schemas_is_empty()
{
var trigger = new ContentChangedTrigger
{
Schemas = ImmutableList<ContentChangedTriggerSchema>.Empty
};
var errors = await RuleTriggerValidator.ValidateAsync(appName, trigger, appProvider);
Assert.Empty(errors);
}
[Fact]
public async Task Should_not_add_error_if_schemas_ids_are_valid()
{
A.CallTo(() => appProvider.GetSchemaAsync(appName, A<Guid>.Ignored, false))
.Returns(A.Fake<ISchemaEntity>());
var trigger = new ContentChangedTrigger
{
Schemas = ImmutableList.Create(
new ContentChangedTriggerSchema()
)
};
var errors = await RuleTriggerValidator.ValidateAsync(appName, trigger, appProvider);
Assert.Empty(errors);
}
}
}

116
tests/Squidex.Domain.Apps.Entities.Tests/Rules/RuleCommandMiddlewareTests.cs

@ -0,0 +1,116 @@
// ==========================================================================
// RuleCommandMiddlewareTests.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using System;
using System.Threading.Tasks;
using FakeItEasy;
using Squidex.Domain.Apps.Core.Rules;
using Squidex.Domain.Apps.Core.Rules.Actions;
using Squidex.Domain.Apps.Core.Rules.Triggers;
using Squidex.Domain.Apps.Entities.Rules.Commands;
using Squidex.Domain.Apps.Entities.Schemas;
using Squidex.Domain.Apps.Entities.TestHelpers;
using Squidex.Infrastructure.Commands;
using Xunit;
namespace Squidex.Domain.Apps.Entities.Rules
{
public class RuleCommandMiddlewareTests : HandlerTestBase<RuleDomainObject>
{
private readonly IAppProvider appProvider = A.Fake<IAppProvider>();
private readonly RuleCommandMiddleware sut;
private readonly RuleDomainObject rule;
private readonly RuleTrigger ruleTrigger = new ContentChangedTrigger();
private readonly RuleAction ruleAction = new WebhookAction { Url = new Uri("https://squidex.io") };
private readonly Guid ruleId = Guid.NewGuid();
public RuleCommandMiddlewareTests()
{
A.CallTo(() => appProvider.GetSchemaAsync(A<string>.Ignored, A<Guid>.Ignored, false))
.Returns(A.Fake<ISchemaEntity>());
rule = new RuleDomainObject();
sut = new RuleCommandMiddleware(Handler, appProvider);
}
[Fact]
public async Task Create_should_create_domain_object()
{
var context = CreateContextForCommand(new CreateRule { Trigger = ruleTrigger, Action = ruleAction });
await TestCreate(rule, async _ =>
{
await sut.HandleAsync(context);
});
}
[Fact]
public async Task Update_should_update_domain_object()
{
var context = CreateContextForCommand(new UpdateRule { Trigger = ruleTrigger, Action = ruleAction });
CreateRule();
await TestUpdate(rule, async _ =>
{
await sut.HandleAsync(context);
});
}
[Fact]
public async Task Enable_should_update_domain_object()
{
CreateRule();
DisableRule();
var command = CreateContextForCommand(new EnableRule { RuleId = ruleId });
await TestUpdate(rule, async _ =>
{
await sut.HandleAsync(command);
});
}
[Fact]
public async Task Disable_should_update_domain_object()
{
CreateRule();
var command = CreateContextForCommand(new DisableRule { RuleId = ruleId });
await TestUpdate(rule, async _ =>
{
await sut.HandleAsync(command);
});
}
[Fact]
public async Task Delete_should_update_domain_object()
{
CreateRule();
var command = CreateContextForCommand(new DeleteRule { RuleId = ruleId });
await TestUpdate(rule, async _ =>
{
await sut.HandleAsync(command);
});
}
private void DisableRule()
{
rule.Disable(new DisableRule());
}
private void CreateRule()
{
rule.Create(new CreateRule { Trigger = ruleTrigger, Action = ruleAction });
}
}
}

249
tests/Squidex.Domain.Apps.Entities.Tests/Rules/RuleDomainObjectTests.cs

@ -0,0 +1,249 @@
// ==========================================================================
// RuleDomainObjectTests.cs
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex Group
// All rights reserved.
// ==========================================================================
using System;
using System.Collections.Immutable;
using Squidex.Domain.Apps.Core.Rules;
using Squidex.Domain.Apps.Core.Rules.Actions;
using Squidex.Domain.Apps.Core.Rules.Triggers;
using Squidex.Domain.Apps.Entities.Rules.Commands;
using Squidex.Domain.Apps.Entities.TestHelpers;
using Squidex.Domain.Apps.Events.Rules;
using Squidex.Infrastructure;
using Xunit;
namespace Squidex.Domain.Apps.Entities.Rules
{
public class RuleDomainObjectTests : HandlerTestBase<RuleDomainObject>
{
private readonly RuleTrigger ruleTrigger = new ContentChangedTrigger();
private readonly RuleAction ruleAction = new WebhookAction { Url = new Uri("https://squidex.io") };
private readonly RuleDomainObject sut;
public Guid RuleId { get; } = Guid.NewGuid();
public RuleDomainObjectTests()
{
sut = new RuleDomainObject();
}
[Fact]
public void Create_should_throw_exception_if_created()
{
sut.Create(new CreateRule { Trigger = ruleTrigger, Action = ruleAction });
Assert.Throws<DomainException>(() =>
{
sut.Create(CreateRuleCommand(new CreateRule { Trigger = ruleTrigger, Action = ruleAction }));
});
}
[Fact]
public void Create_should_create_events()
{
var command = new CreateRule { Trigger = ruleTrigger, Action = ruleAction };
sut.Create(CreateRuleCommand(command));
Assert.Same(ruleTrigger, sut.State.RuleDef.Trigger);
Assert.Same(ruleAction, sut.State.RuleDef.Action);
sut.GetUncomittedEvents()
.ShouldHaveSameEvents(
CreateRuleEvent(new RuleCreated { Trigger = ruleTrigger, Action = ruleAction })
);
}
[Fact]
public void Update_should_throw_exception_if_not_created()
{
Assert.Throws<DomainException>(() =>
{
sut.Update(CreateRuleCommand(new UpdateRule { Trigger = ruleTrigger, Action = ruleAction }));
});
}
[Fact]
public void Update_should_throw_exception_if_rule_is_deleted()
{
CreateRule();
DeleteRule();
Assert.Throws<DomainException>(() =>
{
sut.Update(CreateRuleCommand(new UpdateRule { Trigger = ruleTrigger, Action = ruleAction }));
});
}
[Fact]
public void Update_should_create_events()
{
var newTrigger = new ContentChangedTrigger
{
Schemas = ImmutableList<ContentChangedTriggerSchema>.Empty
};
var newAction = new WebhookAction
{
Url = new Uri("https://squidex.io/v2")
};
CreateRule();
var command = new UpdateRule { Trigger = newTrigger, Action = newAction };
sut.Update(CreateRuleCommand(command));
Assert.Same(newTrigger, sut.State.RuleDef.Trigger);
Assert.Same(newAction, sut.State.RuleDef.Action);
sut.GetUncomittedEvents()
.ShouldHaveSameEvents(
CreateRuleEvent(new RuleUpdated { Trigger = newTrigger, Action = newAction })
);
}
[Fact]
public void Enable_should_throw_exception_if_not_created()
{
Assert.Throws<DomainException>(() =>
{
sut.Enable(CreateRuleCommand(new EnableRule()));
});
}
[Fact]
public void Enable_should_throw_exception_if_rule_is_deleted()
{
CreateRule();
DeleteRule();
Assert.Throws<DomainException>(() =>
{
sut.Enable(CreateRuleCommand(new EnableRule()));
});
}
[Fact]
public void Enable_should_create_events()
{
CreateRule();
var command = new EnableRule();
sut.Enable(CreateRuleCommand(command));
Assert.True(sut.State.RuleDef.IsEnabled);
sut.GetUncomittedEvents()
.ShouldHaveSameEvents(
CreateRuleEvent(new RuleEnabled())
);
}
[Fact]
public void Disable_should_throw_exception_if_not_created()
{
Assert.Throws<DomainException>(() =>
{
sut.Disable(CreateRuleCommand(new DisableRule()));
});
}
[Fact]
public void Disable_should_throw_exception_if_rule_is_deleted()
{
CreateRule();
DeleteRule();
Assert.Throws<DomainException>(() =>
{
sut.Disable(CreateRuleCommand(new DisableRule()));
});
}
[Fact]
public void Disable_should_create_events()
{
CreateRule();
var command = new DisableRule();
sut.Disable(CreateRuleCommand(command));
Assert.False(sut.State.RuleDef.IsEnabled);
sut.GetUncomittedEvents()
.ShouldHaveSameEvents(
CreateRuleEvent(new RuleDisabled())
);
}
[Fact]
public void Delete_should_throw_exception_if_not_created()
{
Assert.Throws<DomainException>(() =>
{
sut.Delete(CreateRuleCommand(new DeleteRule()));
});
}
[Fact]
public void Delete_should_throw_exception_if_already_deleted()
{
CreateRule();
DeleteRule();
Assert.Throws<DomainException>(() =>
{
sut.Delete(CreateRuleCommand(new DeleteRule()));
});
}
[Fact]
public void Delete_should_update_create_events()
{
CreateRule();
sut.Delete(CreateRuleCommand(new DeleteRule()));
Assert.True(sut.State.IsDeleted);
sut.GetUncomittedEvents()
.ShouldHaveSameEvents(
CreateRuleEvent(new RuleDeleted())
);
}
private void CreateRule()
{
sut.Create(CreateRuleCommand(new CreateRule { Trigger = ruleTrigger, Action = ruleAction }));
sut.ClearUncommittedEvents();
}
private void DeleteRule()
{
sut.Delete(CreateRuleCommand(new DeleteRule()));
sut.ClearUncommittedEvents();
}
protected T CreateRuleEvent<T>(T @event) where T : RuleEvent
{
@event.RuleId = RuleId;
return CreateEvent(@event);
}
protected T CreateRuleCommand<T>(T command) where T : RuleAggregateCommand
{
command.RuleId = RuleId;
return CreateCommand(command);
}
}
}
Loading…
Cancel
Save