Skip to content

Commit

Permalink
Feature/mark operations (#81)
Browse files Browse the repository at this point in the history
* Mark operations

* Add status text + tests

* more test

* Comment out mark action ok untill bodyMessage is implemented

---------

Co-authored-by: Hammerbeck <[email protected]>
  • Loading branch information
Andreass2 and Hammerbeck authored May 30, 2024
1 parent e95e681 commit 2c02d7e
Show file tree
Hide file tree
Showing 9 changed files with 182 additions and 9 deletions.
43 changes: 43 additions & 0 deletions Test/Altinn.Correspondence.Tests/CorrespondenceControllerTests.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Net;
using System.Net.Http.Json;
using Altinn.Correspondece.Tests.Factories;
using Altinn.Correspondence.Application.GetCorrespondencesResponse;
Expand Down Expand Up @@ -52,4 +53,46 @@ public async Task GetCorrespondenceDetails()
var getCorrespondenceOverviewResponse = await _client.GetAsync($"correspondence/api/v1/correspondence/{correspondenceId}/details");
Assert.True(getCorrespondenceOverviewResponse.IsSuccessStatusCode, await getCorrespondenceOverviewResponse.Content.ReadAsStringAsync());
}

[Fact]
public async Task MarkActions_CorrespondenceNotExists_ReturnNotFound()
{
var readResponse = await _client.PostAsync($"correspondence/api/v1/correspondence/00000000-0100-0000-0000-000000000000/markasread", null);
Assert.Equal(HttpStatusCode.NotFound, readResponse.StatusCode);

var confirmResponse = await _client.PostAsync($"correspondence/api/v1/correspondence/00000000-0100-0000-0000-000000000000/confirm", null);
Assert.Equal(HttpStatusCode.NotFound, confirmResponse.StatusCode);

var archiveResponse = await _client.PostAsync($"correspondence/api/v1/correspondence/00000000-0100-0000-0000-000000000000/archive", null);
Assert.Equal(HttpStatusCode.NotFound, archiveResponse.StatusCode);
}

[Fact]
public async Task ReceiverMarkActions_CorrespondenceNotPublished_ReturnBadRequest()
{
var initializeCorrespondenceResponse = await _client.PostAsJsonAsync("correspondence/api/v1/correspondence", InitializeCorrespondenceFactory.BasicCorrespondence());
var correspondenceId = Guid.Parse(await initializeCorrespondenceResponse.Content.ReadAsStringAsync());

Console.WriteLine(correspondenceId);
var readResponse = await _client.PostAsync($"correspondence/api/v1/correspondence/{correspondenceId}/markasread", null);
Assert.Equal(HttpStatusCode.BadRequest, readResponse.StatusCode);

var confirmResponse = await _client.PostAsync($"correspondence/api/v1/correspondence/{correspondenceId}/confirm", null);
Assert.Equal(HttpStatusCode.BadRequest, confirmResponse.StatusCode);
}

/* [Fact]
public async Task ReceiverMarkActions_CorrespondencePublished_ReturnOk()
{
var initializeCorrespondenceResponse = await _client.PostAsJsonAsync("correspondence/api/v1/correspondence", InitializeCorrespondenceFactory.BasicCorrespondence());
var correspondenceId = Guid.Parse(await initializeCorrespondenceResponse.Content.ReadAsStringAsync());
//TODO: Add logic to publish correspondence
var readResponse = await _client.PostAsync($"correspondence/api/v1/correspondence/{correspondenceId}/markasread", null);
Assert.True(readResponse.IsSuccessStatusCode, await readResponse.Content.ReadAsStringAsync());
var confirmResponse = await _client.PostAsync($"correspondence/api/v1/correspondence/{correspondenceId}/confirm", null);
Assert.True(confirmResponse.IsSuccessStatusCode, await confirmResponse.Content.ReadAsStringAsync());
} */
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Altinn.Correspondence.Application.GetCorrespondenceOverviewCommand;
using Altinn.Correspondence.Application.GetCorrespondencesCommand;
using Altinn.Correspondence.Application.InitializeCorrespondenceCommand;
using Altinn.Correspondence.Application.UpdateCorrespondenceStatusCommand;
using Altinn.Correspondence.Core.Models.Enums;
using Altinn.Correspondence.Helpers;
using Altinn.Correspondence.Mappers;
Expand Down Expand Up @@ -169,15 +170,26 @@ public async Task<ActionResult<CorrespondencesExt>> GetCorrespondences(
/// <remarks>
/// Meant for Receivers
/// </remarks>
/// <returns>Ok</returns>
/// <returns>StatusId</returns>
[HttpPost]
[Route("{correspondenceId}/markasread")]
public async Task<ActionResult> MarkAsRead(
Guid correspondenceId)
Guid correspondenceId,
[FromServices] UpdateCorrespondenceStatusCommandHandler handler,
CancellationToken cancellationToken)
{
_logger.LogInformation("Marking Correspondence as read for {correspondenceId}", correspondenceId.ToString());

return Ok();
var commandResult = await handler.Process(new UpdateCorrespondenceStatusCommandRequest
{
CorrespondenceId = correspondenceId,
Status = CorrespondenceStatus.Read
}, cancellationToken);

return commandResult.Match(
data => Ok(data),
Problem
);
}

/// <summary>
Expand All @@ -186,15 +198,26 @@ public async Task<ActionResult> MarkAsRead(
/// <remarks>
/// Meant for Receivers
/// </remarks>
/// <returns>Ok</returns>
/// <returns>StatusId</returns>
[HttpPost]
[Route("{correspondenceId}/confirm")]
public async Task<ActionResult> Confirm(
Guid correspondenceId)
Guid correspondenceId,
[FromServices] UpdateCorrespondenceStatusCommandHandler handler,
CancellationToken cancellationToken)
{
_logger.LogInformation("Marking Correspondence as confirmed for {correspondenceId}", correspondenceId.ToString());

return Ok();
var commandResult = await handler.Process(new UpdateCorrespondenceStatusCommandRequest
{
CorrespondenceId = correspondenceId,
Status = CorrespondenceStatus.Confirmed
}, cancellationToken);

return commandResult.Match(
data => Ok(data),
Problem
);
}

/// <summary>
Expand All @@ -203,15 +226,26 @@ public async Task<ActionResult> Confirm(
/// <remarks>
/// Meant for Receivers
/// </remarks>
/// <returns>Ok</returns>
/// <returns>StatusId</returns>
[HttpPost]
[Route("{correspondenceId}/archive")]
public async Task<ActionResult> Archive(
Guid correspondenceId)
Guid correspondenceId,
[FromServices] UpdateCorrespondenceStatusCommandHandler handler,
CancellationToken cancellationToken)
{
_logger.LogInformation("Archiving Correspondence with id: {correspondenceId}", correspondenceId.ToString());

return Ok();
var commandResult = await handler.Process(new UpdateCorrespondenceStatusCommandRequest
{
CorrespondenceId = correspondenceId,
Status = CorrespondenceStatus.Archived
}, cancellationToken);

return commandResult.Match(
data => Ok(data),
Problem
);
}

/// <summary>
Expand Down
2 changes: 2 additions & 0 deletions src/Altinn.Correspondence.Application/DependencyInjection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Altinn.Correspondence.Application.InitializeAttachmentCommand;
using Altinn.Correspondence.Application.InitializeCorrespondenceCommand;
using Altinn.Correspondence.Application.UploadAttachmentCommand;
using Altinn.Correspondence.Application.UpdateCorrespondenceStatusCommand;
using Microsoft.Extensions.DependencyInjection;

namespace Altinn.Correspondence.Application;
Expand All @@ -22,6 +23,7 @@ public static void AddApplicationHandlers(this IServiceCollection services)
services.AddScoped<GetCorrespondenceOverviewCommandHandler>();
services.AddScoped<GetAttachmentOverviewCommandHandler>();
services.AddScoped<GetAttachmentDetailsCommandHandler>();
services.AddScoped<UpdateCorrespondenceStatusCommandHandler>();
services.AddScoped<UploadAttachmentCommandHandler>();
services.AddScoped<DownloadAttachmentQueryHandler>();
}
Expand Down
1 change: 1 addition & 0 deletions src/Altinn.Correspondence.Application/Errors.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ public static class Errors
public static Error UploadFailed = new(4, "Error occurred during upload", HttpStatusCode.BadGateway);
public static Error InvalidFileSize = new(5, "File must have content and has a max file size of 2GB", HttpStatusCode.BadRequest);
public static Error InvalidAttachmentStatus = new(6, "File has already been or is being uploaded", HttpStatusCode.BadRequest);
public static Error CorrespondenceNotPublished = new Error(7, "A correspondence can only be confirmed or read when it is published. See correspondence status.", HttpStatusCode.BadRequest);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using Altinn.Correspondence.Core.Models;
using Altinn.Correspondence.Core.Models.Enums;
using Altinn.Correspondence.Core.Repositories;
using OneOf;

namespace Altinn.Correspondence.Application.UpdateCorrespondenceStatusCommand;

public class UpdateCorrespondenceStatusCommandHandler : IHandler<UpdateCorrespondenceStatusCommandRequest, Guid>
{
private readonly ICorrespondenceRepository _correspondenceRepository;
private readonly ICorrespondenceStatusRepository _correspondenceStatusRepository;
public UpdateCorrespondenceStatusCommandHandler(ICorrespondenceRepository correspondenceRepository, ICorrespondenceStatusRepository correspondenceStatusRepository)
{
_correspondenceRepository = correspondenceRepository;
_correspondenceStatusRepository = correspondenceStatusRepository;
}

public async Task<OneOf<Guid, Error>> Process(UpdateCorrespondenceStatusCommandRequest request, CancellationToken cancellationToken)
{
var correspondence = await _correspondenceRepository.GetCorrespondenceById(request.CorrespondenceId, false, cancellationToken);
if (correspondence == null)
{
return Errors.CorrespondenceNotFound;
}

var currentStatus = await _correspondenceStatusRepository.GetLatestStatusByCorrespondenceId(request.CorrespondenceId, cancellationToken);
if ((request.Status == CorrespondenceStatus.Confirmed || request.Status == CorrespondenceStatus.Read) && currentStatus?.Status != CorrespondenceStatus.Published)
{
return Errors.CorrespondenceNotPublished;
}
if (currentStatus?.Status == request.Status)
{
return request.CorrespondenceId;
}

await _correspondenceStatusRepository.AddCorrespondenceStatus(new CorrespondenceStatusEntity
{
CorrespondenceId = request.CorrespondenceId,
Status = request.Status,
StatusChanged = DateTime.UtcNow,
StatusText = request.Status.ToString(),
}, cancellationToken);
return request.CorrespondenceId;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Altinn.Correspondence.Core.Models.Enums;

namespace Altinn.Correspondence.Application.UpdateCorrespondenceStatusCommand;

public class UpdateCorrespondenceStatusCommandRequest
{
public Guid CorrespondenceId { get; set; }
public CorrespondenceStatus Status { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Altinn.Correspondence.Core.Models;

namespace Altinn.Correspondence.Core.Repositories
{
public interface ICorrespondenceStatusRepository
{
Task<Guid> AddCorrespondenceStatus(CorrespondenceStatusEntity Correspondence, CancellationToken cancellationToken);
Task<CorrespondenceStatusEntity?> GetLatestStatusByCorrespondenceId(Guid CorrespondenceId, CancellationToken cancellationToken);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public static void AddPersistence(this IServiceCollection services)
services.AddScoped<IAttachmentRepository, AttachmentRepository>();
services.AddScoped<IAttachmentStatusRepository, AttachmentStatusRepository>();
services.AddScoped<ICorrespondenceRepository, CorrespondenceRepository>();
services.AddScoped<ICorrespondenceStatusRepository, CorrespondenceStatusRepository>();
services.AddScoped<IStorageRepository, StorageRepository>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using Altinn.Correspondence.Core.Models;
using Altinn.Correspondence.Core.Repositories;
using Microsoft.EntityFrameworkCore;

namespace Altinn.Correspondence.Persistence.Repositories
{
public class CorrespondenceStatusRepository(ApplicationDbContext context) : ICorrespondenceStatusRepository
{
private readonly ApplicationDbContext _context = context;

public async Task<Guid> AddCorrespondenceStatus(CorrespondenceStatusEntity status, CancellationToken cancellationToken)
{
await _context.CorrespondenceStatuses.AddAsync(status, cancellationToken);
await _context.SaveChangesAsync();
return status.Id;
}

public async Task<CorrespondenceStatusEntity?> GetLatestStatusByCorrespondenceId(Guid CorrespondenceId, CancellationToken cancellationToken)
{
var status = await _context.CorrespondenceStatuses
.Where(s => s.CorrespondenceId == CorrespondenceId)
.OrderByDescending(s => s.StatusChanged)
.FirstOrDefaultAsync(cancellationToken);

return status;
}
}
}

0 comments on commit 2c02d7e

Please sign in to comment.