Skip to content

Commit

Permalink
SetDefaultLanguageCommand
Browse files Browse the repository at this point in the history
  • Loading branch information
Utar94 committed Oct 7, 2024
1 parent d7d0df1 commit 7332314
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using Logitar.Cms.Contracts.Languages;
using Logitar.EventSourcing;
using MediatR;

namespace Logitar.Cms.Core.Languages.Commands;

public record SetDefaultLanguageCommand(Guid Id) : Activity, IRequest<LanguageModel?>;

internal class SetDefaultLanguageCommandHandler : IRequestHandler<SetDefaultLanguageCommand, LanguageModel?>
{
private readonly ILanguageQuerier _languageQuerier;
private readonly ILanguageRepository _languageRepository;

public SetDefaultLanguageCommandHandler(ILanguageQuerier languageQuerier, ILanguageRepository languageRepository)
{
_languageQuerier = languageQuerier;
_languageRepository = languageRepository;
}

public async Task<LanguageModel?> Handle(SetDefaultLanguageCommand command, CancellationToken cancellationToken)
{
LanguageId languageId = new(command.Id);
Language? language = await _languageRepository.LoadAsync(languageId, cancellationToken);
if (language == null)
{
return null;
}
else if (!language.IsDefault)
{
ActorId actorId = command.GetActorId();

Language @default = await _languageRepository.LoadDefaultAsync(cancellationToken);
@default.SetDefault(isDefault: false, actorId);

language.SetDefault(actorId);

await _languageRepository.SaveAsync([@default, language], cancellationToken);
}

return await _languageQuerier.ReadAsync(language, cancellationToken);
}
}
1 change: 1 addition & 0 deletions backend/src/Logitar.Cms.Core/Languages/ILanguageQuerier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ public interface ILanguageQuerier
Task<LanguageModel?> ReadAsync(LanguageId id, CancellationToken cancellationToken = default);
Task<LanguageModel?> ReadAsync(Guid id, CancellationToken cancellationToken = default);
Task<LanguageModel?> ReadAsync(string locale, CancellationToken cancellationToken = default);
Task<LanguageModel> ReadDefaultAsync(CancellationToken cancellationToken = default);
}
2 changes: 2 additions & 0 deletions backend/src/Logitar.Cms.Core/Languages/ILanguageRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ public interface ILanguageRepository
Task<Language?> LoadAsync(LanguageId id, CancellationToken cancellationToken = default);
Task<Language?> LoadAsync(LanguageId id, long? version, CancellationToken cancellationToken = default);

Task<Language> LoadDefaultAsync(CancellationToken cancellationToken = default);

Task SaveAsync(Language language, CancellationToken cancellationToken = default);
Task SaveAsync(IEnumerable<Language> languages, CancellationToken cancellationToken = default);
}
23 changes: 23 additions & 0 deletions backend/src/Logitar.Cms.Core/Languages/Language.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,19 @@ protected virtual void Apply(CreatedEvent @event)
_locale = @event.Locale;
}

public void SetDefault(ActorId actorId = default) => SetDefault(isDefault: true, actorId);
public void SetDefault(bool isDefault, ActorId actorId = default)
{
if (IsDefault != isDefault)
{
Raise(new SetDefaultEvent(isDefault), actorId);
}
}
protected virtual void Apply(SetDefaultEvent @event)
{
IsDefault = @event.IsDefault;
}

public void Update(ActorId actorId = default)
{
if (_updatedEvent.HasChanges)
Expand Down Expand Up @@ -65,6 +78,16 @@ public CreatedEvent(bool isDefault, Locale locale)
}
}

public class SetDefaultEvent : DomainEvent, INotification
{
public bool IsDefault { get; }

public SetDefaultEvent(bool isDefault)
{
IsDefault = isDefault;
}
}

public class UpdatedEvent : DomainEvent, INotification
{
public Locale? Locale { get; set; }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using Logitar.Cms.Contracts.Languages;
using Moq;

namespace Logitar.Cms.Core.Languages.Commands;

[Trait(Traits.Category, Categories.Unit)]
public class SetDefaultLanguageCommandHandlerTests
{
private readonly CancellationToken _cancellationToken = default;

private readonly Mock<ILanguageQuerier> _languageQuerier = new();
private readonly Mock<ILanguageRepository> _languageRepository = new();

private readonly SetDefaultLanguageCommandHandler _handler;

private readonly Language _default = new(new Locale("en"), isDefault: true);
private readonly Language _language = new(new Locale("fr"));

public SetDefaultLanguageCommandHandlerTests()
{
_handler = new(_languageQuerier.Object, _languageRepository.Object);

_languageRepository.Setup(x => x.LoadAsync(_default.Id, _cancellationToken)).ReturnsAsync(_default);
_languageRepository.Setup(x => x.LoadAsync(_language.Id, _cancellationToken)).ReturnsAsync(_language);
_languageRepository.Setup(x => x.LoadDefaultAsync(_cancellationToken)).ReturnsAsync(_default);
}

[Fact(DisplayName = "It should do nothing when the language is already default.")]
public async Task It_should_do_nothing_when_the_language_is_already_default()
{
LanguageModel model = new();
_languageQuerier.Setup(x => x.ReadAsync(_default, _cancellationToken)).ReturnsAsync(model);

SetDefaultLanguageCommand command = new(_default.Id.ToGuid());

LanguageModel? result = await _handler.Handle(command, _cancellationToken);
Assert.NotNull(result);
Assert.Same(model, result);

_languageRepository.Verify(x => x.LoadDefaultAsync(It.IsAny<CancellationToken>()), Times.Never);
_languageRepository.Verify(x => x.SaveAsync(It.IsAny<IEnumerable<Language>>(), It.IsAny<CancellationToken>()), Times.Never);
}

[Fact(DisplayName = "It should return null when the language could not be found.")]
public async Task It_should_return_null_when_the_language_could_not_be_found()
{
SetDefaultLanguageCommand command = new(Guid.NewGuid());

Assert.Null(await _handler.Handle(command, _cancellationToken));
}

[Fact(DisplayName = "It should set the default language.")]
public async Task It_should_set_the_default_language()
{
LanguageModel model = new();
_languageQuerier.Setup(x => x.ReadAsync(_language, _cancellationToken)).ReturnsAsync(model);

SetDefaultLanguageCommand command = new(_language.Id.ToGuid());

LanguageModel? result = await _handler.Handle(command, _cancellationToken);
Assert.NotNull(result);
Assert.Same(model, result);

Assert.False(_default.IsDefault);
Assert.True(_language.IsDefault);

_languageRepository.Verify(x => x.LoadDefaultAsync(_cancellationToken), Times.Once);
_languageRepository.Verify(x => x.SaveAsync(
It.Is<IEnumerable<Language>>(y => y.SequenceEqual(new Language[] { _default, _language })),
_cancellationToken), Times.Once);
}
}

0 comments on commit 7332314

Please sign in to comment.