Skip to content

Commit

Permalink
Application new feature: edit discussion entry
Browse files Browse the repository at this point in the history
  • Loading branch information
VoltanFr committed Mar 4, 2024
1 parent f2c0a8b commit aa1e063
Show file tree
Hide file tree
Showing 10 changed files with 943 additions and 2 deletions.
46 changes: 46 additions & 0 deletions MemCheck.Application/Cards/EditCardDiscussionEntry.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using MemCheck.Application.QueryValidation;
using Microsoft.EntityFrameworkCore;
using System;
using System.Threading.Tasks;

namespace MemCheck.Application.Cards;

public sealed class EditCardDiscussionEntry : RequestRunner<EditCardDiscussionEntry.Request, EditCardDiscussionEntry.Result>
{
#region Fields
private readonly DateTime runUtcDate;
#endregion
public EditCardDiscussionEntry(CallContext callContext, DateTime? runUtcDate = null) : base(callContext)
{
this.runUtcDate = runUtcDate ?? DateTime.UtcNow;
}
protected override async Task<ResultWithMetrologyProperties<Result>> DoRunAsync(Request request)
{
var previousVersionCreator = new PreviousCardDiscussionEntryVersionCreator(DbContext);
var entry = await previousVersionCreator.RunAsync(request.EntryId, runUtcDate);
entry.Text = request.Text;
await DbContext.SaveChangesAsync();
return new ResultWithMetrologyProperties<Result>(new Result(), ("EntryId", request.EntryId.ToString()));
}
#region Request & Result records
public sealed record Request(Guid UserId, Guid EntryId, string Text) : IRequest
{
public async Task CheckValidityAsync(CallContext callContext)
{
await QueryValidationHelper.CheckUserExistsAsync(callContext.DbContext, UserId);

var entry = await callContext.DbContext.CardDiscussionEntries.AsNoTracking()
.Include(entry => entry.Creator)
.SingleOrDefaultAsync(entry => entry.Id == EntryId);
if (entry == null)
throw new NonexistentCardDiscussionEntryException();

await QueryValidationHelper.CheckCardExistsAsync(callContext.DbContext, entry.Card); // Not really needed, and not checked by a unit test - just a security
CardVisibilityHelper.CheckUserIsAllowedToViewCard(callContext.DbContext, UserId, entry.Card);
QueryValidationHelper.CheckCanCreateCardDiscussionEntryWithText(Text);
QueryValidationHelper.CheckUserCanEditCardDiscussionEntry(UserId, entry);
}
}
public sealed record Result();
#endregion
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using MemCheck.Database;
using MemCheck.Domain;
using Microsoft.EntityFrameworkCore;
using System;
using System.Threading.Tasks;

namespace MemCheck.Application.Cards;

internal sealed class PreviousCardDiscussionEntryVersionCreator
{
#region Fields
private readonly MemCheckDbContext dbContext;
#endregion
#region Private methods
private async Task<CardDiscussionEntryPreviousVersion> CreatePreviousVersionAsync(CardDiscussionEntry entry, DateTime? versionUtcDate = null)
{
var previousVersion = new CardDiscussionEntryPreviousVersion()
{
Card = entry.Card,
Creator = entry.Creator,
Text = entry.Text,
CreationUtcDate = versionUtcDate ?? entry.CreationUtcDate,
PreviousVersion = entry.PreviousVersion,
};
await dbContext.CardDiscussionEntryPreviousVersions.AddAsync(previousVersion);
return previousVersion;
}
#endregion
public PreviousCardDiscussionEntryVersionCreator(MemCheckDbContext dbContext)
{
this.dbContext = dbContext;
}
public async Task<CardDiscussionEntry> RunAsync(Guid entryId, DateTime? newVersionUtcDate = null)
{
var entry = await dbContext.CardDiscussionEntries
.Include(entry => entry.Creator)
.Include(entry => entry.PreviousVersion)
.SingleAsync(entry => entry.Id == entryId);

var previousVersion = await CreatePreviousVersionAsync(entry);
entry.PreviousVersion = previousVersion;
entry.CreationUtcDate = newVersionUtcDate ?? DateTime.UtcNow;
return entry;
}
}
2 changes: 1 addition & 1 deletion MemCheck.Application/MemCheck.Application.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Library</OutputType>
<VersionPrefix>0.58.1</VersionPrefix>
<VersionPrefix>0.59.0</VersionPrefix>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;

namespace MemCheck.Application.QueryValidation;

public class NonexistentCardDiscussionEntryException : InvalidOperationException
{
public NonexistentCardDiscussionEntryException(string message) : base(message)
{
}
public NonexistentCardDiscussionEntryException(string message, Exception innerException) : base(message, innerException)
{
}
public NonexistentCardDiscussionEntryException()
{
}
}
6 changes: 6 additions & 0 deletions MemCheck.Application/QueryValidation/QueryValidationHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,12 @@ public static void CheckCanCreateCardDiscussionEntryWithText(string text)
if (text.Length > CardDiscussionMaxTextLength)
throw new TextTooLongException(text.Length, CardDiscussionMinTextLength, CardDiscussionMaxTextLength);
}
public static void CheckUserCanEditCardDiscussionEntry(Guid userId, CardDiscussionEntry entry)
{
// We could consider allowing administrators to edit discussion entries, but this is not implemented yet
if (entry.Creator.Id != userId)
throw new UserNotAllowedToEditDiscussionEntryException();
}
public static bool TagIsPerso(Guid tagId, MemCheckDbContext dbContext)
{
var tag = dbContext.Tags.AsNoTracking().Single(tag => tag.Id == tagId);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;

namespace MemCheck.Application.QueryValidation;

public class UserNotAllowedToEditDiscussionEntryException : InvalidOperationException
{
public UserNotAllowedToEditDiscussionEntryException(string message) : base(message)
{
}
public UserNotAllowedToEditDiscussionEntryException(string message, Exception innerException) : base(message, innerException)
{
}
public UserNotAllowedToEditDiscussionEntryException()
{
}
}
Loading

0 comments on commit aa1e063

Please sign in to comment.