From aba0694d141358db2846c7ad8ce991acf2cab444 Mon Sep 17 00:00:00 2001 From: dyatlov-a Date: Sun, 22 Sep 2024 15:02:25 +0400 Subject: [PATCH] Refactoring ReviewMessageBuilder --- .../Contracts/IReviewMessageBuilder.cs | 4 +- .../Services/ReviewMessageBuilder.cs | 219 +++++++++--------- 2 files changed, 114 insertions(+), 109 deletions(-) diff --git a/src/Inc.TeamAssistant.Reviewer.Application/Contracts/IReviewMessageBuilder.cs b/src/Inc.TeamAssistant.Reviewer.Application/Contracts/IReviewMessageBuilder.cs index 29704528..1ce791e7 100644 --- a/src/Inc.TeamAssistant.Reviewer.Application/Contracts/IReviewMessageBuilder.cs +++ b/src/Inc.TeamAssistant.Reviewer.Application/Contracts/IReviewMessageBuilder.cs @@ -9,12 +9,12 @@ public interface IReviewMessageBuilder { Task> Build( int messageId, - TaskForReview taskForReview, + TaskForReview task, Person reviewer, Person owner, CancellationToken token); - Task Push(TaskForReview taskForReview, CancellationToken token); + Task Push(TaskForReview task, CancellationToken token); Task Build(DraftTaskForReview draft, LanguageId languageId, CancellationToken token); } \ No newline at end of file diff --git a/src/Inc.TeamAssistant.Reviewer.Application/Services/ReviewMessageBuilder.cs b/src/Inc.TeamAssistant.Reviewer.Application/Services/ReviewMessageBuilder.cs index cc46094b..b22fa2b0 100644 --- a/src/Inc.TeamAssistant.Reviewer.Application/Services/ReviewMessageBuilder.cs +++ b/src/Inc.TeamAssistant.Reviewer.Application/Services/ReviewMessageBuilder.cs @@ -14,84 +14,85 @@ internal sealed class ReviewMessageBuilder : IReviewMessageBuilder { private readonly IMessageBuilder _messageBuilder; private readonly ITeamAccessor _teamAccessor; - private readonly ITaskForReviewReader _taskForReviewReader; + private readonly ITaskForReviewReader _taskReader; private readonly IReviewMetricsProvider _metricsProvider; private readonly ReviewTeamMetricsFactory _metricsFactory; - private readonly DraftTaskForReviewService _service; + private readonly DraftTaskForReviewService _draftService; public ReviewMessageBuilder( IMessageBuilder messageBuilder, ITeamAccessor teamAccessor, - ITaskForReviewReader taskForReviewReader, + ITaskForReviewReader taskReader, IReviewMetricsProvider metricsProvider, ReviewTeamMetricsFactory metricsFactory, - DraftTaskForReviewService service) + DraftTaskForReviewService draftService) { _messageBuilder = messageBuilder ?? throw new ArgumentNullException(nameof(messageBuilder)); _teamAccessor = teamAccessor ?? throw new ArgumentNullException(nameof(teamAccessor)); - _taskForReviewReader = taskForReviewReader ?? throw new ArgumentNullException(nameof(taskForReviewReader)); + _taskReader = taskReader ?? throw new ArgumentNullException(nameof(taskReader)); _metricsProvider = metricsProvider ?? throw new ArgumentNullException(nameof(metricsProvider)); _metricsFactory = metricsFactory ?? throw new ArgumentNullException(nameof(metricsFactory)); - _service = service ?? throw new ArgumentNullException(nameof(service)); + _draftService = draftService ?? throw new ArgumentNullException(nameof(draftService)); } public async Task> Build( int messageId, - TaskForReview taskForReview, + TaskForReview task, Person reviewer, Person owner, CancellationToken token) { - ArgumentNullException.ThrowIfNull(taskForReview); + ArgumentNullException.ThrowIfNull(task); ArgumentNullException.ThrowIfNull(reviewer); ArgumentNullException.ThrowIfNull(owner); - var metricsByTeam = _metricsProvider.Get(taskForReview.TeamId); - var metricsByTask = await _metricsFactory.Create(taskForReview, token); + var metricsByTeam = _metricsProvider.Get(task.TeamId); + var metricsByTask = await _metricsFactory.Create(task, token); + var hasOwnerAction = messageId == task.OwnerMessageId; var notifications = new List { - await MessageForTeam(taskForReview, reviewer, owner, metricsByTeam, metricsByTask, token), - await MessageForReviewer(taskForReview, metricsByTeam, metricsByTask, token) + await MessageForTeam(task, reviewer, owner, metricsByTeam, metricsByTask, token), + await MessageForReviewer(task, metricsByTeam, metricsByTask, token) }; - if (!taskForReview.ReviewerMessageId.HasValue && taskForReview.OriginalReviewerId.HasValue) - notifications.Add(await HideControlsForReviewer( - taskForReview.OriginalReviewerId.Value, + if (!task.ReviewerMessageId.HasValue && task.OriginalReviewerId.HasValue) + notifications.Add(await HideControlsForOriginalReviewer( + task.OriginalReviewerId.Value, messageId, - taskForReview, + task, token)); - if (taskForReview.State == TaskForReviewState.OnCorrection || messageId == taskForReview.OwnerMessageId) - notifications.Add(await MessageForOwner(taskForReview, metricsByTeam, metricsByTask, token)); + if (task.State == TaskForReviewState.OnCorrection || hasOwnerAction) + notifications.Add(await MessageForOwner(task, metricsByTeam, metricsByTask, token)); - if (taskForReview.State == TaskForReviewState.Accept) - notifications.Add(await ReviewFinish(taskForReview, token)); + if (task.State == TaskForReviewState.Accept) + notifications.Add(await ReviewFinish(task, token)); return notifications; } - public async Task Push(TaskForReview taskForReview, CancellationToken token) + public async Task Push(TaskForReview task, CancellationToken token) { - ArgumentNullException.ThrowIfNull(taskForReview); + ArgumentNullException.ThrowIfNull(task); - var totalTime = taskForReview.GetTotalTime(DateTimeOffset.UtcNow); + var totalTime = task.GetTotalTime(DateTimeOffset.UtcNow); - return taskForReview switch + return task switch { { State: TaskForReviewState.New or TaskForReviewState.InProgress, ReviewerMessageId: not null } => await CreatePushMessage( - taskForReview.BotId, - taskForReview.ReviewerId, - taskForReview.ReviewerMessageId.Value, + task.BotId, + task.ReviewerId, + task.ReviewerMessageId.Value, Messages.Reviewer_NeedEndReview, totalTime, token), { State: TaskForReviewState.OnCorrection, OwnerMessageId: not null } => await CreatePushMessage( - taskForReview.BotId, - taskForReview.OwnerId, - taskForReview.OwnerMessageId.Value, + task.BotId, + task.OwnerId, + task.OwnerMessageId.Value, Messages.Reviewer_NeedCorrection, totalTime, token), @@ -111,44 +112,44 @@ public async Task Build( var reviewTargetMessageTemplate = await _messageBuilder.Build( Messages.Reviewer_PreviewReviewerTemplate, languageId); - var messageBuilder = new StringBuilder(); + var builder = new StringBuilder(); - messageBuilder.AppendLine(await _messageBuilder.Build(Messages.Reviewer_PreviewTitle, languageId)); - messageBuilder.AppendLine(); - messageBuilder.AppendLine(draft.Description); - messageBuilder.AppendLine(); + builder.AppendLine(await _messageBuilder.Build(Messages.Reviewer_PreviewTitle, languageId)); + builder.AppendLine(); + builder.AppendLine(draft.Description); + builder.AppendLine(); if (draft.TargetPersonId.HasValue) { var reviewTarget = await _teamAccessor.GetPerson(draft.TargetPersonId.Value, token); - messageBuilder.AppendLine(string.Format(reviewTargetMessageTemplate, reviewTarget.DisplayName)); + builder.AppendLine(string.Format(reviewTargetMessageTemplate, reviewTarget.DisplayName)); - if (!await _service.HasTeammate(draft.TeamId, draft.TargetPersonId.Value, token)) + if (!await _draftService.HasTeammate(draft.TeamId, draft.TargetPersonId.Value, token)) { - messageBuilder.AppendLine(); - messageBuilder.Append(Icons.Alert); - messageBuilder.Append(await _messageBuilder.Build( + builder.AppendLine(); + builder.Append(Icons.Alert); + builder.Append(await _messageBuilder.Build( Messages.Reviewer_PreviewCheckTeammate, languageId, reviewTarget.DisplayName, teamContext.TeamName)); - messageBuilder.AppendLine(); + builder.AppendLine(); } } else - messageBuilder.AppendLine(string.Format(reviewTargetMessageTemplate, teamContext.TeamName)); + builder.AppendLine(string.Format(reviewTargetMessageTemplate, teamContext.TeamName)); - if (!_service.HasDescriptionAndLinks(draft.Description)) + if (!_draftService.HasDescriptionAndLinks(draft.Description)) { - messageBuilder.AppendLine(); - messageBuilder.Append(Icons.Alert); - messageBuilder.Append(await _messageBuilder.Build(Messages.Reviewer_PreviewCheckDescription, languageId)); - messageBuilder.AppendLine(); + builder.AppendLine(); + builder.Append(Icons.Alert); + builder.Append(await _messageBuilder.Build(Messages.Reviewer_PreviewCheckDescription, languageId)); + builder.AppendLine(); } - messageBuilder.AppendLine(); - messageBuilder.AppendLine(await _messageBuilder.Build(Messages.Reviewer_PreviewEditHelp, languageId)); - var message = messageBuilder.ToString(); + builder.AppendLine(); + builder.AppendLine(await _messageBuilder.Build(Messages.Reviewer_PreviewEditHelp, languageId)); + var message = builder.ToString(); var notificationMessage = draft.PreviewMessageId.HasValue ? NotificationMessage.Edit(new ChatMessage(draft.ChatId, draft.PreviewMessageId.Value), message) @@ -177,16 +178,16 @@ await _messageBuilder.Build(Messages.Reviewer_PreviewRemoveDraft, languageId), var languageId = await _teamAccessor.GetClientLanguage(botId, personId, token); - var messageBuilder = new StringBuilder(); - messageBuilder.AppendLine(await _messageBuilder.Build(messageTextId, languageId)); - messageBuilder.AppendLine(); - messageBuilder.AppendLine(await _messageBuilder.Build( + var builder = new StringBuilder(); + builder.AppendLine(await _messageBuilder.Build(messageTextId, languageId)); + builder.AppendLine(); + builder.AppendLine(await _messageBuilder.Build( Messages.Reviewer_TotalTime, languageId, workTimeTotal.ToString(GlobalSettings.TimeFormat))); return NotificationMessage - .Create(personId, messageBuilder.ToString()) + .Create(personId, builder.ToString()) .ReplyTo(messageId); } @@ -206,38 +207,30 @@ private async Task MessageForTeam( Func attachPersons = n => n; var languageId = await _teamAccessor.GetClientLanguage(task.BotId, owner.Id, token); - var state = task.State switch - { - TaskForReviewState.New => Icons.Waiting, - TaskForReviewState.InProgress => Icons.InProgress, - TaskForReviewState.OnCorrection => Icons.OnCorrection, - TaskForReviewState.Accept => Icons.Accept, - _ => throw new ArgumentOutOfRangeException(nameof(task.State), task.State, "State out of range.") - }; var reviewerTargetMessageKey = task.HasConcreteReviewer ? Messages.Reviewer_TargetManually : Messages.Reviewer_TargetAutomatically; - var messageBuilder = new StringBuilder(); - messageBuilder.AppendLine(await _messageBuilder.Build(Messages.Reviewer_NewTaskForReview, languageId)); - messageBuilder.AppendLine(await _messageBuilder.Build(Messages.Reviewer_Owner, languageId, owner.DisplayName)); + var builder = new StringBuilder(); + builder.AppendLine(await _messageBuilder.Build(Messages.Reviewer_NewTaskForReview, languageId)); + builder.AppendLine(await _messageBuilder.Build(Messages.Reviewer_Owner, languageId, owner.DisplayName)); - messageBuilder.Append(await _messageBuilder.Build(reviewerTargetMessageKey, languageId)); - reviewer.Append(messageBuilder, (p, o) => attachPersons += n => n.AttachPerson(p, o)); - messageBuilder.AppendLine(); + builder.Append(await _messageBuilder.Build(reviewerTargetMessageKey, languageId)); + reviewer.Append(builder, (p, o) => attachPersons += n => n.AttachPerson(p, o)); + builder.AppendLine(); - messageBuilder.AppendLine(); - messageBuilder.AppendLine(task.Description); - messageBuilder.AppendLine(state); + builder.AppendLine(); + builder.AppendLine(task.Description); + builder.AppendLine(StateAsIcon(task)); var stats = await ReviewStatsBuilder .Create(_messageBuilder) .WithReviewMetrics() .WithCorrectionMetrics() .Build(task, metricsByTeam, metricsByTask, languageId); - messageBuilder.Append(stats); + builder.Append(stats); - var message = messageBuilder.ToString(); + var message = builder.ToString(); var notification = task.MessageId.HasValue ? NotificationMessage.Edit(new ChatMessage(task.ChatId, task.MessageId.Value), message) : NotificationMessage @@ -251,22 +244,22 @@ private async Task MessageForTeam( return attachPersons(notification); } - private async Task HideControlsForReviewer( + private async Task HideControlsForOriginalReviewer( long reviewerId, int messageId, - TaskForReview taskForReview, + TaskForReview task, CancellationToken token) { - ArgumentNullException.ThrowIfNull(taskForReview); + ArgumentNullException.ThrowIfNull(task); - var languageId = await _teamAccessor.GetClientLanguage(taskForReview.BotId, reviewerId, token); + var languageId = await _teamAccessor.GetClientLanguage(task.BotId, reviewerId, token); - var messageBuilder = new StringBuilder(); - messageBuilder.AppendLine(await _messageBuilder.Build(Messages.Reviewer_NeedReview, languageId)); - messageBuilder.AppendLine(); - messageBuilder.AppendLine(taskForReview.Description); + var builder = new StringBuilder(); + builder.AppendLine(await _messageBuilder.Build(Messages.Reviewer_NeedReview, languageId)); + builder.AppendLine(); + builder.AppendLine(task.Description); - return NotificationMessage.Edit(new(reviewerId, messageId), messageBuilder.ToString()); + return NotificationMessage.Edit(new(reviewerId, messageId), builder.ToString()); } private async Task MessageForReviewer( @@ -280,18 +273,18 @@ private async Task MessageForReviewer( ArgumentNullException.ThrowIfNull(metricsByTask); var languageId = await _teamAccessor.GetClientLanguage(task.BotId, task.ReviewerId, token); - var messageBuilder = new StringBuilder(); - messageBuilder.AppendLine(await _messageBuilder.Build(Messages.Reviewer_NeedReview, languageId)); - messageBuilder.AppendLine(); - messageBuilder.AppendLine(task.Description); + var builder = new StringBuilder(); + builder.AppendLine(await _messageBuilder.Build(Messages.Reviewer_NeedReview, languageId)); + builder.AppendLine(); + builder.AppendLine(task.Description); var stats = await ReviewStatsBuilder .Create(_messageBuilder) .WithReviewMetrics() .Build(task, metricsByTeam, metricsByTask, languageId); - messageBuilder.Append(stats); + builder.Append(stats); - var message = messageBuilder.ToString(); + var message = builder.ToString(); var notification = task.ReviewerMessageId.HasValue ? NotificationMessage.Edit(new(task.ReviewerId, task.ReviewerMessageId.Value), message) : NotificationMessage @@ -310,7 +303,7 @@ private async Task MessageForReviewer( $"{CommandList.MoveToInProgress}{task.Id:N}")); var fromDate = DateTimeOffset.UtcNow.GetLastDayOfWeek(DayOfWeek.Monday); - var hasReassign = await _taskForReviewReader.HasReassignFromDate(task.ReviewerId, fromDate, token); + var hasReassign = await _taskReader.HasReassignFromDate(task.ReviewerId, fromDate, token); if (!task.OriginalReviewerId.HasValue && !hasReassign) { var reassignReviewButton = await _messageBuilder.Build(Messages.Reviewer_Reassign, languageId); @@ -343,18 +336,18 @@ private async Task MessageForOwner( ArgumentNullException.ThrowIfNull(metricsByTask); var languageId = await _teamAccessor.GetClientLanguage(task.BotId, task.OwnerId, token); - var messageBuilder = new StringBuilder(); - messageBuilder.AppendLine(await _messageBuilder.Build(Messages.Reviewer_ReviewDeclined, languageId)); - messageBuilder.AppendLine(); - messageBuilder.AppendLine(task.Description); + var builder = new StringBuilder(); + builder.AppendLine(await _messageBuilder.Build(Messages.Reviewer_ReviewDeclined, languageId)); + builder.AppendLine(); + builder.AppendLine(task.Description); var stats = await ReviewStatsBuilder .Create(_messageBuilder) .WithCorrectionMetrics() .Build(task, metricsByTeam, metricsByTask, languageId); - messageBuilder.Append(stats); + builder.Append(stats); - var message = messageBuilder.ToString(); + var message = builder.ToString(); var notification = task.OwnerMessageId.HasValue ? NotificationMessage.Edit(new(task.OwnerId, task.OwnerMessageId.Value), message) : NotificationMessage @@ -375,23 +368,35 @@ private async Task MessageForOwner( return notification; } - private async Task ReviewFinish(TaskForReview taskForReview, CancellationToken token) + private async Task ReviewFinish(TaskForReview task, CancellationToken token) { - ArgumentNullException.ThrowIfNull(taskForReview); + ArgumentNullException.ThrowIfNull(task); - var languageId = await _teamAccessor.GetClientLanguage(taskForReview.BotId, taskForReview.OwnerId, token); - var totalTime = taskForReview.GetTotalTime(DateTimeOffset.UtcNow); + var languageId = await _teamAccessor.GetClientLanguage(task.BotId, task.OwnerId, token); + var totalTime = task.GetTotalTime(DateTimeOffset.UtcNow); - var messageBuilder = new StringBuilder(); - messageBuilder.AppendLine(await _messageBuilder.Build(Messages.Reviewer_Accepted, languageId)); - messageBuilder.AppendLine(); - messageBuilder.AppendLine(taskForReview.Description); - messageBuilder.AppendLine(); - messageBuilder.AppendLine(await _messageBuilder.Build( + var builder = new StringBuilder(); + builder.AppendLine(await _messageBuilder.Build(Messages.Reviewer_Accepted, languageId)); + builder.AppendLine(); + builder.AppendLine(task.Description); + builder.AppendLine(); + builder.AppendLine(await _messageBuilder.Build( Messages.Reviewer_TotalTime, languageId, totalTime.ToString(GlobalSettings.TimeFormat))); - return NotificationMessage.Create(taskForReview.OwnerId, messageBuilder.ToString()); + return NotificationMessage.Create(task.OwnerId, builder.ToString()); + } + + private string StateAsIcon(TaskForReview task) + { + return task.State switch + { + TaskForReviewState.New => Icons.Waiting, + TaskForReviewState.InProgress => Icons.InProgress, + TaskForReviewState.OnCorrection => Icons.OnCorrection, + TaskForReviewState.Accept => Icons.Accept, + _ => throw new ArgumentOutOfRangeException(nameof(task.State), task.State, "State out of range.") + }; } } \ No newline at end of file