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

Facilitate FTS redirect to co-sirsi app #589

Merged
merged 1 commit into from
Sep 10, 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
22 changes: 22 additions & 0 deletions Frontend/CO.CDP.OrganisationApp.Tests/HelperTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using FluentAssertions;

namespace CO.CDP.OrganisationApp.Tests;

public class HelperTests
{
[Theory]
[InlineData("/relative/path", true)] // Valid relative URI
[InlineData("relative/path", true)] // Valid relative URI without a leading slash
[InlineData("", false)] // Empty string
[InlineData(null, false)] // Null value
[InlineData(" ", false)] // Whitespace
[InlineData("http://example.com", false)] // Absolute URI (not relative)
[InlineData("/path/with spaces", true)] // Relative URI with spaces

public void ValidRelativeUri_ShouldReturnExpectedResults(string? input, bool expected)
{
var result = Helper.ValidRelativeUri(input);

result.Should().Be(expected);
}
}
66 changes: 58 additions & 8 deletions Frontend/CO.CDP.OrganisationApp.Tests/Pages/OneLoginTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ public async Task OnGetSignIn_ShouldReturnAuthChallange()
.Which.Properties!.RedirectUri.Should().Be("/one-login/user-info");
}

[Fact]
public async Task OnGetSignIn_WhenRedirectUrlProvides_ShouldReturnAuthChallangeWithRedirectUrlQueryString()
{
var model = GivenOneLoginCallbackModel();

var results = await model.OnGet("sign-in", "/org/1");

results.Should().BeOfType<ChallengeResult>()
.Which.Properties!.RedirectUri.Should().Be("/one-login/user-info?redirectUri=%2Forg%2F1");
}

[Fact]
public async Task OnGetUserInfo_OnSuccessfulAuthentication_ShouldRetrieveUserProfile()
{
Expand Down Expand Up @@ -92,6 +103,34 @@ public async Task OnGetUserInfo_WhenPersonAlreadyRegistered_ShouldRedirectToOrga
.Which.PageName.Should().Be("OrganisationSelection");
}

[Fact]
public async Task OnGetUserInfo_WhenPersonAlreadyRegisteredAndRelativeRedirectUrlProvided_ShouldRedirectToRedirectUrl()
{
var model = GivenOneLoginCallbackModel();

personClientMock.Setup(t => t.LookupPersonAsync(It.IsAny<string>()))
.ReturnsAsync(dummyPerson);

var results = await model.OnGet("user-info", "/org/1");

results.Should().BeOfType<RedirectResult>()
.Which.Url.Should().Be("/org/1");
}

[Fact]
public async Task OnGetUserInfo_WhenPersonAlreadyRegisteredAndAbsoluteRedirectUrlProvided_ShouldRedirectToOrganisationDetailsPageWithoutRedirectUrlQueryString()
{
var model = GivenOneLoginCallbackModel();

personClientMock.Setup(t => t.LookupPersonAsync(It.IsAny<string>()))
.ReturnsAsync(dummyPerson);

var results = await model.OnGet("user-info", "http://test-domain/org/1");

results.Should().BeOfType<RedirectToPageResult>()
.Which.PageName.Should().Be("OrganisationSelection");
}

[Fact]
public async Task OnGetUserInfo_WhenPersonNotRegistered_ShouldRedirectToPrivacyPolicyPage()
{
Expand All @@ -107,22 +146,33 @@ public async Task OnGetUserInfo_WhenPersonNotRegistered_ShouldRedirectToPrivacyP
}

[Fact]
public async Task OnGetUserInfo_WhenPersonInviteId_ShouldRedirectToClaimOrganisationInvitePage()
public async Task OnGetUserInfo_WhenPersonNotRegisteredAndRelativeRedirectUrlProvided_ShouldRedirectToPrivacyPolicyPageWithRedirectUrlQueryString()
{
var model = GivenOneLoginCallbackModel();

personClientMock.Setup(t => t.LookupPersonAsync(It.IsAny<string>()))
.ReturnsAsync(dummyPerson);
.ThrowsAsync(new ApiException("Unexpected error", 404, "", default, null));

var personInviteId = Guid.NewGuid();
var results = await model.OnGet("user-info", "/org/1");

sessionMock.Setup(s => s.Get<Guid?>("PersonInviteId"))
.Returns(personInviteId);
var redirectToPageResult = results.Should().BeOfType<RedirectToPageResult>();
redirectToPageResult.Which.PageName.Should().Be("PrivacyPolicy");
redirectToPageResult.Which.RouteValues.Should().BeEquivalentTo(new Dictionary<string, string> { { "RedirectUri", "/org/1" } });
}

var results = await model.OnGet("user-info");
[Fact]
public async Task OnGetUserInfo_WhenPersonNotRegisteredAndAbsoluteRedirectUrlProvided_ShouldRedirectToPrivacyPolicyPageWithoutRedirectUrlQueryString()
{
var model = GivenOneLoginCallbackModel();

results.Should().BeOfType<RedirectToPageResult>()
.Which.PageName.Should().Be("ClaimOrganisationInvite");
personClientMock.Setup(t => t.LookupPersonAsync(It.IsAny<string>()))
.ThrowsAsync(new ApiException("Unexpected error", 404, "", default, null));

var results = await model.OnGet("user-info", "http://test-domain/org/1");

var redirectToPageResult = results.Should().BeOfType<RedirectToPageResult>();
redirectToPageResult.Which.PageName.Should().Be("PrivacyPolicy");
redirectToPageResult.Which.RouteValues.Should().BeEquivalentTo(new Dictionary<string, string?> { { "RedirectUri", default } });
}

[Fact]
Expand Down

This file was deleted.

26 changes: 26 additions & 0 deletions Frontend/CO.CDP.OrganisationApp.Tests/Pages/PrivacyPolicyTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,32 @@ public void Model_WhenAgreeToPrivacyPolicySetTrue_ShouldRedirectToTourDetailsPag
.Which.PageName.Should().Be("YourDetails");
}

[Fact]
public void Model_WhenAgreeToPrivacyPolicySetTrueAndRelativeRedirectUrlProvided_ShouldRedirectToTourDetailsPageWithRedirectUrlQueryString()
{
var model = GivenPrivacyPolicyModel();
model.AgreeToPrivacy = true;

var results = model.OnPost("/org/1");

var redirectToPageResult = results.Should().BeOfType<RedirectToPageResult>();
redirectToPageResult.Which.PageName.Should().Be("YourDetails");
redirectToPageResult.Which.RouteValues.Should().BeEquivalentTo(new Dictionary<string, string> { { "RedirectUri", "/org/1" } });
}

[Fact]
public void Model_WhenAgreeToPrivacyPolicySetTrueAndAbsoluteRedirectUrlProvided_ShouldRedirectToTourDetailsPageWithoutRedirectUrlQueryString()
{
var model = GivenPrivacyPolicyModel();
model.AgreeToPrivacy = true;

var results = model.OnPost("http://test-domain/org/1");

var redirectToPageResult = results.Should().BeOfType<RedirectToPageResult>();
redirectToPageResult.Which.PageName.Should().Be("YourDetails");
redirectToPageResult.Which.RouteValues.Should().BeEquivalentTo(new Dictionary<string, string?> { { "RedirectUri", default } });
}

private PrivacyPolicyModel GivenPrivacyPolicyModel()
{
return new PrivacyPolicyModel(sessionMock.Object);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using CO.CDP.OrganisationApp.Models;
using CO.CDP.OrganisationApp.Pages.Users;
using CO.CDP.Person.WebApiClient;
using FluentAssertions;
using Microsoft.AspNetCore.Mvc;
using Moq;
using ProblemDetails = CO.CDP.Person.WebApiClient.ProblemDetails;

namespace CO.CDP.OrganisationApp.Tests.Pages.Users;

public class ClaimOrganisationInviteModelTests
{
private readonly Mock<IPersonClient> personClientMock;
private readonly Mock<ISession> sessionMock;
private readonly ClaimOrganisationInviteModel model;
private const string UsreUrn = "urn:test";
private readonly Guid PersonId = Guid.NewGuid();

public ClaimOrganisationInviteModelTests()
{
var person = new Person.WebApiClient.Person("test@test", "F1", PersonId, "L1");
personClientMock = new Mock<IPersonClient>();
personClientMock.Setup(pc => pc.LookupPersonAsync(UsreUrn)).ReturnsAsync(person);

sessionMock = new Mock<ISession>();
sessionMock.Setup(session => session.Get<UserDetails>(Session.UserDetailsKey))
.Returns(new UserDetails { UserUrn = UsreUrn });

model = new ClaimOrganisationInviteModel(personClientMock.Object, sessionMock.Object);
}

[Fact]
public async Task OnGet_ShouldRedirectToOrganisationSelection_WhenPersonAndInviteClaimedSuccessfully()
{
var personInviteId = Guid.NewGuid();
var claimPersonInvite = new ClaimPersonInvite(personInviteId);
personClientMock.Setup(pc => pc.ClaimPersonInviteAsync(PersonId, claimPersonInvite)).Returns(Task.CompletedTask);

var result = await model.OnGet(personInviteId);

result.Should().BeOfType<RedirectToPageResult>()
.Which.PageName.Should().Be("OrganisationSelection");
personClientMock.Verify(pc => pc.LookupPersonAsync(UsreUrn), Times.Once);
personClientMock.Verify(pc => pc.ClaimPersonInviteAsync(PersonId, claimPersonInvite), Times.Once);
}

[Fact]
public async Task OnGet_ShouldThrowForOtherApiErrors()
{
var personInviteId = Guid.NewGuid();
var problemDetails = new ProblemDetails("", "", null, "", "") { AdditionalProperties = { { "code", "SOME_OTHER_ERROR" } } };
personClientMock.Setup(pc => pc.ClaimPersonInviteAsync(PersonId, new ClaimPersonInvite(personInviteId)))
.ThrowsAsync(new ApiException<ProblemDetails>("Some other error", 400, "", null, problemDetails, null));

Func<Task> act = async () => await model.OnGet(personInviteId);

await act.Should().ThrowAsync<ApiException<ProblemDetails>>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using CO.CDP.OrganisationApp.Pages.Users;
using FluentAssertions;
using Microsoft.AspNetCore.Mvc;

namespace CO.CDP.OrganisationApp.Tests.Pages.Users;

public class OrganisationInviteModelTests
{
[Fact]
public void OnGet_RedirectsToOneLoginWithRedirectUriQuerystring()
{
var personInviteId = Guid.NewGuid();

var result = new OrganisationInviteModel().OnGet(personInviteId);

result.Should().BeOfType<RedirectResult>()
.Which.Url.Should().Be($"/one-login/sign-in?redirecturi=%2Fclaim-organisation-invite%2F{personInviteId}");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
using Microsoft.AspNetCore.Mvc.RazorPages;
using CO.CDP.Organisation.WebApiClient;
using CO.CDP.OrganisationApp.Constants;
using CO.CDP.OrganisationApp.Pages.Users;

namespace CO.CDP.OrganisationApp.Pages.Users;
namespace CO.CDP.OrganisationApp.Tests.Pages.Users;

public class UserCheckAnswersModelTests
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
using CO.CDP.Organisation.WebApiClient;
using CO.CDP.OrganisationApp.Models;
using CO.CDP.OrganisationApp.Pages.Users;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Moq;

namespace CO.CDP.OrganisationApp.Pages.Users;
namespace CO.CDP.OrganisationApp.Tests.Pages.Users;

public class UserRemoveConfirmationModelTests
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
using CO.CDP.Organisation.WebApiClient;
using CO.CDP.OrganisationApp.Models;
using CO.CDP.OrganisationApp.Pages.Users;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Moq;

namespace CO.CDP.OrganisationApp.Pages.Users;
namespace CO.CDP.OrganisationApp.Tests.Pages.Users;

public class UserSummaryModelTests
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,36 @@ public async Task OnPost_WhenValidModel_ShouldRegisterPerson()
.Which.PageName.Should().Be("OrganisationSelection");
}

[Fact]
public async Task OnPost_WhenValidModelAndRelativeRedirectUrlProvided_ShouldRedirectToRedirectUrl()
{
var model = GivenYourDetailsModel();

sessionMock.Setup(s => s.Get<UserDetails>(Session.UserDetailsKey))
.Returns(new UserDetails { UserUrn = "urn:fdc:gov.uk:2022:bad51" });
personClientMock.Setup(s => s.CreatePersonAsync(It.IsAny<NewPerson>())).ReturnsAsync(dummyPerson);

var actionResult = await model.OnPost("/org/1");

actionResult.Should().BeOfType<RedirectResult>()
.Which.Url.Should().Be("/org/1");
}

[Fact]
public async Task OnPost_WhenValidModelAndAbsoluteRedirectUrlProvided_ShouldRedirectToOrganisationDetailsPageWithoutRedirectUrlQueryString()
{
var model = GivenYourDetailsModel();

sessionMock.Setup(s => s.Get<UserDetails>(Session.UserDetailsKey))
.Returns(new UserDetails { UserUrn = "urn:fdc:gov.uk:2022:bad51" });
personClientMock.Setup(s => s.CreatePersonAsync(It.IsAny<NewPerson>())).ReturnsAsync(dummyPerson);

var actionResult = await model.OnPost("http://test-domain/org/1");

actionResult.Should().BeOfType<RedirectToPageResult>()
.Which.PageName.Should().Be("OrganisationSelection");
}

[Fact]
public async Task OnPost_WhenErrorInRegisteringPerson_ShouldReturnPageWithError()
{
Expand Down
7 changes: 7 additions & 0 deletions Frontend/CO.CDP.OrganisationApp/Helper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace CO.CDP.OrganisationApp;

public static class Helper
{
public static bool ValidRelativeUri(string? redirectUri)
=> !string.IsNullOrWhiteSpace(redirectUri) && Uri.TryCreate(redirectUri, UriKind.Relative, out var _);
}
Loading