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

Feature/448427 pom subs validation #20

Open
wants to merge 43 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
ccc7291
WIP
IdrisEviden Oct 25, 2024
ad121d6
Merge branch 'main' into feature/448427-pom-subs-validation
IdrisEviden Oct 25, 2024
96f35bf
WIP
IdrisEviden Oct 25, 2024
05d9eb3
Unit tests for subsidiary validation
IdrisEviden Oct 27, 2024
8d5253b
Unit tests
IdrisEviden Oct 28, 2024
d7cef53
Attending to SonarQube feedbACK
IdrisEviden Oct 28, 2024
be6fe8e
refactoring and more tests
IdrisEviden Oct 29, 2024
5ea22f1
Merge branch 'main' into feature/448427-pom-subs-validation
IdrisEviden Oct 29, 2024
694fffb
added tests
IdrisEviden Oct 29, 2024
aa3999e
Correction of error thrown up in the Build Docker Image satge of the …
IdrisEviden Oct 29, 2024
9db9f18
Corrected filename in Dockerfile
IdrisEviden Oct 29, 2024
d41fb58
Added more tests
IdrisEviden Oct 29, 2024
f788bdc
Added more tests
IdrisEviden Oct 29, 2024
c45a051
Added more tests
IdrisEviden Oct 30, 2024
b4de89e
Added more tests
IdrisEviden Oct 30, 2024
eafe6d1
Added more tests
IdrisEviden Oct 30, 2024
d3f232b
Edited gitignore to remove local.settings 18.json
IdrisEviden Oct 30, 2024
0ed65b4
Added more tests
IdrisEviden Oct 30, 2024
2fe9063
Added more tests
IdrisEviden Oct 30, 2024
dded9ac
Added more tests
IdrisEviden Oct 30, 2024
a5d0788
Excluded CompanyDetailsDataItem and CompanyDetailsDataResult from cov…
IdrisEviden Oct 30, 2024
ca9429d
Added more tests
IdrisEviden Oct 31, 2024
f609d7d
Made changes to reflect changes that came out of QA of User Story 448425
IdrisEviden Oct 31, 2024
c0ef4bc
Made changes to merge the errorcodes for same producer into one colle…
IdrisEviden Oct 31, 2024
c88e991
Made changes to merge the errorcodes for same producer into one colle…
IdrisEviden Oct 31, 2024
c1c9af3
Changed FindMatchingProducerTests to use fluent validation
IdrisEviden Nov 1, 2024
2c4001f
Changed FindMatchingProducerTests to use fluent validation
IdrisEviden Nov 1, 2024
01d7e1a
Changed CompanyDetailsDataItemTests.cs to use fluent validation
IdrisEviden Nov 1, 2024
f0c3dbf
Changed OrganisationMatcherTests to use fluent validation
IdrisEviden Nov 1, 2024
977adad
Changed ProducerValidationEventFormatterTests to use fluent validation
IdrisEviden Nov 1, 2024
09aa528
Changed RequestValidatorTests to use fluent validation
IdrisEviden Nov 1, 2024
84b52b9
Changed SubsidiaryMatcherTests to use fluent validation
IdrisEviden Nov 1, 2024
c0d8697
Changed SubsidiaryValidationEvaluatorTests to use fluent validation
IdrisEviden Nov 1, 2024
878e919
Changed ValidationServiceProducerRowValidatorTests to use fluent vali…
IdrisEviden Nov 1, 2024
a415370
Changed ValidationServiceTests to use fluent validation
IdrisEviden Nov 1, 2024
605c675
Resolved a review comment
IdrisEviden Nov 1, 2024
c37c36f
Removed Data project, moving functional contents to Application
IdrisEviden Nov 1, 2024
ca3556a
Some refactoring
IdrisEviden Nov 1, 2024
e73f2f2
Some refactoring
IdrisEviden Nov 1, 2024
dcda9da
project removed from docker file
Fahad-Ali-Eviden Nov 1, 2024
a53f7ea
Merge branch 'feature/448427-pom-subs-validation' of https://github.c…
Fahad-Ali-Eviden Nov 1, 2024
753f96d
Some refactoring
IdrisEviden Nov 1, 2024
d2854b3
Merge branch 'feature/448427-pom-subs-validation' of https://github.c…
IdrisEviden Nov 1, 2024
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
using System.Net;
using EPR.ProducerContentValidation.Application.Clients;
using EPR.ProducerContentValidation.Data.Config;
using EPR.ProducerContentValidation.Data.Models.Subsidiary;
using FluentAssertions;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Moq.Protected;
using Newtonsoft.Json;

namespace EPR.ProducerContentValidation.Application.UnitTests.Clients
{
[TestClass]
public class CompanyDetailsApiClientTests
{
private CompanyDetailsApiConfig? _config;

[TestInitialize]
public void Setup()
{
_config = new CompanyDetailsApiConfig
{
BaseUrl = "https://www.testurl.com",
ClientId = "test-client-id",
Timeout = 5,
};
}

[TestMethod]
public async Task GetSubsidiaryDetails_ShouldReturnSubsidiaryDetailsRequest_OnSuccess()
{
// Arrange
var request = new SubsidiaryDetailsRequest();
var content = JsonConvert.SerializeObject(request);
var responseMessage = new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(content),
};
var handlerMock = new Mock<HttpMessageHandler>(MockBehavior.Strict);
handlerMock
.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.IsAny<HttpRequestMessage>(),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(content),
})
.Verifiable();
var httpClient = new HttpClient(handlerMock.Object)
{
BaseAddress = new Uri(_config.BaseUrl),
Timeout = TimeSpan.FromSeconds(_config.Timeout),
};
var sut = new CompanyDetailsApiClient(httpClient, NullLogger<CompanyDetailsApiClient>.Instance);

// Act
var result = await sut.GetSubsidiaryDetails(request);

// Assert
result.Should().BeEquivalentTo(request);
handlerMock.Protected().Verify(
"SendAsync",
Times.Once(),
ItExpr.Is<HttpRequestMessage>(req =>
req.Method == HttpMethod.Post &&
req.RequestUri.ToString().EndsWith("api/subsidiary-details")),
ItExpr.IsAny<CancellationToken>());
}

[DataRow(HttpStatusCode.Conflict)]
[DataRow(HttpStatusCode.BadRequest)]
[DataRow(HttpStatusCode.BadGateway)]
[DataRow(HttpStatusCode.Unauthorized)]
[TestMethod]
public async Task GetSubsidiaryDetails_WhenSendAsyncNotSuccessful_ThrowsError(HttpStatusCode statusCode)
{
// Arrange
var handlerMock = new Mock<HttpMessageHandler>(MockBehavior.Strict);
handlerMock
.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.IsAny<HttpRequestMessage>(),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(new HttpResponseMessage()
{
StatusCode = statusCode,
})
.Verifiable();

var httpClient = new HttpClient(handlerMock.Object)
{
BaseAddress = new Uri(_config.BaseUrl),
Timeout = TimeSpan.FromSeconds(_config.Timeout),
};
var sut = new CompanyDetailsApiClient(httpClient, NullLogger<CompanyDetailsApiClient>.Instance);

// Act
Func<Task> act = () => sut.GetSubsidiaryDetails(new SubsidiaryDetailsRequest());

// Assert
await act.Should().ThrowAsync<Exception>();
}

[TestMethod]
public async Task GetSubsidiaryDetails_ShouldReturnDefault_WhenResponseContentIsEmpty()
{
// Arrange
var request = new SubsidiaryDetailsRequest();
var handlerMock = new Mock<HttpMessageHandler>(MockBehavior.Strict);
handlerMock
.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.IsAny<HttpRequestMessage>(),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(string.Empty), // Simulate empty content
})
.Verifiable();

var httpClient = new HttpClient(handlerMock.Object)
{
BaseAddress = new Uri(_config.BaseUrl),
Timeout = TimeSpan.FromSeconds(_config.Timeout),
};
var sut = new CompanyDetailsApiClient(httpClient, NullLogger<CompanyDetailsApiClient>.Instance);

// Act
var result = await sut.GetSubsidiaryDetails(request);

// Assert
result.Should().BeNull(); // Since default for reference type is null
handlerMock.Protected().Verify(
"SendAsync",
Times.Once(),
ItExpr.Is<HttpRequestMessage>(req =>
req.Method == HttpMethod.Post &&
req.RequestUri.ToString().EndsWith("api/subsidiary-details")),
ItExpr.IsAny<CancellationToken>());
}
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
using System.Diagnostics;
using Bogus;
using EPR.ProducerContentValidation.Application.Clients;
using EPR.ProducerContentValidation.Application.Constants;
using EPR.ProducerContentValidation.Application.Models;
using EPR.ProducerContentValidation.Application.Options;
using EPR.ProducerContentValidation.Application.Profiles;
using EPR.ProducerContentValidation.Application.ReferenceData;
using EPR.ProducerContentValidation.Application.Services;
using EPR.ProducerContentValidation.Application.Services.Helpers.Interfaces;
using EPR.ProducerContentValidation.Application.Services.Interfaces;
using EPR.ProducerContentValidation.Application.Services.Subsidiary;
using EPR.ProducerContentValidation.Application.Validators;
using EPR.ProducerContentValidation.Application.Validators.Factories;
using EPR.ProducerContentValidation.TestSupport;
using FluentAssertions;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.FeatureManagement;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;

Expand All @@ -28,6 +32,11 @@ public ValidatorsPerformanceTests()
Mock<IOptions<ValidationOptions>> validationOptionsMock = new();
Mock<IIssueCountService> errorCountServiceMock = new();
Mock<ILogger<ValidationService>> loggerMock = new();
Mock<IFeatureManager> featureManagerMock = new();
Mock<ISubsidiaryDetailsRequestBuilder> subsidiaryDetailsRequestBuilderMock = new();
Mock<ICompanyDetailsApiClient> companyDetailsApiClientMock = new();
Mock<IRequestValidator> requestValidatorMock = new();
Mock<IValidationServiceProducerRowValidator> validationServiceProducerRowValidatorMock = new();

var submissionConfigOptions = new Mock<IOptions<List<SubmissionPeriodOption>>>();

Expand All @@ -54,7 +63,12 @@ public ValidatorsPerformanceTests()
compositeValidatorUnderTest,
AutoMapperHelpers.GetMapper<ProducerProfile>(),
errorCountServiceMock.Object,
Microsoft.Extensions.Options.Options.Create(new StorageAccountOptions { PomContainer = "ContainerName" }));
Microsoft.Extensions.Options.Options.Create(new StorageAccountOptions { PomContainer = "ContainerName" }),
featureManagerMock.Object,
subsidiaryDetailsRequestBuilderMock.Object,
companyDetailsApiClientMock.Object,
requestValidatorMock.Object,
validationServiceProducerRowValidatorMock.Object);
}

[TestMethod]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
using EPR.ProducerContentValidation.Application.DTOs.SubmissionApi;
using EPR.ProducerContentValidation.Application.Models;
using EPR.ProducerContentValidation.Application.Services.Helpers;
using EPR.ProducerContentValidation.Application.Services.Helpers.Interfaces;
using EPR.ProducerContentValidation.Data.Models.Subsidiary;
using EPR.ProducerContentValidation.TestSupport;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;

namespace EPR.ProducerContentValidation.Application.UnitTests.Services.Helpers
{
[TestClass]
public class FindMatchingProducerTests
{
private readonly Mock<IOrganisationMatcher> _organisationMatcherMock;
private readonly Mock<ISubsidiaryMatcher> _subsidiaryMatcherMock;
private readonly Mock<ISubsidiaryValidationEvaluator> _subsidiaryValidationEvaluatorMock;
private readonly FindMatchingProducer _findMatchingProducer;

public FindMatchingProducerTests()
{
_organisationMatcherMock = new Mock<IOrganisationMatcher>();
_subsidiaryMatcherMock = new Mock<ISubsidiaryMatcher>();
_subsidiaryValidationEvaluatorMock = new Mock<ISubsidiaryValidationEvaluator>();

_findMatchingProducer = new FindMatchingProducer(
_organisationMatcherMock.Object,
_subsidiaryMatcherMock.Object,
_subsidiaryValidationEvaluatorMock.Object);
}

[TestMethod]
public void Match_NoMatchingOrganisation_ReturnsNull()
{
// Arrange
var row = ModelGenerator.CreateProducerRow(1);
var response = new SubsidiaryDetailsResponse();

_organisationMatcherMock
.Setup(m => m.FindMatchingOrganisation(row, response))
.Returns((SubsidiaryOrganisationDetail?)null);

// Act
var result = _findMatchingProducer.Match(row, response, 1);

// Assert
Assert.IsNull(result);
IdrisEviden marked this conversation as resolved.
Show resolved Hide resolved
_organisationMatcherMock.Verify(m => m.FindMatchingOrganisation(row, response), Times.Once);
_subsidiaryMatcherMock.Verify(m => m.FindMatchingSubsidiary(It.IsAny<ProducerRow>(), It.IsAny<SubsidiaryOrganisationDetail>()), Times.Never);
_subsidiaryValidationEvaluatorMock.Verify(m => m.EvaluateSubsidiaryValidation(It.IsAny<ProducerRow>(), It.IsAny<SubsidiaryDetail>(), It.IsAny<int>()), Times.Never);
}

[TestMethod]
public void Match_NoMatchingSubsidiary_ReturnsNull()
{
// Arrange
var row = ModelGenerator.CreateProducerRow(1);
var response = new SubsidiaryDetailsResponse();
var matchingOrg = new SubsidiaryOrganisationDetail();

_organisationMatcherMock
.Setup(m => m.FindMatchingOrganisation(row, response))
.Returns(matchingOrg);

_subsidiaryMatcherMock
.Setup(m => m.FindMatchingSubsidiary(row, matchingOrg))
.Returns((SubsidiaryDetail?)null);

// Act
var result = _findMatchingProducer.Match(row, response, 1);

// Assert
Assert.IsNull(result);
_organisationMatcherMock.Verify(m => m.FindMatchingOrganisation(row, response), Times.Once);
_subsidiaryMatcherMock.Verify(m => m.FindMatchingSubsidiary(row, matchingOrg), Times.Once);
_subsidiaryValidationEvaluatorMock.Verify(m => m.EvaluateSubsidiaryValidation(It.IsAny<ProducerRow>(), It.IsAny<SubsidiaryDetail>(), It.IsAny<int>()), Times.Never);
}

[TestMethod]
public void Match_MatchingOrganisationAndSubsidiary_ReturnsValidationResult()
{
// Arrange
var row = ModelGenerator.CreateProducerRow(1);
var response = new SubsidiaryDetailsResponse();
var matchingOrg = new SubsidiaryOrganisationDetail();
var matchingSub = new SubsidiaryDetail();
var expectedValidationResult = new ProducerValidationEventIssueRequest(
SubsidiaryId: "S123",
DataSubmissionPeriod: "2024-Q1",
RowNumber: 1,
ProducerId: "P456",
ProducerType: "Large",
ProducerSize: "Large",
WasteType: "Plastic",
PackagingCategory: "Containers",
MaterialType: "Polyethylene",
MaterialSubType: "High-Density",
FromHomeNation: "UK",
ToHomeNation: "Germany",
QuantityKg: "100",
QuantityUnits: "200",
BlobName: "ExampleBlobName",
ErrorCodes: new List<string> { "E001", "E002" });

_organisationMatcherMock
.Setup(m => m.FindMatchingOrganisation(row, response))
.Returns(matchingOrg);

_subsidiaryMatcherMock
.Setup(m => m.FindMatchingSubsidiary(row, matchingOrg))
.Returns(matchingSub);

_subsidiaryValidationEvaluatorMock
.Setup(m => m.EvaluateSubsidiaryValidation(row, matchingSub, 1))
.Returns(expectedValidationResult);

// Act
var result = _findMatchingProducer.Match(row, response, 1);

// Assert
Assert.AreEqual(expectedValidationResult, result);
_organisationMatcherMock.Verify(m => m.FindMatchingOrganisation(row, response), Times.Once);
_subsidiaryMatcherMock.Verify(m => m.FindMatchingSubsidiary(row, matchingOrg), Times.Once);
_subsidiaryValidationEvaluatorMock.Verify(m => m.EvaluateSubsidiaryValidation(row, matchingSub, 1), Times.Once);
}
}
}
Loading