Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#dp-271 generate share code refactor #517

Merged
merged 2 commits into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 42 additions & 1 deletion Frontend/CO.CDP.OrganisationApp.Tests/FormsEngineTests.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
using CO.CDP.OrganisationApp.Models;
using FluentAssertions;
using Moq;
using DataShareWebApiClient = CO.CDP.DataSharing.WebApiClient;
using WebApiClient = CO.CDP.Forms.WebApiClient;

namespace CO.CDP.OrganisationApp.Tests;

public class FormsEngineTests
{
private readonly Mock<WebApiClient.IFormsClient> _formsApiClientMock;
private readonly Mock<DataShareWebApiClient.IDataSharingClient> _dataSharingClientMock;
private readonly Mock<ITempDataService> _tempDataServiceMock;
private readonly FormsEngine _formsEngine;

public FormsEngineTests()
{
_formsApiClientMock = new Mock<WebApiClient.IFormsClient>();
_dataSharingClientMock = new Mock<DataShareWebApiClient.IDataSharingClient>();
_tempDataServiceMock = new Mock<ITempDataService>();
_formsEngine = new FormsEngine(_formsApiClientMock.Object, _tempDataServiceMock.Object);
_formsEngine = new FormsEngine(_formsApiClientMock.Object, _tempDataServiceMock.Object, _dataSharingClientMock.Object);
}

private static (Guid organisationId, Guid formId, Guid sectionId, string sessionKey) CreateTestGuids()
Expand Down Expand Up @@ -294,6 +297,44 @@ public async Task SaveUpdateAnswers_ShouldThrowException_WhenApiCallFails()
await act.Should().ThrowAsync<Exception>().WithMessage("API call failed");
}

[Fact]
public async Task CreateShareCodeAsync_ShouldReturnShareCode_WhenApiCallSucceeds()
{
var formId = Guid.NewGuid();
var organisationId = Guid.NewGuid();
var expectedShareCode = "HDJ2123F";

_dataSharingClientMock.Setup(client => client.CreateSharedDataAsync(
It.Is<DataShareWebApiClient.ShareRequest>(sr =>
sr.FormId == formId && sr.OrganisationId == organisationId)))
.ReturnsAsync(new DataShareWebApiClient.ShareReceipt(formId, null, expectedShareCode));

var result = await _formsEngine.CreateShareCodeAsync(formId, organisationId);

result.Should().Be(expectedShareCode);
_dataSharingClientMock.Verify(client => client.CreateSharedDataAsync(
It.Is<DataShareWebApiClient.ShareRequest>(sr =>
sr.FormId == formId && sr.OrganisationId == organisationId)), Times.Once);
}

[Fact]
public async Task CreateShareCodeAsync_ShouldThrowException_WhenApiCallFails()
{
var formId = Guid.NewGuid();
var organisationId = Guid.NewGuid();

_dataSharingClientMock.Setup(client => client.CreateSharedDataAsync(
It.IsAny<DataShareWebApiClient.ShareRequest>()))
.ThrowsAsync(new Exception("API call failed"));

Func<Task> act = async () => await _formsEngine.CreateShareCodeAsync(formId, organisationId);

await act.Should().ThrowAsync<Exception>().WithMessage("API call failed");
_dataSharingClientMock.Verify(client => client.CreateSharedDataAsync(
It.Is<DataShareWebApiClient.ShareRequest>(sr =>
sr.FormId == formId && sr.OrganisationId == organisationId)), Times.Once);
}

private (Guid formId, Guid sectionId, Guid organisationId, FormQuestionAnswerState answerSet, FormAnswer expectedAnswer) SetupTestData()
{
var formId = Guid.NewGuid();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,4 +172,41 @@ public async Task OnPostAsync_ShouldRedirectToShareCodeConfirmation_WhenSectionT
result.Should().BeOfType<RedirectToPageResult>()
.Which.PageName.Should().Be("/ShareInformation/ShareCodeConfirmation");
}
}

[Fact]
public async Task OnPostAsync_ShouldRedirectToShareCodeConfirmation_WithGeneratedShareCode_WhenSectionIsDeclaration()
{
var shareCode = "HDJ2123F";
_pageModel.FormSectionType = FormSectionType.Declaration;
_pageModel.CurrentQuestionId = Guid.NewGuid();

var formResponse = new SectionQuestionsResponse
{
Section = new FormSection { Type = FormSectionType.Declaration, Title = "Test Section" },
Questions = new List<FormQuestion>
{
new FormQuestion { Id = _pageModel.CurrentQuestionId.Value, Type = FormQuestionType.CheckYourAnswers }
}
};

_formsEngineMock.Setup(f => f.GetCurrentQuestion(It.IsAny<Guid>(), It.IsAny<Guid>(), It.IsAny<Guid>(), It.IsAny<Guid?>()))
.ReturnsAsync(new FormQuestion { Id = _pageModel.CurrentQuestionId.Value, Type = FormQuestionType.CheckYourAnswers });

_formsEngineMock.Setup(f => f.GetFormSectionAsync(It.IsAny<Guid>(), It.IsAny<Guid>(), It.IsAny<Guid>()))
.ReturnsAsync(formResponse);

_formsEngineMock.Setup(f => f.CreateShareCodeAsync(It.IsAny<Guid>(), It.IsAny<Guid>()))
.ReturnsAsync(shareCode);

_tempDataServiceMock.Setup(t => t.PeekOrDefault<FormQuestionAnswerState>(It.IsAny<string>()))
.Returns(new FormQuestionAnswerState());

var result = await _pageModel.OnPostAsync();

_formsEngineMock.Verify(f => f.CreateShareCodeAsync(_pageModel.FormId, _pageModel.OrganisationId), Times.Once);

result.Should().BeOfType<RedirectToPageResult>()
.Which.PageName.Should().Be("/ShareInformation/ShareCodeConfirmation");
(result as RedirectToPageResult)!.RouteValues?["shareCode"].Should().Be(shareCode);
}
}
Original file line number Diff line number Diff line change
@@ -1,81 +1,29 @@
using CO.CDP.OrganisationApp.Pages.ShareInformation;
using FluentAssertions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Moq;
using WebApiClient = CO.CDP.DataSharing.WebApiClient;


namespace CO.CDP.OrganisationApp.Tests.Pages.ShareInformation;
public class ShareCodeConfirmationTests
{
private readonly Mock<WebApiClient.IDataSharingClient> _dataSharingApiClientMock;
private readonly ShareCodeConfirmationModel _pageModel;

public ShareCodeConfirmationTests()
{
_dataSharingApiClientMock = new Mock<WebApiClient.IDataSharingClient>();
_pageModel = new ShareCodeConfirmationModel(_dataSharingApiClientMock.Object);
}

[Fact]
public async Task OnGetAsync_ShouldReturnPageResult_WhenShareCodeIsGeneratedSuccessfully()
public void ShareCodeConfirmationModel_ShouldInitializePropertiesCorrectly()
{
var formId = Guid.NewGuid();
var organisationId = Guid.NewGuid();
var sectionId = Guid.NewGuid();
var shareCode = "HDJ2123F";

_pageModel.FormId = formId;
_pageModel.OrganisationId = organisationId;
_pageModel.SectionId = sectionId;

_dataSharingApiClientMock
.Setup(x => x.CreateSharedDataAsync(It.Is<WebApiClient.ShareRequest>(sr =>
sr.FormId == formId && sr.OrganisationId == organisationId)))
.ReturnsAsync(new WebApiClient.ShareReceipt(formId, null, shareCode));

var result = await _pageModel.OnGetAsync();

result.Should().BeOfType<PageResult>();
_pageModel.ShareCode.Should().Be(shareCode);
}

[Fact]
public async Task OnGetAsync_ShouldRedirectToNotFound_WhenApiExceptionOccursWith404()
{
var formId = Guid.NewGuid();
var organisationId = Guid.NewGuid();
var sectionId = Guid.NewGuid();
var shareCode = "HDJ2123F";

_pageModel.FormId = formId;
_pageModel.OrganisationId = organisationId;
_pageModel.SectionId = sectionId;

_dataSharingApiClientMock
.Setup(x => x.CreateSharedDataAsync(It.IsAny<WebApiClient.ShareRequest>()))
.ThrowsAsync(new WebApiClient.ApiException(string.Empty, 404, string.Empty, null, null));

var result = await _pageModel.OnGetAsync();

result.Should().BeOfType<RedirectResult>().Which.Url.Should().Be("/page-not-found");
_pageModel.ShareCode.Should().BeNull();
}

[Fact]
public async Task OnGetAsync_ShouldAllowMiddlewareToHandle500Error()
{
var formId = Guid.NewGuid();
var organisationId = Guid.NewGuid();
var sectionId = Guid.NewGuid();

_pageModel.FormId = formId;
_pageModel.OrganisationId = organisationId;
_pageModel.SectionId = sectionId;

_dataSharingApiClientMock
.Setup(x => x.CreateSharedDataAsync(It.IsAny<WebApiClient.ShareRequest>()))
.ThrowsAsync(new WebApiClient.ApiException("Internal Server Error", 500, string.Empty, null, null));

await Assert.ThrowsAsync<WebApiClient.ApiException>(async () => await _pageModel.OnGetAsync());
var model = new ShareCodeConfirmationModel
{
OrganisationId = organisationId,
FormId = formId,
SectionId = sectionId,
ShareCode = shareCode
};

model.OrganisationId.Should().Be(organisationId);
model.FormId.Should().Be(formId);
model.SectionId.Should().Be(sectionId);
model.ShareCode.Should().Be(shareCode);
}
}
17 changes: 14 additions & 3 deletions Frontend/CO.CDP.OrganisationApp/FormsEngine.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
using CO.CDP.Forms.WebApiClient;
using CO.CDP.OrganisationApp.Models;
using DataShareWebApiClient = CO.CDP.DataSharing.WebApiClient;
using SectionQuestionsResponse = CO.CDP.OrganisationApp.Models.SectionQuestionsResponse;

namespace CO.CDP.OrganisationApp;

public class FormsEngine(IFormsClient formsApiClient, ITempDataService tempDataService) : IFormsEngine
public class FormsEngine(
IFormsClient formsApiClient,
ITempDataService tempDataService,
DataShareWebApiClient.IDataSharingClient dataSharingClient) : IFormsEngine
{
public const string OrganisationSupplierInfoFormId = "0618b13e-eaf2-46e3-a7d2-6f2c44be7022";

Expand Down Expand Up @@ -119,9 +122,17 @@ await formsApiClient.PutFormSectionAnswersAsync(
answersPayload);
}

public async Task<string> CreateShareCodeAsync(Guid formId, Guid organisationId)
{
var sharingDataDetails = await dataSharingClient.CreateSharedDataAsync(
new DataShareWebApiClient.ShareRequest(formId, organisationId));

return sharingDataDetails.ShareCode;
}
private static FormAddress? MapAddress(Address? formAdddress)
{
if (formAdddress == null) return null;
if (formAdddress == null)
return null;
return new FormAddress(
streetAddress: formAdddress.AddressLine1,
locality: formAdddress.TownOrCity,
Expand Down
1 change: 1 addition & 0 deletions Frontend/CO.CDP.OrganisationApp/IFormsEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ public interface IFormsEngine
Task<FormQuestion?> GetCurrentQuestion(Guid organisationId, Guid formId, Guid sectionId, Guid? questionId);

Task SaveUpdateAnswers(Guid formId, Guid sectionId, Guid organisationId, FormQuestionAnswerState answerSet);
Task<string> CreateShareCodeAsync(Guid formId, Guid organisationId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,15 @@ public async Task<IActionResult> OnPostAsync()

tempDataService.Remove(FormQuestionAnswerStateKey);

return RedirectToPage(FormSectionType == Models.FormSectionType.Declaration ?
"/ShareInformation/ShareCodeConfirmation" : "FormsAddAnotherAnswerSet",
new { OrganisationId, FormId, SectionId });
if (FormSectionType == Models.FormSectionType.Declaration)
{
var shareCode = await formsEngine.CreateShareCodeAsync(FormId, OrganisationId);

return RedirectToPage("/ShareInformation/ShareCodeConfirmation",
new { OrganisationId, FormId, SectionId, shareCode });
}

return RedirectToPage("FormsAddAnotherAnswerSet", new { OrganisationId, FormId, SectionId });
}

Guid? nextQuestionId;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
using CO.CDP.DataSharing.WebApiClient;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace CO.CDP.OrganisationApp.Pages.ShareInformation;

public class ShareCodeConfirmationModel(
IDataSharingClient dataSharingClient) : PageModel
public class ShareCodeConfirmationModel() : PageModel
{
[BindProperty(SupportsGet = true)]
public Guid OrganisationId { get; set; }
Expand All @@ -16,19 +14,7 @@ public class ShareCodeConfirmationModel(
[BindProperty(SupportsGet = true)]
public Guid SectionId { get; set; }

[BindProperty(SupportsGet = true)]
public string? ShareCode { get; set; }

public async Task<IActionResult> OnGetAsync()
{
try
{
var sharingDataDetails = await dataSharingClient.CreateSharedDataAsync(new ShareRequest(FormId, OrganisationId));
ShareCode = sharingDataDetails.ShareCode;
}
catch (ApiException ex) when (ex.StatusCode == 404)
{
return Redirect("/page-not-found");
}
return Page();
}
}