Skip to content

Commit

Permalink
Merge branch 'main' into feature/dp-970-incorrect-heading-supplier-in…
Browse files Browse the repository at this point in the history
…formation
  • Loading branch information
JBaigGoaco authored Dec 13, 2024
2 parents 543813f + 6cc747d commit b17a496
Show file tree
Hide file tree
Showing 45 changed files with 1,665 additions and 192 deletions.
46 changes: 46 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Run github actions locally with act https://github.com/nektos/act
# act --container-architecture linux/amd64 --artifact-server-path ./build/artifacts -W ./.github/workflows/build.yml

name: Build

on:
Expand Down Expand Up @@ -59,6 +62,7 @@ jobs:
outputs:
version: ${{ steps.version.outputs.version }}
images: ${{ steps.save.outputs.images }}
images_json: ${{ steps.save.outputs.images_json }}
steps:
- uses: actions/checkout@v4
with:
Expand Down Expand Up @@ -97,9 +101,12 @@ jobs:
id: save
run: |
IMAGES=$(docker images | awk '$1 ~ /cabinetoffice\/cdp-/ && $2 ~ /^'$IMAGE_VERSION'$/ { print $1":"$2}' | tr '\n' ' ')
IMAGES_JSON=$(echo $IMAGES | tr " " "\n" | jq -R . | jq -c -s .)
echo "Images to be saved: $IMAGES"
echo "Images to be saved (json): $IMAGES_JSON"
docker save -o cdp-images.tar $IMAGES
echo "images=${IMAGES}" >> $GITHUB_OUTPUT
echo "images_json=${IMAGES_JSON}" >> $GITHUB_OUTPUT
env:
IMAGE_VERSION: ${{ steps.version.outputs.version }}
- name: Upload Docker Images as Artifacts
Expand All @@ -108,6 +115,45 @@ jobs:
name: docker-images
path: cdp-images.tar

vulnerability-scan:
# since we do not fail the build for now, but the report is to get feedback, only run it on the main branch and tags
if: (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')) && github.repository_owner == 'cabinetoffice'
runs-on: ubuntu-latest
name: Scan for vulnerabilities
needs: [test, package]
strategy:
matrix:
image: ${{ fromJSON(needs.package.outputs.images_json) }}
steps:
- uses: actions/checkout@v4

- name: Download Docker Images
uses: actions/download-artifact@v4
with:
name: docker-images
- name: Load Docker Images
run: docker load -i cdp-images.tar

- name: Determine the category
id: category
run: |
image=${{ matrix.image }}
category=${image%%:*}
echo "category=$category" >> $GITHUB_OUTPUT
- name: Scan ${{ matrix.image }}
uses: anchore/scan-action@v5
id: scan
with:
image: "${{ matrix.image }}"
fail-build: false
severity-cutoff: critical
output-format: sarif
- name: Upload Image Vulnerability Reports
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: ${{ steps.scan.outputs.sarif }}
category: ${{ steps.category.outputs.category }}

publish:
if: (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')) && github.repository_owner == 'cabinetoffice'
runs-on: ubuntu-latest
Expand Down
4 changes: 2 additions & 2 deletions .mise.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[tools]
dotnet = "8.0.401"
terraform = "1.9.5"
terragrunt = "0.66.9"
terraform = "1.10.2"
terragrunt = "0.69.10"
poetry = "1.8.3"
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
using CO.CDP.Localization;
using CO.CDP.OrganisationApp.Models;
using CO.CDP.OrganisationApp.Pages.Consortium;
using FluentAssertions;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Routing;
using Moq;

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

public class ConsortiumAddressModelTest
{
private readonly Mock<ISession> _sessionMock;

public ConsortiumAddressModelTest()
{
_sessionMock = new Mock<ISession>();
_sessionMock.Setup(session => session.Get<UserDetails>(Session.UserDetailsKey))
.Returns(new UserDetails { UserUrn = "urn:test" });
}

[Fact]
public void WhenEmptyModelIsPosted_ShouldRaiseValidationErrors()
{
var model = GivenConsortiumAddressModel();

var results = ModelValidationHelper.Validate(model.Address);

results.Count.Should().Be(4);
}

[Fact]
public void WhenAddressLine1IsEmpty_ShouldRaiseAddressLine1ValidationError()
{
var model = GivenConsortiumAddressModel();

var results = ModelValidationHelper.Validate(model.Address);

results.Any(c => c.MemberNames.Contains("AddressLine1")).Should().BeTrue();

results.Where(c => c.MemberNames.Contains("AddressLine1")).First()
.ErrorMessage.Should().Be(nameof(StaticTextResource.Shared_Address_AddressLine1_ErrorMessage));
}

[Fact]
public void WhenAddressLine1IsNotEmpty_ShouldNotRaiseAddressLine1ValidationError()
{
var model = GivenConsortiumAddressModel();
model.Address.AddressLine1 = "dummay";

var results = ModelValidationHelper.Validate(model.Address);

results.Any(c => c.MemberNames.Contains("AddressLine1")).Should().BeFalse();
}

[Fact]
public void WhenTownOrCityIsEmpty_ShouldRaiseTownOrCityValidationError()
{
var model = GivenConsortiumAddressModel();

var results = ModelValidationHelper.Validate(model.Address);

results.Any(c => c.MemberNames.Contains("TownOrCity")).Should().BeTrue();

results.Where(c => c.MemberNames.Contains("TownOrCity")).First()
.ErrorMessage.Should().Be(nameof(StaticTextResource.Shared_Address_TownOrCity_ErrorMessage));
}

[Fact]
public void WhenTownOrCityIsNotEmpty_ShouldNotRaiseTownOrCityValidationError()
{
var model = GivenConsortiumAddressModel();
model.Address.TownOrCity = "dummay";

var results = ModelValidationHelper.Validate(model.Address);

results.Any(c => c.MemberNames.Contains("TownOrCity")).Should().BeFalse();
}

[Fact]
public void WhenPostcodeIsNotEmpty_ShouldNotRaisePostcodeValidationError()
{
var model = GivenConsortiumAddressModel();
model.Address.Postcode = "dummay";

var results = ModelValidationHelper.Validate(model.Address);

results.Any(c => c.MemberNames.Contains("Postcode")).Should().BeFalse();
}

[Fact]
public void WhenCountryIsNotEmpty_ShouldNotRaiseCountryValidationError()
{
var model = GivenConsortiumAddressModel();
model.Address.Country = "EN";

var results = ModelValidationHelper.Validate(model.Address);

results.Any(c => c.MemberNames.Contains("Country")).Should().BeFalse();
}

[Fact]
public void OnPost_WhenInValidModel_ShouldReturnSamePage()
{
var modelState = new ModelStateDictionary();
modelState.AddModelError("error", "some error");
var actionContext = new ActionContext(new DefaultHttpContext(),
new RouteData(), new PageActionDescriptor(), modelState);
var pageContext = new PageContext(actionContext);

var model = GivenConsortiumAddressModel();
model.PageContext = pageContext;

var actionResult = model.OnPost();

actionResult.Should().BeOfType<PageResult>();
}

[Fact]
public void OnPost_WhenValidModel_ShouldSetConsortiumDetailsInSession()
{
var model = GivenConsortiumAddressModel();

var consortiumDetails = DummyConsortiumDetails();

_sessionMock.Setup(s => s.Get<ConsortiumDetails>(Session.ConsortiumKey)).Returns(consortiumDetails);

model.OnPost();

_sessionMock.Verify(s => s.Get<ConsortiumDetails>(Session.ConsortiumKey), Times.Once);
_sessionMock.Verify(s => s.Set(Session.ConsortiumKey, It.IsAny<ConsortiumDetails>()), Times.Once);
}

[Fact]
public void OnPost_WhenValidModelAndBuyer_ShouldRedirectToConsortiumEmailPage()
{
var consortiumDetails = DummyConsortiumDetails();

_sessionMock.Setup(s => s.Get<ConsortiumDetails>(Session.ConsortiumKey))
.Returns(consortiumDetails);

var model = GivenConsortiumAddressModel();

var actionResult = model.OnPost();

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

[Fact]
public void OnGet_ValidSession_ReturnsConsortiumDetails()
{
var consortiumDetails = DummyConsortiumDetails();

_sessionMock.Setup(s => s.Get<ConsortiumDetails>(Session.ConsortiumKey))
.Returns(consortiumDetails);
_sessionMock.Setup(s => s.Set(Session.ConsortiumKey, consortiumDetails));

var model = GivenConsortiumAddressModel();

model.OnGet();

model.Address.AddressLine1.Should().Be(consortiumDetails.PostalAddress!.AddressLine1);
model.Address.TownOrCity.Should().Be(consortiumDetails.PostalAddress.TownOrCity);
model.Address.Postcode.Should().Be(consortiumDetails.PostalAddress.Postcode);
}

private ConsortiumDetails DummyConsortiumDetails(string consortiumName = "Consortium 1", string consortiumEmailAddress = "[email protected]")
{
var consortiumDetails = new ConsortiumDetails
{
ConsortiumName = consortiumName,
ConsortiumEmail = consortiumEmailAddress,
PostalAddress = new Models.Address { AddressLine1 = "Address Line 1", TownOrCity = "London", Postcode = "SW1Y 5ED", CountryName = "United kindom", Country = "GB" }
};

return consortiumDetails;
}

private ConsortiumAddressModel GivenConsortiumAddressModel()
{
return new ConsortiumAddressModel(_sessionMock.Object) { Address = new() };
}
}
Loading

0 comments on commit b17a496

Please sign in to comment.