Skip to content

Commit

Permalink
Merge branch 'main' into feature/DP-660-Apply-Sorting-on-FormAnswers
Browse files Browse the repository at this point in the history
  • Loading branch information
shilpigoel-goaco committed Oct 3, 2024
2 parents eec9f7f + 21e2f6e commit 7ee42b9
Show file tree
Hide file tree
Showing 122 changed files with 15,611 additions and 1,132 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ jobs:
echo "Version: $VERSION"
echo "version=${VERSION}" >> $GITHUB_OUTPUT
- name: Build
run: make build-docker
run: make build-docker VERSION=${IMAGE_VERSION}
env:
IMAGE_VERSION: ${{ steps.version.outputs.version }}
- name: Start services
Expand Down
20 changes: 20 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -172,51 +172,71 @@ RUN dotnet tool restore
RUN dotnet ef migrations bundle -p /src/Services/CO.CDP.EntityVerification --self-contained -o /app/migrations/efbundle

FROM base AS migrations-organisation-information
ARG VERSION
ENV VERSION=${VERSION}
WORKDIR /app
COPY --from=build-migrations-organisation-information /app/migrations/efbundle .
ENTRYPOINT /app/efbundle --connection "Host=$OrganisationInformationDatabase__Host;Database=$OrganisationInformationDatabase__Database;Username=$OrganisationInformationDatabase__Username;Password=$OrganisationInformationDatabase__Password;"

FROM base AS migrations-entity-verification
ARG VERSION
ENV VERSION=${VERSION}
WORKDIR /app
COPY --from=build-migrations-entity-verification /app/migrations/efbundle .
ENTRYPOINT /app/efbundle --connection "Host=$EntityVerificationDatabase__Host;Database=$EntityVerificationDatabase__Database;Username=$EntityVerificationDatabase__Username;Password=$EntityVerificationDatabase__Password;"

FROM base AS final-authority
ARG VERSION
ENV VERSION=${VERSION}
WORKDIR /app
COPY --from=publish-authority /app/publish .
ENTRYPOINT ["dotnet", "CO.CDP.Organisation.Authority.dll"]

FROM base AS final-tenant
ARG VERSION
ENV VERSION=${VERSION}
WORKDIR /app
COPY --from=publish-tenant /app/publish .
ENTRYPOINT ["dotnet", "CO.CDP.Tenant.WebApi.dll"]

FROM base AS final-organisation
ARG VERSION
ENV VERSION=${VERSION}
WORKDIR /app
COPY --from=publish-organisation /app/publish .
ENTRYPOINT ["dotnet", "CO.CDP.Organisation.WebApi.dll"]

FROM base AS final-person
ARG VERSION
ENV VERSION=${VERSION}
WORKDIR /app
COPY --from=publish-person /app/publish .
ENTRYPOINT ["dotnet", "CO.CDP.Person.WebApi.dll"]

FROM base AS final-forms
ARG VERSION
ENV VERSION=${VERSION}
WORKDIR /app
COPY --from=publish-forms /app/publish .
ENTRYPOINT ["dotnet", "CO.CDP.Forms.WebApi.dll"]

FROM base AS final-data-sharing
ARG VERSION
ENV VERSION=${VERSION}
WORKDIR /app
COPY --from=publish-data-sharing /app/publish .
ENTRYPOINT ["dotnet", "CO.CDP.DataSharing.WebApi.dll"]

FROM base AS final-entity-verification
ARG VERSION
ENV VERSION=${VERSION}
WORKDIR /app
COPY --from=publish-entity-verification /app/publish .
ENTRYPOINT ["dotnet", "CO.CDP.EntityVerification.dll"]

FROM base AS final-organisation-app
ARG VERSION
ENV VERSION=${VERSION}
WORKDIR /app
COPY --from=publish-organisation-app /app/publish .
ENTRYPOINT ["dotnet", "CO.CDP.OrganisationApp.dll"]
52 changes: 32 additions & 20 deletions Frontend/CO.CDP.OrganisationApp.Tests/AuthorizationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,26 +117,6 @@ public static IEnumerable<object[]> TestCases()
yield return new object[] { $"/organisation/{testOrganisationId}/users/{personInviteGuid}/change-role?handler=personInvite", new string[] { "Person invite Last name", "Can add, remove and edit users" } };
}

[Theory]
[MemberData(nameof(TestCases))]
public async Task TestAuthorizationIsSuccessful_WhenUserIsAllowedToAccessResourceAsSupportAdminUser(string url, string[] expectedTexts)
{
var _httpClient = BuildHttpClient([], [PersonScopes.SupportAdmin]);

var request = new HttpRequestMessage(HttpMethod.Get, url);

var response = await _httpClient.SendAsync(request);

var responseBody = await response.Content.ReadAsStringAsync();

responseBody.Should().NotBeNull();
response.StatusCode.Should().Be(HttpStatusCode.OK);
foreach (string expectedText in expectedTexts)
{
responseBody.Should().Contain(expectedText);
}
}

[Theory]
[MemberData(nameof(TestCases))]
public async Task TestAuthorizationIsSuccessful_WhenUserIsAllowedToAccessResourceAsAdminUser(string url, string[] expectedTexts)
Expand Down Expand Up @@ -226,4 +206,36 @@ public async Task TestCannotSeeUsersLinkOnOrganisationPage_WhenUserIsNotAllowedT
responseBody.Should().NotContain($"href=\"/organisation/{testOrganisationId}/users/user-summary\">Users</a>");
responseBody.Should().NotContain("Users");
}

public static IEnumerable<object[]> SupportAdminAccessTestCases()
{
yield return new object[] { $"/organisation/{testOrganisationId}", new string[] { "Organisation name", "Organisation identifier", "Organisation email", "Supplier information" }, new string[] { "Change", "Users" }, HttpStatusCode.OK };
yield return new object[] { $"/organisation/{testOrganisationId}/address/uk?frm-overview", new string[] {}, new string[] {}, HttpStatusCode.NotFound };
yield return new object[] { $"/organisation/{testOrganisationId}/users/user-summary", new string[] {}, new string[] {}, HttpStatusCode.NotFound };
}

[Theory]
[MemberData(nameof(SupportAdminAccessTestCases))]
public async Task TestAuthorizationIsSuccessful_WhenUserIsAllowedToAccessResourceAsSupportAdminUser(string url, string[] shouldContain, string[] shouldNotContain, HttpStatusCode expectedStatusCode)
{
var _httpClient = BuildHttpClient([], [PersonScopes.SupportAdmin]);

var request = new HttpRequestMessage(HttpMethod.Get, url);

var response = await _httpClient.SendAsync(request);

var responseBody = await response.Content.ReadAsStringAsync();

responseBody.Should().NotBeNull();
response.StatusCode.Should().Be(expectedStatusCode);
foreach (string expectedText in shouldContain)
{
responseBody.Should().Contain(expectedText);
}

foreach (string expectedText in shouldNotContain)
{
responseBody.Should().NotContain(expectedText);
}
}
}
133 changes: 96 additions & 37 deletions Frontend/CO.CDP.OrganisationApp.Tests/FormsEngineTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,40 +56,59 @@ private static WebApiClient.SectionQuestionsResponse CreateApiSectionQuestionsRe
id: sectionId,
title: "SectionTitle"
),
questions: new List<WebApiClient.FormQuestion>
{
new WebApiClient.FormQuestion(
id: questionId,
title: "Question1",
description: "Description1",
caption: "Caption1",
summaryTitle: "Question1 Title",
type: WebApiClient.FormQuestionType.Text,
isRequired: true,
nextQuestion: nextQuestionId,
nextQuestionAlternative: null,
options: new WebApiClient.FormQuestionOptions(
choiceProviderStrategy: choiceProviderStrategy,
choices: new List<WebApiClient.FormQuestionChoice>
{
new WebApiClient.FormQuestionChoice(
id: Guid.NewGuid(),
title: "Option1",
groupName: null,
hint: new WebApiClient.FormQuestionChoiceHint(
title: null,
description: "Hint Description"
)
questions: new List<WebApiClient.FormQuestion>
{
new WebApiClient.FormQuestion(
id: questionId,
title: "Question1",
description: "Description1",
caption: "Caption1",
summaryTitle: "Question1 Title",
type: WebApiClient.FormQuestionType.Text,
isRequired: true,
nextQuestion: nextQuestionId,
nextQuestionAlternative: null,
options: new WebApiClient.FormQuestionOptions(
choiceProviderStrategy: choiceProviderStrategy,
choices: new List<WebApiClient.FormQuestionChoice>
{
new WebApiClient.FormQuestionChoice(
id: Guid.NewGuid(),
title: "Option1",
groupName: null,
hint: new WebApiClient.FormQuestionChoiceHint(
title: null,
description: "Hint Description"
)
)
},
groups: new List<WebApiClient.FormQuestionGroup>
{
new WebApiClient.FormQuestionGroup(
name: "Group 1",
hint: "Group 1 Hint",
caption: "Group 1 Caption",
choices: new List<WebApiClient.FormQuestionGroupChoice>
{
new WebApiClient.FormQuestionGroupChoice(
title: "Group Choice 1",
value: "group_choice_1"
),
new WebApiClient.FormQuestionGroupChoice(
title: "Group Choice 2",
value: "group_choice_2"
)
}
)
}
)
}
)
)
},
answerSets: new List<WebApiClient.FormAnswerSet>()
);
)
},
answerSets: new List<WebApiClient.FormAnswerSet>()
);
}

private static SectionQuestionsResponse CreateModelSectionQuestionsResponse(Guid sectionId, Guid questionId, Guid nextQuestionId, string? choiceProviderStrategy = null, List<string>? options = null)
private static SectionQuestionsResponse CreateModelSectionQuestionsResponse(Guid sectionId, Guid questionId, Guid nextQuestionId, string? choiceProviderStrategy = null, Dictionary<string, string>? options = null)
{
return new SectionQuestionsResponse
{
Expand All @@ -108,8 +127,9 @@ private static SectionQuestionsResponse CreateModelSectionQuestionsResponse(Guid
NextQuestion = nextQuestionId,
Options = new FormQuestionOptions
{
Choices = options == null ? new List<string> { "Option1" } : options,
ChoiceProviderStrategy = choiceProviderStrategy
Choices = options == null ? new Dictionary<string, string>() { { "Option1", "Option1" } } : options,
ChoiceProviderStrategy = choiceProviderStrategy,
ChoiceAnswerFieldName = "OptionValue",
}
}
}
Expand Down Expand Up @@ -139,9 +159,26 @@ public async Task GetFormSectionAsync_ShouldFetchAndCacheResponse_WhenCachedResp
var (organisationId, formId, sectionId, sessionKey) = CreateTestGuids();
var questionId = Guid.NewGuid();
var nextQuestionId = Guid.NewGuid();

var apiResponse = CreateApiSectionQuestionsResponse(sectionId, questionId, nextQuestionId);

var expectedResponse = CreateModelSectionQuestionsResponse(sectionId, questionId, nextQuestionId);

expectedResponse.Questions[0].Options.Groups = new List<FormQuestionGroup>
{
new FormQuestionGroup
{
Name = "Group 1",
Hint = "Group 1 Hint",
Caption = "Group 1 Caption",
Choices = new List<FormQuestionGroupChoice>
{
new FormQuestionGroupChoice { Title = "Group Choice 1", Value = "group_choice_1" },
new FormQuestionGroupChoice { Title = "Group Choice 2", Value = "group_choice_2" }
}
}
};

_tempDataServiceMock.Setup(t => t.Peek<SectionQuestionsResponse>(sessionKey))
.Returns((SectionQuestionsResponse?)null);
_choiceProviderServiceMock.Setup(t => t.GetStrategy(It.IsAny<string>()))
Expand Down Expand Up @@ -254,15 +291,37 @@ public async Task GetFormSectionAsync_ShouldFetchChoicesFromCustomChoiceProvider
var questionId = Guid.NewGuid();
var nextQuestionId = Guid.NewGuid();
var apiResponse = CreateApiSectionQuestionsResponse(sectionId, questionId, nextQuestionId, "ExclusionAppliesToChoiceProviderStrategy");
var expectedResponse = CreateModelSectionQuestionsResponse(sectionId, questionId, nextQuestionId, "ExclusionAppliesToChoiceProviderStrategy", ["User's current organisation", "Connected person", "Connected organisation"]);
var expectedResponse = CreateModelSectionQuestionsResponse(sectionId, questionId, nextQuestionId, "ExclusionAppliesToChoiceProviderStrategy");

expectedResponse.Questions[0].Options.Choices = new Dictionary<string, string>() {
{ $@"{{""id"":""{organisationId}"",""type"":""organisation""}}", "User's current organisation" },
{ "{\"id\":\"e4bdd7ef-8200-4257-9892-b16f43d1803e\",\"type\":\"connected-entity\"}", "Connected person" },
{ "{\"id\":\"4c8dccba-df39-4997-814b-7599ed9b5bed\",\"type\":\"connected-entity\"}", "Connected organisation" } };

expectedResponse.Questions[0].Options.ChoiceAnswerFieldName = "JsonValue";

expectedResponse.Questions[0].Options.Groups = new List<FormQuestionGroup>
{
new FormQuestionGroup
{
Name = "Group 1",
Hint = "Group 1 Hint",
Caption = "Group 1 Caption",
Choices = new List<FormQuestionGroupChoice>
{
new FormQuestionGroupChoice { Title = "Group Choice 1", Value = "group_choice_1" },
new FormQuestionGroupChoice { Title = "Group Choice 2", Value = "group_choice_2" }
}
}
};

_organisationClientMock.Setup(c => c.GetConnectedEntitiesAsync(It.IsAny<Guid>()))
.ReturnsAsync([
new ConnectedEntityLookup(new Guid(), ConnectedEntityType.Individual, "Connected person", new Uri("http://whatever")),
new ConnectedEntityLookup(new Guid(), ConnectedEntityType.Organisation, "Connected organisation", new Uri("http://whatever"))
new ConnectedEntityLookup(new Guid("e4bdd7ef-8200-4257-9892-b16f43d1803e"), ConnectedEntityType.Individual, "Connected person", new Uri("http://whatever")),
new ConnectedEntityLookup(new Guid("4c8dccba-df39-4997-814b-7599ed9b5bed"), ConnectedEntityType.Organisation, "Connected organisation", new Uri("http://whatever"))
]);
_organisationClientMock.Setup(c => c.GetOrganisationAsync(organisationId))
.ReturnsAsync(new Organisation.WebApiClient.Organisation([], [],null, null, organisationId, null, "User's current organisation", []));
.ReturnsAsync(new Organisation.WebApiClient.Organisation([], [], null, null, organisationId, null, "User's current organisation", []));
_userInfoServiceMock.Setup(u => u.GetOrganisationId()).Returns(organisationId);
_tempDataServiceMock.Setup(t => t.Peek<SectionQuestionsResponse>(sessionKey))
.Returns((SectionQuestionsResponse?)null);
Expand Down
Loading

0 comments on commit 7ee42b9

Please sign in to comment.