Skip to content

Commit

Permalink
Feat: Add confirmation requirement IsConfirmationNeeded to correspo…
Browse files Browse the repository at this point in the history
…ndence (#387)

* fix: if correspondence is not available, return 404 regardless of requested status

* delete old InitializedCorrespondenceFactory

* Add IsConfirmationNeeded field to CorrespondenceEntity, requests, responses, and DB

* logic for handling IsConfirmationNeeded added

* Add tests for archived and purged correspondence

* fix: exclaimation mark used twice in condition check

* Add extension method for checking if a correspondence has had a specific status

* fix: map correctly IsConfirmationNeeded in response for GET calls

* Update postman collection

* make IsConfirmationNeeded not required, as default becomes false

* add workflow for checking label for new PRs (#384)

* add workflow for checking label for new PRs

* rerun job when PR is set to ready for review

* add better name to workflow

* Update .github/workflows/check-label-for-pr.yml

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update .github/workflows/check-label-for-pr.yml

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* add more triggers on PR to run workflow

* fix: remove ignore-for-release in labels list

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Fix Maskinporten token error (#386)

* OnChallenge modifies response object. Instead, use exception from authentication failure to short-circuit onchallenge handler when failure source is known (used Maskinporten token on Altinn token endpoint), and set the response there instead.

* Seal it at least

* Null handle

* Async should be awaited

* Legacy - authorize multiple recipients (#388)

* Accessmanagement to enable multiple recipients

* cleanup and improvements

---------

Co-authored-by: Hammerbeck <andreas.hammerbeck@digdir.no>

* Make DueDateTime nullable

* Add IsConfirmationNeeded field to CorrespondenceEntity, requests, responses, and DB

* logic for handling IsConfirmationNeeded added

* rebase fix: delete duplicate IsConfirmationNeeded migration

* make DueDateTime required if IsConfirmationNeeded is used

* add boolean param to WithConfirmationNeeded

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Roar Mjelde <36594318+Ceredron@users.noreply.github.com>
Co-authored-by: Andreas Hammerbeck <Andreas_93@hotmail.com>
Co-authored-by: Hammerbeck <andreas.hammerbeck@digdir.no>
  • Loading branch information
5 people authored Oct 25, 2024
1 parent 42d958d commit a0c6af4
Show file tree
Hide file tree
Showing 30 changed files with 741 additions and 378 deletions.
134 changes: 119 additions & 15 deletions Test/Altinn.Correspondence.Tests/CorrespondenceControllerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,37 @@ public async Task InitializeCorrespondence_AllowSystemDeleteAfter_PriorDueDate_R
Assert.Equal(HttpStatusCode.BadRequest, initializeCorrespondenceResponse.StatusCode);
}

[Fact]
public async Task InitializeCorrespondence_WithConfirmationNeeded_Without_DueDate_Returns_BadRequest()
{
// Arrange
var payload = new CorrespondenceBuilder()
.CreateCorrespondence()
.WithConfirmationNeeded(true)
.Build();

// Act
var initializeCorrespondenceResponse = await _senderClient.PostAsJsonAsync("correspondence/api/v1/correspondence", payload);

// Assert
Assert.Equal(HttpStatusCode.BadRequest, initializeCorrespondenceResponse.StatusCode);
}

[Fact]
public async Task InitializeCorrespondence_With_RequestedPublishTime_Null()
{
// Arrange
var correspondence = new CorrespondenceBuilder()
.CreateCorrespondence()
.WithRequestedPublishTime(null)
.Build();

var initializeCorrespondenceResponse = await _senderClient.PostAsJsonAsync("correspondence/api/v1/correspondence", correspondence);

// Assert
Assert.Equal(HttpStatusCode.OK, initializeCorrespondenceResponse.StatusCode);
}

[Fact]
public async Task UploadCorrespondence_Gives_Ok()
{
Expand Down Expand Up @@ -921,6 +952,50 @@ public async Task ReceiverMarkActions_CorrespondencePublished_ReturnOk()
Assert.True(overview?.MarkedUnread == true);
}

[Fact]
public async Task UpdateCorrespondenceStatus_ToArchived_WithoutConfirmation_WhenConfirmationNeeded_ReturnsBadRequest()
{
// Arrange
var payload = new CorrespondenceBuilder()
.CreateCorrespondence()
.WithDueDateTime(DateTimeOffset.UtcNow.AddDays(1))
.WithConfirmationNeeded(true)
.Build();
var initializeCorrespondenceResponse = await _senderClient.PostAsJsonAsync("correspondence/api/v1/correspondence", payload);
var correspondenceResponse = await initializeCorrespondenceResponse.Content.ReadFromJsonAsync<InitializeCorrespondencesResponseExt>(_responseSerializerOptions);
Assert.Equal(CorrespondenceStatus.Published, correspondenceResponse?.Correspondences?.FirstOrDefault()?.Status);
var correspondenceId = correspondenceResponse?.Correspondences?.FirstOrDefault()?.CorrespondenceId;

// Act
var archiveResponse = await _recipientClient.PostAsync($"correspondence/api/v1/correspondence/{correspondenceId}/archive", null);

// Assert
Assert.Equal(HttpStatusCode.BadRequest, archiveResponse.StatusCode);
}

[Fact]
public async Task UpdateCorrespondenceStatus_ToArchived_WithConfirmation_WhenConfirmationNeeded_GivesOk()
{
// Arrange
var payload = new CorrespondenceBuilder()
.CreateCorrespondence()
.WithDueDateTime(DateTimeOffset.UtcNow.AddDays(1))
.WithConfirmationNeeded(true)
.Build();
var initializeCorrespondenceResponse = await _senderClient.PostAsJsonAsync("correspondence/api/v1/correspondence", payload);
var correspondenceResponse = await initializeCorrespondenceResponse.Content.ReadFromJsonAsync<InitializeCorrespondencesResponseExt>(_responseSerializerOptions);
Assert.Equal(CorrespondenceStatus.Published, correspondenceResponse?.Correspondences?.FirstOrDefault()?.Status);
var correspondenceId = correspondenceResponse?.Correspondences?.FirstOrDefault()?.CorrespondenceId;

// Act
var confirmResponse = await _recipientClient.PostAsync($"correspondence/api/v1/correspondence/{correspondenceId}/confirm", null);
Assert.Equal(HttpStatusCode.OK, confirmResponse.StatusCode);
var archiveResponse = await _recipientClient.PostAsync($"correspondence/api/v1/correspondence/{correspondenceId}/archive", null);

// Assert
Assert.Equal(HttpStatusCode.OK, archiveResponse.StatusCode);
}

[Fact]
public async Task Correspondence_with_dataLocationUrl_Reuses_Attachment()
{
Expand Down Expand Up @@ -1059,6 +1134,50 @@ public async Task Delete_Published_Correspondence_SuccessForRecipient_FailsForSe
Assert.Equal(overview?.Status, CorrespondenceStatusExt.PurgedByRecipient);
}

[Fact]
public async Task Delete_Published_Correspondence_WithoutConfirmation_WhenConfirmationNeeded_ReturnsBadRequest()
{
// Arrange
var payload = new CorrespondenceBuilder()
.CreateCorrespondence()
.WithDueDateTime(DateTimeOffset.UtcNow.AddDays(1))
.WithConfirmationNeeded(true)
.Build();
var initializeCorrespondenceResponse = await _senderClient.PostAsJsonAsync("correspondence/api/v1/correspondence", payload);
var correspondenceResponse = await initializeCorrespondenceResponse.Content.ReadFromJsonAsync<InitializeCorrespondencesResponseExt>(_responseSerializerOptions);
Assert.Equal(CorrespondenceStatus.Published, correspondenceResponse?.Correspondences?.FirstOrDefault()?.Status);
var correspondenceId = correspondenceResponse?.Correspondences?.FirstOrDefault()?.CorrespondenceId;

// Act
var deleteResponse = await _recipientClient.DeleteAsync($"correspondence/api/v1/correspondence/{correspondenceId}/purge");

// Assert
Assert.Equal(HttpStatusCode.BadRequest, deleteResponse.StatusCode);
}

[Fact]
public async Task Delete_Published_Correspondence_WithConfirmation_WhenConfirmationNeeded_Gives_OK()
{
// Arrange
var payload = new CorrespondenceBuilder()
.CreateCorrespondence()
.WithDueDateTime(DateTimeOffset.UtcNow.AddDays(1))
.WithConfirmationNeeded(true)
.Build();
var initializeCorrespondenceResponse = await _senderClient.PostAsJsonAsync("correspondence/api/v1/correspondence", payload);
var correspondenceResponse = await initializeCorrespondenceResponse.Content.ReadFromJsonAsync<InitializeCorrespondencesResponseExt>(_responseSerializerOptions);
Assert.Equal(CorrespondenceStatus.Published, correspondenceResponse?.Correspondences?.FirstOrDefault()?.Status);
var correspondenceId = correspondenceResponse?.Correspondences?.FirstOrDefault()?.CorrespondenceId;

// Act
var confirmResponse = await _recipientClient.PostAsync($"correspondence/api/v1/correspondence/{correspondenceId}/confirm", null);
Assert.Equal(HttpStatusCode.OK, confirmResponse.StatusCode);
var deleteResponse = await _recipientClient.DeleteAsync($"correspondence/api/v1/correspondence/{correspondenceId}/purge");

// Assert
Assert.Equal(HttpStatusCode.OK, deleteResponse.StatusCode);
}

[Fact]
public async Task Delete_Correspondence_Also_deletes_attachment()
{
Expand Down Expand Up @@ -1477,21 +1596,6 @@ public async Task CancelNotificationHandler_SendsSlackNotification_WhenCancellat
slackClientMock.Verify(client => client.Post(It.IsAny<SlackMessage>()), Times.Once);
}

[Fact]
public async Task InitializeCorrespondence_With_RequestedPublishTime_Null()
{
// Arrange
var correspondence = new CorrespondenceBuilder()
.CreateCorrespondence()
.WithRequestedPublishTime(null)
.Build();

var initializeCorrespondenceResponse = await _senderClient.PostAsJsonAsync("correspondence/api/v1/correspondence", correspondence);

// Assert
Assert.Equal(HttpStatusCode.OK, initializeCorrespondenceResponse.StatusCode);
}

private MultipartFormDataContent CorrespondenceToFormData(BaseCorrespondenceExt correspondence)
{
var formData = new MultipartFormDataContent(){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ public CorrespondenceBuilder CreateCorrespondence()
{"culpa_852", "2"},
{"anim5", "3"}
},
IgnoreReservation = false
IgnoreReservation = false,
IsConfirmationNeeded = false,
},
Recipients = new List<string>(){
"0192:991825827", // org number
Expand Down Expand Up @@ -129,6 +130,11 @@ public CorrespondenceBuilder WithAllowSystemDeleteAfter(DateTimeOffset dueDateTi
_correspondence.Correspondence.AllowSystemDeleteAfter = dueDateTime;
return this;
}
public CorrespondenceBuilder WithConfirmationNeeded(bool confirmationNeeded)
{
_correspondence.Correspondence.IsConfirmationNeeded = confirmationNeeded;
return this;
}
public CorrespondenceBuilder WithNotificationTemplate(NotificationTemplateExt notificationTemplate)
{
_correspondence.Correspondence.Notification ??= new InitializeCorrespondenceNotificationExt()
Expand Down Expand Up @@ -196,7 +202,7 @@ public static CorrespondenceEntity CorrespondenceEntityWithNotifications()
NotificationTemplate = new Core.Models.Enums.NotificationTemplate(),
NotificationChannel = new Core.Models.Enums.NotificationChannel(),
}
}
},
};
}
}
Expand Down
Loading

0 comments on commit a0c6af4

Please sign in to comment.