Skip to content

Commit

Permalink
Added validation for review target
Browse files Browse the repository at this point in the history
  • Loading branch information
dyatlov-a committed Sep 19, 2024
1 parent 3c326bd commit 3523489
Show file tree
Hide file tree
Showing 11 changed files with 80 additions and 15 deletions.
8 changes: 8 additions & 0 deletions src/Inc.TeamAssistant.Connector.DataAccess/Messages.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Inc.TeamAssistant.Primitives.Languages;

namespace Inc.TeamAssistant.Connector.DataAccess;

public static class Messages
{
public static readonly MessageId Connector_PersonNotFound = new(nameof(Connector_PersonNotFound));
}
9 changes: 9 additions & 0 deletions src/Inc.TeamAssistant.Connector.DataAccess/TeamAccessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ public async Task<IReadOnlyCollection<Person>> GetTeammates(
return await _personRepository.Find(personId, token);
}

public async Task<Person> GetPerson(long personId, CancellationToken token)
{
var person = await _personRepository.Find(personId, token);
if (person is null)
throw new TeamAssistantUserException(Messages.Connector_PersonNotFound, personId);

return person;
}

public async Task<LanguageId> GetClientLanguage(Guid botId, long personId, CancellationToken token)
{
return await _clientLanguageRepository.Get(botId, personId, token);
Expand Down
1 change: 1 addition & 0 deletions src/Inc.TeamAssistant.Gateway/wwwroot/langs/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@
"Reviewer_PreviewTitle": "Previewing a draft of the task for review.",
"Reviewer_PreviewReviewerTemplate": "The task will be assigned to {0}",
"Reviewer_PreviewCheckDescription": "You need to provide a link to the source code and a description.",
"Reviewer_PreviewCheckTeammate": "Participant {0} is not part of team {1}.",
"Reviewer_PreviewEditHelp": "To edit a draft, please edit the original post.",
"Reviewer_PreviewMoveToReview": "Submit",
"Reviewer_PreviewRemoveDraft": "Cancel",
Expand Down
1 change: 1 addition & 0 deletions src/Inc.TeamAssistant.Gateway/wwwroot/langs/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@
"Reviewer_PreviewTitle": "Предварительный просмотр черновика задачи на ревью.",
"Reviewer_PreviewReviewerTemplate": "Задача будет назначена на {0}",
"Reviewer_PreviewCheckDescription": "Необходимо указать ссылку на исходный код и описание.",
"Reviewer_PreviewCheckTeammate": "Участник {0} не подключен к команде {1}.",
"Reviewer_PreviewEditHelp": "Для редактирования черновика необходимо отредактировать исходное сообщение.",
"Reviewer_PreviewMoveToReview": "Отправить на ревью",
"Reviewer_PreviewRemoveDraft": "Отменить",
Expand Down
1 change: 1 addition & 0 deletions src/Inc.TeamAssistant.Primitives/ITeamAccessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ public interface ITeamAccessor
Task<(Guid BotId, string TeamName)> GetTeamContext(Guid teamId, CancellationToken token);
Task<IReadOnlyCollection<Person>> GetTeammates(Guid teamId, DateTimeOffset now, CancellationToken token);
Task<Person?> FindPerson(long personId, CancellationToken token);
Task<Person> GetPerson(long personId, CancellationToken token);
Task<LanguageId> GetClientLanguage(Guid botId, long personId, CancellationToken token);
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ public async Task<CommandResult> Handle(EditDraftCommand command, CancellationTo
if (draft is not null)
{
draft.WithDescription(command.Description);

if (command.MessageContext.TargetPersonId.HasValue)
draft.WithTargetPerson(command.MessageContext.TargetPersonId.Value);
else
draft.WithoutTargetPerson();

var notification = await _reviewMessageBuilder.Build(draft, command.MessageContext.LanguageId, token);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,25 @@ public MoveToReviewCommandValidator(

RuleFor(e => e.DraftId)
.NotEmpty()
.MustAsync(HasDescriptionAndLinks)
.WithMessage("'Description' must contains a link to the source code and some description");
.CustomAsync(ValidateDraft);
}

private async Task<bool> HasDescriptionAndLinks(Guid draftId, CancellationToken token)
private async Task ValidateDraft(
Guid draftId,
ValidationContext<MoveToReviewCommand> context,
CancellationToken token)
{
ArgumentNullException.ThrowIfNull(context);

var draft = await _draftTaskForReviewRepository.GetById(draftId, token);

return _draftTaskForReviewService.HasDescriptionAndLinks(draft.Description);
if (!_draftTaskForReviewService.HasDescriptionAndLinks(draft.Description))
context.AddFailure(
nameof(draft.Description),
"Must contains a link to the source code and some description");

if (draft.TargetPersonId.HasValue &&
!await _draftTaskForReviewService.HasTeammate(draft.TeamId, draft.TargetPersonId.Value, token))
context.AddFailure(nameof(draft.TargetPersonId), "Teammate not found");
}
}
1 change: 1 addition & 0 deletions src/Inc.TeamAssistant.Reviewer.Application/Messages.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ internal static class Messages
public static readonly MessageId Reviewer_PreviewTitle = new(nameof(Reviewer_PreviewTitle));
public static readonly MessageId Reviewer_PreviewReviewerTemplate = new(nameof(Reviewer_PreviewReviewerTemplate));
public static readonly MessageId Reviewer_PreviewCheckDescription = new(nameof(Reviewer_PreviewCheckDescription));
public static readonly MessageId Reviewer_PreviewCheckTeammate = new(nameof(Reviewer_PreviewCheckTeammate));
public static readonly MessageId Reviewer_PreviewEditHelp = new(nameof(Reviewer_PreviewEditHelp));
public static readonly MessageId Reviewer_PreviewMoveToReview = new(nameof(Reviewer_PreviewMoveToReview));
public static readonly MessageId Reviewer_PreviewRemoveDraft = new(nameof(Reviewer_PreviewRemoveDraft));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,22 @@ namespace Inc.TeamAssistant.Reviewer.Application.Services;
internal sealed class DraftTaskForReviewService
{
private readonly IDraftTaskForReviewRepository _draftTaskForReviewRepository;
private readonly ITeamAccessor _teamAccessor;

public DraftTaskForReviewService(IDraftTaskForReviewRepository draftTaskForReviewRepository)
public DraftTaskForReviewService(
IDraftTaskForReviewRepository draftTaskForReviewRepository,
ITeamAccessor teamAccessor)
{
_draftTaskForReviewRepository =
draftTaskForReviewRepository ?? throw new ArgumentNullException(nameof(draftTaskForReviewRepository));
_teamAccessor = teamAccessor ?? throw new ArgumentNullException(nameof(teamAccessor));
}

public async Task<bool> HasTeammate(Guid teamId, long personId, CancellationToken token)
{
var teammates = await _teamAccessor.GetTeammates(teamId, DateTimeOffset.UtcNow, token);

return teammates.Any(t => t.Id == personId);
}

public bool HasDescriptionAndLinks(string description)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,24 +106,37 @@ public async Task<NotificationMessage> Build(
ArgumentNullException.ThrowIfNull(draft);
ArgumentNullException.ThrowIfNull(languageId);

var teamContext = await _teamAccessor.GetTeamContext(draft.TeamId, token);
var reviewTargetMessageTemplate = await _messageBuilder.Build(
Messages.Reviewer_PreviewReviewerTemplate,
languageId);
var messageBuilder = new StringBuilder();

messageBuilder.AppendLine(await _messageBuilder.Build(Messages.Reviewer_PreviewTitle, languageId));
messageBuilder.AppendLine();
messageBuilder.AppendLine(draft.Description);
messageBuilder.AppendLine();

if (draft.TargetPersonId.HasValue)
{
var targetPersonMessageTemplate = await _messageBuilder.Build(
Messages.Reviewer_PreviewReviewerTemplate,
languageId);
var targetPerson = await _teamAccessor.FindPerson(draft.TargetPersonId.Value, token);
if (targetPerson is null)
throw new TeamAssistantUserException(Messages.Connector_PersonNotFound, draft.TargetPersonId.Value);
var reviewTarget = await _teamAccessor.GetPerson(draft.TargetPersonId.Value, token);
messageBuilder.AppendLine(string.Format(reviewTargetMessageTemplate, reviewTarget.DisplayName));

messageBuilder.AppendLine();
messageBuilder.AppendLine(string.Format(targetPersonMessageTemplate, targetPerson.DisplayName));
if (!await _service.HasTeammate(draft.TeamId, draft.TargetPersonId.Value, token))
{
messageBuilder.AppendLine();
messageBuilder.Append('❗');
messageBuilder.Append(await _messageBuilder.Build(
Messages.Reviewer_PreviewCheckTeammate,
languageId,
reviewTarget.DisplayName,
teamContext.TeamName));
messageBuilder.AppendLine();
}
}

else
messageBuilder.AppendLine(string.Format(reviewTargetMessageTemplate, teamContext.TeamName));

if (!_service.HasDescriptionAndLinks(draft.Description))
{
messageBuilder.AppendLine();
Expand Down
7 changes: 7 additions & 0 deletions src/Inc.TeamAssistant.Reviewer.Domain/DraftTaskForReview.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ public DraftTaskForReview WithTargetPerson(long personId)
return this;
}

public DraftTaskForReview WithoutTargetPerson()
{
TargetPersonId = null;

return this;
}

public DraftTaskForReview WithPreviewMessage(int messageId)
{
PreviewMessageId = messageId;
Expand Down

0 comments on commit 3523489

Please sign in to comment.