diff --git a/Btms.Analytics.Tests/Btms.Analytics.Tests.csproj b/Btms.Analytics.Tests/Btms.Analytics.Tests.csproj
index b612975b..9e324cd9 100644
--- a/Btms.Analytics.Tests/Btms.Analytics.Tests.csproj
+++ b/Btms.Analytics.Tests/Btms.Analytics.Tests.csproj
@@ -40,6 +40,7 @@
+
diff --git a/Btms.Analytics.Tests/Fixtures/BasicSampleDataTestFixture.cs b/Btms.Analytics.Tests/Fixtures/BasicSampleDataTestFixture.cs
index 15760199..86de9b59 100644
--- a/Btms.Analytics.Tests/Fixtures/BasicSampleDataTestFixture.cs
+++ b/Btms.Analytics.Tests/Fixtures/BasicSampleDataTestFixture.cs
@@ -4,6 +4,7 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using TestDataGenerator.Scenarios;
+using TestGenerator.IntegrationTesting.Backend.Extensions;
using Xunit.Abstractions;
namespace Btms.Analytics.Tests.Fixtures;
diff --git a/Btms.Analytics.Tests/Fixtures/MultiItemDataTestFixture.cs b/Btms.Analytics.Tests/Fixtures/MultiItemDataTestFixture.cs
index 87ce88a2..c22ba19f 100644
--- a/Btms.Analytics.Tests/Fixtures/MultiItemDataTestFixture.cs
+++ b/Btms.Analytics.Tests/Fixtures/MultiItemDataTestFixture.cs
@@ -3,6 +3,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using TestDataGenerator.Scenarios;
+using TestGenerator.IntegrationTesting.Backend.Extensions;
using Xunit.Abstractions;
namespace Btms.Analytics.Tests.Fixtures;
diff --git a/Btms.Analytics.Tests/ImportNotificationsByMaxVersionTests.cs b/Btms.Analytics.Tests/ImportNotificationsByMaxVersionTests.cs
index d7ff84da..c6cd032b 100644
--- a/Btms.Analytics.Tests/ImportNotificationsByMaxVersionTests.cs
+++ b/Btms.Analytics.Tests/ImportNotificationsByMaxVersionTests.cs
@@ -68,7 +68,7 @@ public async Task WhenCalledWithCountry_ReturnsResults()
{
testOutputHelper.WriteLine("Querying for aggregated data");
var result = (await basicSampleDataTestFixture.GetImportNotificationsAggregationService(testOutputHelper)
- .ByMaxVersion(DateTime.Now.NextHour().AddDays(-2), DateTime.Now.NextHour(), country: "AL"));
+ .ByMaxVersion(DateTime.Now.NextHour().AddDays(-2), DateTime.Now.NextHour(), country: "ES"));
testOutputHelper.WriteLine($"{result.Values.Count} aggregated items found");
diff --git a/Btms.Analytics.Tests/MovementsByMaxVersionTests.cs b/Btms.Analytics.Tests/MovementsByMaxVersionTests.cs
index 9f117a60..aec68c84 100644
--- a/Btms.Analytics.Tests/MovementsByMaxVersionTests.cs
+++ b/Btms.Analytics.Tests/MovementsByMaxVersionTests.cs
@@ -1,78 +1,159 @@
-using Btms.Common.Extensions;
+using Btms.Model.Ipaffs;
using FluentAssertions;
+using TestDataGenerator.Scenarios;
+using TestGenerator.IntegrationTesting.Backend;
+using TestGenerator.IntegrationTesting.Backend.Extensions;
+using TestGenerator.IntegrationTesting.Backend.Fixtures;
using Xunit;
using Xunit.Abstractions;
-using Btms.Analytics.Tests.Fixtures;
-using Btms.Model.Ipaffs;
-
namespace Btms.Analytics.Tests;
-[Collection(nameof(BasicSampleDataTestCollection))]
-public class MovementsByMaxVersionTests(
- BasicSampleDataTestFixture basicSampleDataTestFixture,
- ITestOutputHelper testOutputHelper)
+// [Collection(nameof(BasicSampleDataTestCollection))]
+// public class MovementsByMaxVersionTests(
+// BasicSampleDataTestFixture basicSampleDataTestFixture,
+// ITestOutputHelper testOutputHelper)
+public class MovementsByMaxVersionTests(ITestOutputHelper output)
+ : BaseTest(output)
{
- // [Fact]
- // public async Task WhenCalledLastWeek_ReturnExpectedAggregation()
- // {
- // testOutputHelper.WriteLine("Querying for aggregated data");
- // var result = (await basicSampleDataTestFixture.GetMovementsAggregationService(testOutputHelper)
- // .ByStatus(DateTime.Today.WeekAgo(), DateTime.Today.Tomorrow()));
- //
- // testOutputHelper.WriteLine("{0} aggregated items found", result.Values.Count);
- //
- // result.Values.Count.Should().Be(2);
- // result.Values.Keys.Order().Should().Equal("Linked", "Not Linked");
- // }
- //
- // [Fact]
- // public async Task WhenCalledLast48Hours_ReturnExpectedAggregation()
- // {
- // testOutputHelper.WriteLine("Querying for aggregated data");
- // var result = (await basicSampleDataTestFixture.GetMovementsAggregationService(testOutputHelper)
- // .ByStatus(DateTime.Now.NextHour().AddDays(-2), DateTime.Now.NextHour()));
- //
- // testOutputHelper.WriteLine($"{result.Values.Count} aggregated items found");
- //
- // result.Values.Count.Should().Be(2);
- // result.Values.Keys.Order().Should().Equal("Linked", "Not Linked");
- // }
- //
- // [Fact]
- // public async Task WhenCalledWithTimePeriodYieldingNoResults_ReturnEmptyAggregation()
- // {
- // testOutputHelper.WriteLine("Querying for aggregated data");
- // var result = (await basicSampleDataTestFixture.GetMovementsAggregationService(testOutputHelper)
- // .ByStatus(DateTime.MaxValue.AddDays(-1), DateTime.MaxValue));
- //
- // testOutputHelper.WriteLine($"{result.Values.Count} aggregated items found");
- //
- // result.Values.Count.Should().Be(2);
- // result.Values.Keys.Order().Should().Equal("Linked", "Not Linked");
- // }
+
+ [Fact]
+ public async Task WhenCalled_ReturnsResults()
+ {
+ TestOutputHelper.WriteLine("Querying for aggregated data");
+
+ var result = await BackendFixture
+ .BtmsClient
+ .GetAnalyticsDashboard(["movementsByMaxEntryVersion"],
+ dateFrom:DateTime.Today.AddDays(-1),
+ dateTo:DateTime.Today.AddDays(1));
+
+ TestOutputHelper.WriteLine($"{result.StatusCode} status");
+ result.IsSuccessStatusCode.Should().BeTrue(result.StatusCode.ToString());
+
+ var charts = await result.ToJsonDictionary();
+
+ TestOutputHelper.WriteLine($"movementsByMaxEntryVersion keys : {charts["movementsByMaxEntryVersion"].GetKeys()}");
+ TestOutputHelper.WriteLine($"result keys : {charts["movementsByMaxEntryVersion"]["values"]!.GetKeys()}");
+
+ charts["movementsByMaxEntryVersion"]["values"]!
+ .GetKeys()
+ .Length.Should().Be(1);
+
+ var val = charts["movementsByMaxEntryVersion"]["values"]!["1"]!
+ .GetValue()
+ .Should()
+ .Be(1);
+ }
[Fact]
public async Task WhenCalledWithChedType_ReturnsResults()
{
- testOutputHelper.WriteLine("Querying for aggregated data");
- var result = (await basicSampleDataTestFixture.GetMovementsAggregationService(testOutputHelper)
- .ByMaxVersion(DateTime.Now.NextHour().AddDays(-2), DateTime.Now.NextHour(), chedTypes: [ImportNotificationTypeEnum.Cveda]));
+ TestOutputHelper.WriteLine("Querying for aggregated data");
+
+ var result = await BackendFixture
+ .BtmsClient
+ .GetAnalyticsDashboard(["movementsByMaxEntryVersion"],
+ dateFrom:DateTime.Today.AddDays(-1),
+ dateTo:DateTime.Today.AddDays(1),
+ chedTypes: [ImportNotificationTypeEnum.Cvedp]);
+
+ TestOutputHelper.WriteLine($"{result.StatusCode} status");
+ result.IsSuccessStatusCode.Should().BeTrue(result.StatusCode.ToString());
+
+ var charts = await result.ToJsonDictionary();
+
+ TestOutputHelper.WriteLine($"movementsByMaxEntryVersion keys : {charts["movementsByMaxEntryVersion"].GetKeys()}");
+ TestOutputHelper.WriteLine($"result keys : {charts["movementsByMaxEntryVersion"]["values"]!.GetKeys()}");
+
+ charts["movementsByMaxEntryVersion"]["values"]!
+ .GetKeys()
+ .Length.Should().Be(1);
+
+ var val = charts["movementsByMaxEntryVersion"]["values"]!["1"]!
+ .GetValue()
+ .Should()
+ .Be(1);
+ }
+
+ [Fact]
+ public async Task WhenCalledWithWrongChedType_ReturnsResults()
+ {
+ TestOutputHelper.WriteLine("Querying for aggregated data");
- testOutputHelper.WriteLine($"{result.Values.Count} aggregated items found");
+ var result = await BackendFixture
+ .BtmsClient
+ .GetAnalyticsDashboard(["movementsByMaxEntryVersion"],
+ dateFrom:DateTime.Today.AddDays(-1),
+ dateTo:DateTime.Today.AddDays(1),
+ chedTypes: [ImportNotificationTypeEnum.Cveda]);
+
+ TestOutputHelper.WriteLine($"{result.StatusCode} status");
+ result.IsSuccessStatusCode.Should().BeTrue(result.StatusCode.ToString());
+
+ var charts = await result.ToJsonDictionary();
- result.Values.Count.Should().Be(2);
+ TestOutputHelper.WriteLine($"movementsByMaxEntryVersion keys : {charts["movementsByMaxEntryVersion"].GetKeys()}");
+ TestOutputHelper.WriteLine($"result keys : {charts["movementsByMaxEntryVersion"]["values"]!.GetKeys()}");
+
+ charts["movementsByMaxEntryVersion"]["values"]!
+ .GetKeys()
+ .Length.Should().Be(0);
}
[Fact]
public async Task WhenCalledWithCountry_ReturnsResults()
{
- testOutputHelper.WriteLine("Querying for aggregated data");
- var result = (await basicSampleDataTestFixture.GetMovementsAggregationService(testOutputHelper)
- .ByMaxVersion(DateTime.Now.NextHour().AddDays(-2), DateTime.Now.NextHour(), country: "AL"));
+ TestOutputHelper.WriteLine("Querying for aggregated data");
+
+ var result = await BackendFixture
+ .BtmsClient
+ .GetAnalyticsDashboard(["movementsByMaxEntryVersion"],
+ dateFrom:DateTime.Today.AddDays(-1),
+ dateTo:DateTime.Today.AddDays(1),
+ country:"FR");
+
+ TestOutputHelper.WriteLine($"{result.StatusCode} status");
+ result.IsSuccessStatusCode.Should().BeTrue(result.StatusCode.ToString());
+
+ var charts = await result.ToJsonDictionary();
+
+ TestOutputHelper.WriteLine($"movementsByMaxEntryVersion keys : {charts["movementsByMaxEntryVersion"].GetKeys()}");
+ TestOutputHelper.WriteLine($"result keys : {charts["movementsByMaxEntryVersion"]["values"]!.GetKeys()}");
+
+ charts["movementsByMaxEntryVersion"]["values"]!
+ .GetKeys()
+ .Length.Should().Be(1);
+
+ var val = charts["movementsByMaxEntryVersion"]["values"]!["1"]!
+ .GetValue()
+ .Should()
+ .Be(1);
+ }
+
+
+ [Fact]
+ public async Task WhenCalledWithWrongCountry_ReturnsResults()
+ {
+ TestOutputHelper.WriteLine("Querying for aggregated data");
- testOutputHelper.WriteLine($"{result.Values.Count} aggregated items found");
+ var result = await BackendFixture
+ .BtmsClient
+ .GetAnalyticsDashboard(["movementsByMaxEntryVersion"],
+ dateFrom:DateTime.Today.AddDays(-1),
+ dateTo:DateTime.Today.AddDays(1),
+ country:"ES");
+
+ TestOutputHelper.WriteLine($"{result.StatusCode} status");
+ result.IsSuccessStatusCode.Should().BeTrue(result.StatusCode.ToString());
- result.Values.Count.Should().Be(1);
+ var charts = await result.ToJsonDictionary();
+
+ TestOutputHelper.WriteLine($"movementsByMaxEntryVersion keys : {charts["movementsByMaxEntryVersion"].GetKeys()}");
+ TestOutputHelper.WriteLine($"result keys : {charts["movementsByMaxEntryVersion"]["values"]!.GetKeys()}");
+
+ charts["movementsByMaxEntryVersion"]["values"]!
+ .GetKeys()
+ .Length.Should().Be(0);
}
}
\ No newline at end of file
diff --git a/Btms.Analytics/Extensions/MovementExtensions.cs b/Btms.Analytics/Extensions/MovementExtensions.cs
index 4da3dc1b..bd515e6f 100644
--- a/Btms.Analytics/Extensions/MovementExtensions.cs
+++ b/Btms.Analytics/Extensions/MovementExtensions.cs
@@ -12,8 +12,8 @@ public static IQueryable WhereFilteredByCreatedDateAndParams(this IQue
.Where(m => (m.CreatedSource >= from && m.CreatedSource < to)
&& (country == null || m.DispatchCountryCode == country)
&& (chedTypes == null || !chedTypes!.Any() ||
- !m.AlvsDecisionStatus!.Context!.ChedTypes!.Any() ||
- m.AlvsDecisionStatus!.Context!.ChedTypes!.Any(c => chedTypes!.Contains(c))));
+ !m.BtmsStatus.ChedTypes!.Any() ||
+ m.BtmsStatus.ChedTypes!.Any(c => chedTypes!.Contains(c))));
}
@@ -31,7 +31,7 @@ public static IQueryable SelectLinkStatus(this IQueryabl
Movement = m,
CreatedSource = m.CreatedSource!.Value,
Description =
- m.Status.LinkStatus
+ m.BtmsStatus.LinkStatus
// m.Relationships.Notifications.Data.Count > 0 ? "Linked" :
// m.AlvsDecisionStatus!.Context!.AlvsCheckStatus!.AnyMatch ? "Investigate" :
// "Not Linked"
diff --git a/Btms.Analytics/ImportNotificationsAggregationService.cs b/Btms.Analytics/ImportNotificationsAggregationService.cs
index 3110afc1..0dd9ebea 100644
--- a/Btms.Analytics/ImportNotificationsAggregationService.cs
+++ b/Btms.Analytics/ImportNotificationsAggregationService.cs
@@ -120,18 +120,9 @@ public Task ByMaxVersion(DateTime from, DateTime to, Import
var data = context
.Notifications
.Where(n => (n.CreatedSource >= from && n.CreatedSource < to)
- && (country == null || n.PartOne!.Route!.TransitingStates!.Contains(country))
-
+ && (country == null || n.CommoditiesSummary!.CountryOfOrigin! == country)
&& (chedTypes == null || chedTypes!.Length == 0 || n.ImportNotificationType == null || chedTypes!.Contains(n.ImportNotificationType!.Value))
)
-
- // .Select(n => new { Notification = n, IsChedTypeMatch = chedTypes == null || n.ImportNotificationType == null || Array.IndexOf(chedTypes!, n.ImportNotificationType) > -1 })
- // .Where(n => (n.Notification.CreatedSource >= from && n.Notification.CreatedSource < to)
- // && (country == null || n.Notification.PartOne!.Route!.TransitingStates!.Contains(country))
- // && n.IsChedTypeMatch
- // )
- // .Select(n => n.Notification)
-
.GroupBy(n => new { MaxVersion =
n.AuditEntries.Where(a => a.CreatedBy == "Ipaffs").Max(a => a.Version )
})
diff --git a/Btms.Analytics/MovementExceptions.cs b/Btms.Analytics/MovementExceptions.cs
index bca93c76..fdbee4f5 100644
--- a/Btms.Analytics/MovementExceptions.cs
+++ b/Btms.Analytics/MovementExceptions.cs
@@ -18,6 +18,7 @@ public class MovementExceptions(IMongoDbContext context, ILogger logger)
var simplifiedMovementView = context
.Movements
.WhereFilteredByCreatedDateAndParams(from, to, chedTypes, country)
+ .Where(m => !m.BtmsStatus.Linked)
.Select(m => new
{
// TODO - we should think about pre-calculating this stuff and storing it on the movement...
@@ -29,9 +30,8 @@ public class MovementExceptions(IMongoDbContext context, ILogger logger)
MaxEntryVersion = m.ClearanceRequests.Max(c => c.Header!.EntryVersionNumber) ?? 0,
LinkedCheds = m.Relationships.Notifications.Data.Count,
ItemCount = m.Items.Count,
- ChedTypes = m.AlvsDecisionStatus.Context.ChedTypes,
- // HasMatchDecisions = m.AlvsDecisionStatus.Context.AlvsCheckStatus != null && m.AlvsDecisionStatus.Context.AlvsCheckStatus.AnyMatch,
- Status = m.Status,
+ ChedTypes = m.BtmsStatus.ChedTypes,
+ Status = m.BtmsStatus,
DecisionMatched = !m.AlvsDecisionStatus.Decisions
.OrderBy(d => d.Context.AlvsDecisionNumber)
.Reverse()
@@ -51,7 +51,6 @@ public class MovementExceptions(IMongoDbContext context, ILogger logger)
LinkedCheds = m.LinkedCheds,
ItemCount = m.ItemCount,
ChedTypes = m.ChedTypes,
- // HasMatchDecisions = m.HasMatchDecisions,
Status = m.Status,
HasNotificationRelationships = m.HasNotificationRelationships,
Total = m.MaxDecisionNumber + m.MaxEntryVersion + m.LinkedCheds + m.ItemCount,
diff --git a/Btms.Analytics/MovementsAggregationService.cs b/Btms.Analytics/MovementsAggregationService.cs
index a7555b78..d115a015 100644
--- a/Btms.Analytics/MovementsAggregationService.cs
+++ b/Btms.Analytics/MovementsAggregationService.cs
@@ -286,7 +286,7 @@ public Task>
.WhereFilteredByCreatedDateAndParams(from, to, chedTypes, country)
.SelectMany(m => m.AlvsDecisionStatus.Decisions.Select(
d => new {Decision = d, Movement = m } ))
- .SelectMany(d => d.Decision.Checks.Select(c => new { d.Decision, d.Movement, Check = c}))
+ .SelectMany(d => d.Decision.Context.Checks.Select(c => new { d.Decision, d.Movement, Check = c}))
.GroupBy(d => new
{
d.Decision.Context.DecisionStatus,
@@ -306,7 +306,7 @@ public Task>
// Works
var summary = new SingleSeriesDataset() {
Values = mongoQuery
- .GroupBy(q => q.Key.DecisionStatus ?? "TBC")
+ .GroupBy(q => q.Key.DecisionStatus ?? "Investigation Needed")
.ToDictionary(
g => g.Key,
g => g.Sum(k => k.Count)
@@ -320,7 +320,7 @@ public Task>
{
Fields = new Dictionary()
{
- { "Classification", a.Key.DecisionStatus ?? "TBC" },
+ { "Classification", a.Key.DecisionStatus ?? "Investigation Needed" },
{ "CheckCode", a.Key.CheckCode! },
{ "AlvsDecisionCode", a.Key.AlvsDecisionCode! },
{ "BtmsDecisionCode", a.Key.BtmsDecisionCode! }
diff --git a/Btms.Backend.IntegrationTests/AnalyticsTests.cs b/Btms.Backend.IntegrationTests/AnalyticsTests.cs
index 6e9dd337..a81e5592 100644
--- a/Btms.Backend.IntegrationTests/AnalyticsTests.cs
+++ b/Btms.Backend.IntegrationTests/AnalyticsTests.cs
@@ -1,18 +1,7 @@
-using System.Diagnostics.CodeAnalysis;
-using Btms.Common.Extensions;
-using Btms.Model;
-using Btms.SyncJob;
-using Btms.Backend.IntegrationTests.JsonApiClient;
-using FluentAssertions;
-using System.Net;
-using System.Net.Http.Json;
-using System.Text;
-using System.Text.Json;
-using System.Text.Json.Nodes;
-using System.Text.Json.Serialization;
using Btms.Backend.IntegrationTests.Extensions;
using Btms.Backend.IntegrationTests.Helpers;
-using Json.More;
+using FluentAssertions;
+using TestGenerator.IntegrationTesting.Backend.Extensions;
using Xunit;
using Xunit.Abstractions;
@@ -27,7 +16,7 @@ public class AnalyticsTests(ApplicationFactory factory, ITestOutputHelper testOu
public async Task GetIndividualMultiSeriesDatetimeChart()
{
//Act
- var response = await Client.GetAnalyticsDashboard("importNotificationLinkingByCreated");
+ var response = await Client.GetAnalyticsDashboard(["importNotificationLinkingByCreated"]);
// Assert
response.IsSuccessStatusCode.Should().BeTrue(response.StatusCode.ToString());
@@ -44,7 +33,7 @@ public async Task GetIndividualMultiSeriesDatetimeChart()
public async Task GetIndividualMultiSeriesChart()
{
//Act
- var response = await Client.GetAnalyticsDashboard("lastMonthMovementsByItemCount");
+ var response = await Client.GetAnalyticsDashboard(["lastMonthMovementsByItemCount"]);
// Assert
response.IsSuccessStatusCode.Should().BeTrue(response.StatusCode.ToString());
@@ -61,7 +50,7 @@ public async Task GetIndividualMultiSeriesChart()
public async Task GetIndividualSingleSeriesChart()
{
//Act
- var response = await Client.GetAnalyticsDashboard("last7DaysImportNotificationsLinkingStatus");
+ var response = await Client.GetAnalyticsDashboard(["last7DaysImportNotificationsLinkingStatus"]);
// Assert
response.IsSuccessStatusCode.Should().BeTrue(response.StatusCode.ToString());
diff --git a/Btms.Backend.IntegrationTests/BaseApiTests.cs b/Btms.Backend.IntegrationTests/BaseApiTests.cs
index 59bb767d..3e63fd1c 100644
--- a/Btms.Backend.IntegrationTests/BaseApiTests.cs
+++ b/Btms.Backend.IntegrationTests/BaseApiTests.cs
@@ -10,6 +10,7 @@
using FluentAssertions;
using idunno.Authentication.Basic;
using Microsoft.AspNetCore.Mvc.Testing;
+using TestGenerator.IntegrationTesting.Backend.Fixtures;
using Xunit;
using Xunit.Abstractions;
[assembly: CollectionBehavior(DisableTestParallelization = true)]
diff --git a/Btms.Backend.IntegrationTests/Btms.Backend.IntegrationTests.csproj b/Btms.Backend.IntegrationTests/Btms.Backend.IntegrationTests.csproj
index c5f40d92..fb85863f 100644
--- a/Btms.Backend.IntegrationTests/Btms.Backend.IntegrationTests.csproj
+++ b/Btms.Backend.IntegrationTests/Btms.Backend.IntegrationTests.csproj
@@ -19,7 +19,6 @@
-
all
runtime; build; native; contentfiles; analyzers; buildtransitive
@@ -44,6 +43,7 @@
+
diff --git a/Btms.Backend.IntegrationTests/DecisionTests/ChedPDuplicateDecisionTests.cs b/Btms.Backend.IntegrationTests/DecisionTests/ChedPDuplicateDecisionTests.cs
index 4b187bd4..4d88ade8 100644
--- a/Btms.Backend.IntegrationTests/DecisionTests/ChedPDuplicateDecisionTests.cs
+++ b/Btms.Backend.IntegrationTests/DecisionTests/ChedPDuplicateDecisionTests.cs
@@ -1,32 +1,34 @@
-using Btms.Model;
-using FluentAssertions;
using Btms.Backend.IntegrationTests.Helpers;
+using Btms.Model;
using Btms.Types.Alvs;
+using Btms.Types.Ipaffs;
+using FluentAssertions;
using TestDataGenerator.Scenarios.ChedP;
+using TestGenerator.IntegrationTesting.Backend;
+using TestGenerator.IntegrationTesting.Backend.Fixtures;
using Xunit;
using Xunit.Abstractions;
namespace Btms.Backend.IntegrationTests.DecisionTests;
[Trait("Category", "Integration")]
-public class ChedPDuplicateDecisionTests(InMemoryScenarioApplicationFactory factory, ITestOutputHelper testOutputHelper)
- : BaseApiTests(factory, testOutputHelper, "DecisionTests"), IClassFixture>
-{
-
- [Fact(Skip = "We currently import the duplicate alvs decision & store it on the movement")]
- // [Fact]
+public class ChedPDuplicateDecisionTests(ITestOutputHelper output)
+ : BaseTest(output)
+{
+ // [Fact(Skip = "We currently import the duplicate alvs decision & store it on the movement")]
+ [Fact]
public void SimpleChedPScenario_ShouldBeLinkedAndMatchDecision()
{
// Arrange
- var loadedData = factory.LoadedData;
+ var loadedData = LoadedData;
var chedPMovement = (AlvsClearanceRequest)loadedData.Single(d =>
- d is { message: AlvsClearanceRequest })
- .message;
+ d is { Message: AlvsClearanceRequest })
+ .Message;
- var chedPNotification = (Types.Ipaffs.ImportNotification)loadedData.Single(d =>
- d is { message: Types.Ipaffs.ImportNotification })
- .message;
+ var chedPNotification = (ImportNotification)loadedData.Single(d =>
+ d is { Message: ImportNotification })
+ .Message;
// Act
var jsonClientResponse = Client.AsJsonApiClient().GetById(chedPMovement!.Header!.EntryReference!, "api/movements");
diff --git a/Btms.Backend.IntegrationTests/DecisionTests/ChedPSimpleTests.cs b/Btms.Backend.IntegrationTests/DecisionTests/ChedPSimpleTests.cs
index c2c142c6..863fe1f8 100644
--- a/Btms.Backend.IntegrationTests/DecisionTests/ChedPSimpleTests.cs
+++ b/Btms.Backend.IntegrationTests/DecisionTests/ChedPSimpleTests.cs
@@ -1,88 +1,97 @@
using Btms.Backend.IntegrationTests.Helpers;
using Btms.Model;
-using Btms.Model.Ipaffs;
+using Btms.Types.Ipaffs;
using FluentAssertions;
using TestDataGenerator.Scenarios.ChedP;
+using TestGenerator.IntegrationTesting.Backend;
+using TestGenerator.IntegrationTesting.Backend.Extensions;
+using TestGenerator.IntegrationTesting.Backend.Fixtures;
using Xunit;
using Xunit.Abstractions;
-using ImportNotification = Btms.Types.Ipaffs.ImportNotification;
+using ImportNotificationTypeEnum = Btms.Model.Ipaffs.ImportNotificationTypeEnum;
namespace Btms.Backend.IntegrationTests.DecisionTests;
[Trait("Category", "Integration")]
-public class ChedPSimpleTests(
- InMemoryScenarioApplicationFactory factory,
- ITestOutputHelper testOutputHelper)
- : BaseApiTests(factory, testOutputHelper, "DecisionTests"),
- IClassFixture>
+public class ChedPSimpleTests(ITestOutputHelper output)
+ : BaseTest(output)
{
+
[Fact]
- public void ShouldBeLinked()
+ public void ShouldHaveCorrectAlvsDecisions()
{
- // Act
- var movementResource = Client.AsJsonApiClient()
+ // Assert
+ var movement = Client.AsJsonApiClient()
.Get("api/movements")
- .Data
- .Single()
- .Relationships!.Count.Should().Be(1);
+ .GetResourceObjects()
+ .Single();
+
+ movement.AlvsDecisionStatus.Decisions.Count.Should().Be(1);
+
+ movement.AlvsDecisionStatus.Decisions
+ .First()
+ .Context.DecisionMatched
+ .Should().BeTrue();
}
-
+
[Fact]
- public void ShouldHaveCorrectDecisions()
+ public void ShouldHaveCorrectBtmsDecisions()
{
- var chedPNotification = (ImportNotification)factory
- .LoadedData
+ var chedPNotification = (ImportNotification)LoadedData
.Single(d =>
- d is { message: ImportNotification }
+ d is { Message: ImportNotification }
)
- .message;
-
+ .Message;
+
// Assert
var movement = Client.AsJsonApiClient()
.Get("api/movements")
.GetResourceObjects()
.Single();
-
+
movement.Decisions.Count.Should().Be(2);
- movement.AlvsDecisionStatus.Decisions.Count.Should().Be(1);
-
- movement.AlvsDecisionStatus.Decisions
- .First()
- .Context.DecisionMatched
- .Should().BeTrue();
-
+
var decisionWithLinkAndContext = movement.AuditEntries
.Where(a => a is { CreatedBy: "Btms", Status: "Decision" })
.MaxBy(a => a.Version)!;
-
+
decisionWithLinkAndContext.Context!.ImportNotifications
.Should().NotBeNull();
-
+
decisionWithLinkAndContext.Context!.ImportNotifications!
.Select(n => (n.Id, n.Version))
.Should()
- .Equal((chedPNotification.ReferenceNumber!, 1));
+ .Equal([
+ ( chedPNotification.ReferenceNumber!, 1 )
+ ]);
}
[Fact]
public void ShouldHaveCorrectAuditTrail()
{
+
// Assert
var movement = Client.AsJsonApiClient()
.Get("api/movements")
.GetResourceObjects()
.Single();
-
+
movement.AuditEntries
.Select(a => (a.CreatedBy, a.Status, a.Version))
.Should()
- .Equal(("Cds", "Created", 1), ("Btms", "Decision", 1), ("Btms", "Linked", null), ("Btms", "Decision", 2),
- ("Alvs", "Decision", 1));
+ .Equal([
+ ("Cds", "Created", 1),
+ ("Btms", "Decision", 1),
+ ("Btms", "Linked", null),
+ ("Btms", "Decision", 2),
+ ("Alvs", "Decision", 1)
+ ]);
}
[Fact]
public void ShouldHaveDecisionMatched()
{
+
// Assert
var movement = Client.AsJsonApiClient()
.Get("api/movements")
@@ -96,37 +105,64 @@ public void ShouldHaveDecisionMatched()
.Should()
.BeTrue();
}
+
+ [Fact]
+ public void ShouldHaveDecisionStatus()
+ {
+
+ // Assert
+ var movement = Client.AsJsonApiClient()
+ .Get("api/movements")
+ .GetResourceObjects()
+ .Single();
+ movement
+ .AlvsDecisionStatus
+ .DecisionStatus
+ .Should()
+ .Be("Btms Made Same Decision As Alvs");
+ }
+
[Fact]
public void ShouldHaveChedType()
{
+
// Assert
var movement = Client.AsJsonApiClient()
.Get("api/movements")
.GetResourceObjects()
.Single();
-
-
+
movement
- .Status
+ .BtmsStatus
.ChedTypes
.Should()
.Equal(ImportNotificationTypeEnum.Cvedp);
-
- //
- // movement
- // .AlvsDecisionStatus
- // .Context!
- // .ChedTypes
- // .Should()
- // .Equal(ImportNotificationTypeEnum.Cvedp);
}
+
+ [Fact]
+ // [Fact(Skip = "Relationships aren't being deserialised correctly")]
+ // TODO : for some reason whilst jsonClientResponse contains the notification relationship,
+ // but movement from .GetResourceObject(s)(); doesn't!
+ public void ShouldBeLinked()
+ {
+
+ // Assert
+ var movement = Client.AsJsonApiClient()
+ .Get("api/movements")
+ .GetResourceObjects()
+ .Single();
+ movement.BtmsStatus.LinkStatus.Should().Be("Linked");
+ }
+
+ // [Fact]
[Fact(Skip = "Relationships aren't being deserialised correctly")]
// TODO : for some reason whilst jsonClientResponse contains the notification relationship,
// but movement from .GetResourceObject(s)(); doesn't!
public void ShouldHaveNotificationRelationships()
{
+
// Assert
var movement = Client.AsJsonApiClient()
.Get("api/movements")
@@ -137,4 +173,22 @@ public void ShouldHaveNotificationRelationships()
.Relationships.Notifications.Data
.Should().NotBeEmpty();
}
+
+
+ [Fact]
+ public async Task ShouldNotHaveExceptions()
+ {
+ // TestOutputHelper.WriteLine("Querying for aggregated data");
+
+ var result = await BackendFixture
+ .BtmsClient
+ .GetExceptions();
+
+ TestOutputHelper.WriteLine($"{result.StatusCode} status");
+ result.IsSuccessStatusCode.Should().BeTrue(result.StatusCode.ToString());
+
+ (await result.GetString())
+ .Should()
+ .Be("[]");
+ }
}
\ No newline at end of file
diff --git a/Btms.Backend.IntegrationTests/DecisionTests/ChedPUpdatedNotificationTests.cs b/Btms.Backend.IntegrationTests/DecisionTests/ChedPUpdatedNotificationTests.cs
index 0a293843..94b9e726 100644
--- a/Btms.Backend.IntegrationTests/DecisionTests/ChedPUpdatedNotificationTests.cs
+++ b/Btms.Backend.IntegrationTests/DecisionTests/ChedPUpdatedNotificationTests.cs
@@ -1,24 +1,8 @@
-using System.Diagnostics.CodeAnalysis;
-using Btms.Common.Extensions;
-using Btms.Model;
-using Btms.SyncJob;
-using Btms.Backend.IntegrationTests.JsonApiClient;
-using FluentAssertions;
-using System.Net;
-using System.Net.Http.Json;
-using System.Text;
-using System.Text.Json;
-using System.Text.Json.Nodes;
-using System.Text.Json.Serialization;
-using Btms.Backend.IntegrationTests.Extensions;
using Btms.Backend.IntegrationTests.Helpers;
-using Btms.Business.Commands;
-using Btms.Model.Cds;
-using Btms.Model.Ipaffs;
+using Btms.Model;
using Btms.Types.Alvs;
-using TestDataGenerator.Scenarios;
-using Json.More;
-using Microsoft.Extensions.Logging;
+using Btms.Types.Ipaffs;
+using FluentAssertions;
using TestDataGenerator.Scenarios.ChedP;
using Xunit;
using Xunit.Abstractions;
@@ -42,8 +26,8 @@ public void MultipleNotificationVersionScenario_ShouldBeLinkedAndMatchDecision()
.message;
// The scenario has multiple versions of the same notification so we just want one of them.
- var chedPNotification = (Types.Ipaffs.ImportNotification)loadedData.FirstOrDefault(d =>
- d is { generator: MultiStepScenarioGenerator, message: Types.Ipaffs.ImportNotification })
+ var chedPNotification = (ImportNotification)loadedData.FirstOrDefault(d =>
+ d is { generator: MultiStepScenarioGenerator, message: ImportNotification })
.message;
// Act
diff --git a/Btms.Backend.IntegrationTests/DecisionTests/ManyItemTests.cs b/Btms.Backend.IntegrationTests/DecisionTests/NoMatchManyItemTests.cs
similarity index 54%
rename from Btms.Backend.IntegrationTests/DecisionTests/ManyItemTests.cs
rename to Btms.Backend.IntegrationTests/DecisionTests/NoMatchManyItemTests.cs
index 187e02f2..d088cc3d 100644
--- a/Btms.Backend.IntegrationTests/DecisionTests/ManyItemTests.cs
+++ b/Btms.Backend.IntegrationTests/DecisionTests/NoMatchManyItemTests.cs
@@ -1,28 +1,9 @@
-using System.Diagnostics.CodeAnalysis;
-using Btms.Common.Extensions;
+using Btms.Backend.IntegrationTests.Helpers;
using Btms.Model;
-using Btms.SyncJob;
-using Btms.Backend.IntegrationTests.JsonApiClient;
using FluentAssertions;
-using System.Net;
-using System.Net.Http.Json;
-using System.Text;
-using System.Text.Json;
-using System.Text.Json.Nodes;
-using System.Text.Json.Serialization;
-using Btms.Backend.IntegrationTests.Extensions;
-using Btms.Backend.IntegrationTests.Helpers;
-using Btms.Business.Commands;
-using Btms.Model.Cds;
-using Btms.Model.Ipaffs;
-using Btms.Types.Alvs;
using TestDataGenerator.Scenarios;
-using Json.More;
-using Microsoft.Extensions.Logging;
-using TestDataGenerator.Scenarios.ChedP;
using Xunit;
using Xunit.Abstractions;
-using ImportNotification = Btms.Types.Ipaffs.ImportNotification;
namespace Btms.Backend.IntegrationTests.DecisionTests;
@@ -40,7 +21,8 @@ public void ShouldHaveOneChedType()
// .Data
.GetResourceObjects()
.Single()
- .Status.ChedTypes!.Count().Should().Be(1);
+ .BtmsStatus.ChedTypes!.Count()
+ .Should().Be(1);
}
}
\ No newline at end of file
diff --git a/Btms.Backend.IntegrationTests/DecisionTests/NoMatchNoAlvsDecisionTests.cs b/Btms.Backend.IntegrationTests/DecisionTests/NoMatchNoAlvsDecisionTests.cs
new file mode 100644
index 00000000..290defe3
--- /dev/null
+++ b/Btms.Backend.IntegrationTests/DecisionTests/NoMatchNoAlvsDecisionTests.cs
@@ -0,0 +1,63 @@
+using Btms.Model;
+using FluentAssertions;
+using TestDataGenerator.Scenarios;
+using TestGenerator.IntegrationTesting.Backend;
+using TestGenerator.IntegrationTesting.Backend.Fixtures;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Btms.Backend.IntegrationTests.DecisionTests;
+
+[Trait("Category", "Integration")]
+public class NoMatchNoAlvsDecisionTests(ITestOutputHelper output)
+ : BaseTest(output)
+ // IClassFixture>,
+ // IClassFixture>
+{
+
+ [Fact]
+ public void ShouldHaveNotificationRelationships()
+ {
+
+ // Assert
+ var movement = Client.AsJsonApiClient()
+ .Get("api/movements")
+ .GetResourceObjects()
+ .Single();
+
+ movement.BtmsStatus.LinkStatus.Should().Be("Not Linked");
+ }
+
+ [Fact]
+ public void ShouldHaveDecisionStatus()
+ {
+
+ // Assert
+ var movement = Client.AsJsonApiClient()
+ .Get("api/movements")
+ .GetResourceObjects()
+ .Single();
+
+ movement.AlvsDecisionStatus.DecisionStatus.Should().BeNull();
+ }
+
+ [Fact]
+ public void ShouldHaveDecisionMatched()
+ {
+ // var res = Client.AsJsonApiClient()
+ // .Get("api/movements");
+
+ // Assert
+ var movement = Client.AsJsonApiClient()
+ .Get("api/movements")
+ .GetResourceObjects()
+ .Single();
+
+ movement
+ .AlvsDecisionStatus
+ .Context!
+ .DecisionMatched
+ .Should()
+ .BeFalse();
+ }
+}
\ No newline at end of file
diff --git a/Btms.Backend.IntegrationTests/DecisionTests/NoMatchTests.cs b/Btms.Backend.IntegrationTests/DecisionTests/NoMatchTests.cs
new file mode 100644
index 00000000..635df347
--- /dev/null
+++ b/Btms.Backend.IntegrationTests/DecisionTests/NoMatchTests.cs
@@ -0,0 +1,73 @@
+using Btms.Backend.IntegrationTests.Helpers;
+using Btms.Model;
+using FluentAssertions;
+using TestDataGenerator.Scenarios;
+using TestGenerator.IntegrationTesting.Backend;
+using TestGenerator.IntegrationTesting.Backend.Fixtures;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Btms.Backend.IntegrationTests.DecisionTests;
+
+[Trait("Category", "Integration")]
+public class NoMatchTests(ITestOutputHelper output)
+ : BaseTest(output)
+ ////IClassFixture>,
+ ////IClassFixture>
+{
+
+ [Fact]
+ public void ShouldHaveNotificationRelationships()
+ {
+ // Assert
+ var movement = Client.AsJsonApiClient()
+ .Get("api/movements")
+ .GetResourceObjects()
+ .Single();
+
+ movement.BtmsStatus.LinkStatus.Should().Be("Not Linked");
+ }
+
+ [Fact]
+ public void ShouldHaveAlvsDecision()
+ {
+ // Assert
+ var movement = Client.AsJsonApiClient()
+ .Get("api/movements")
+ .GetResourceObjects()
+ .Single();
+
+ movement.AlvsDecisionStatus.Decisions.Count.Should().Be(1);
+ }
+
+ [Fact]
+ public void ShouldHaveDecisionStatus()
+ {
+
+ // Assert
+ var movement = Client.AsJsonApiClient()
+ .Get("api/movements")
+ .GetResourceObjects()
+ .Single();
+
+ movement.AlvsDecisionStatus.DecisionStatus.Should().BeNull();
+ }
+
+ [Fact]
+ public void ShouldHaveDecisionMatchedFalse()
+ {
+
+ // Assert
+ var movement = Client.AsJsonApiClient()
+ .Get("api/movements")
+ .GetResourceObjects()
+ .Single();
+
+ movement
+ .AlvsDecisionStatus
+ .Context!
+ .DecisionMatched
+ .Should()
+ .BeFalse();
+ }
+}
\ No newline at end of file
diff --git a/Btms.Backend.IntegrationTests/Extensions/HttpExtensions.cs b/Btms.Backend.IntegrationTests/Extensions/HttpExtensions.cs
deleted file mode 100644
index 0c4ec614..00000000
--- a/Btms.Backend.IntegrationTests/Extensions/HttpExtensions.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System.Text.Json.Nodes;
-using Btms.Common.Extensions;
-
-namespace Btms.Backend.IntegrationTests.Extensions;
-
-public static class HttpExtensions
-{
- public static async Task> ToJsonDictionary(this HttpResponseMessage? response)
- {
- var responseDictionary = (await response!.Content.ReadAsStringAsync()).ToJsonDictionary();
- ArgumentNullException.ThrowIfNull(responseDictionary);
- return responseDictionary;
- }
-}
\ No newline at end of file
diff --git a/Btms.Backend.IntegrationTests/GmrTests.cs b/Btms.Backend.IntegrationTests/GmrTests.cs
index 4a13f778..7b95fd39 100644
--- a/Btms.Backend.IntegrationTests/GmrTests.cs
+++ b/Btms.Backend.IntegrationTests/GmrTests.cs
@@ -1,12 +1,8 @@
+using Btms.Backend.IntegrationTests.Helpers;
using Btms.Business.Commands;
-using Btms.Backend.IntegrationTests.JsonApiClient;
using FluentAssertions;
-using idunno.Authentication.Basic;
using Microsoft.AspNetCore.Mvc.Testing;
-using System.Net.Http.Headers;
-using System.Text;
-using System.Text.Json;
-using Btms.Backend.IntegrationTests.Helpers;
+using TestGenerator.IntegrationTesting.Backend.Fixtures;
using Xunit;
using Xunit.Abstractions;
diff --git a/Btms.Backend.IntegrationTests/Helpers/ApplicationFactory.cs b/Btms.Backend.IntegrationTests/Helpers/ApplicationFactory.cs
index 48cc3dad..72bbbd0b 100644
--- a/Btms.Backend.IntegrationTests/Helpers/ApplicationFactory.cs
+++ b/Btms.Backend.IntegrationTests/Helpers/ApplicationFactory.cs
@@ -8,6 +8,7 @@
using Microsoft.Extensions.Options;
using MongoDB.Bson.Serialization.Conventions;
using MongoDB.Driver;
+using TestGenerator.IntegrationTesting.Backend.Fixtures;
using Xunit.Abstractions;
namespace Btms.Backend.IntegrationTests.Helpers;
diff --git a/Btms.Backend.IntegrationTests/Helpers/InMemoryScenarioApplicationFactory.cs b/Btms.Backend.IntegrationTests/Helpers/InMemoryScenarioApplicationFactory.cs
index 6cdab976..f43d77d8 100644
--- a/Btms.Backend.IntegrationTests/Helpers/InMemoryScenarioApplicationFactory.cs
+++ b/Btms.Backend.IntegrationTests/Helpers/InMemoryScenarioApplicationFactory.cs
@@ -23,6 +23,7 @@
using TestDataGenerator.Config;
using TestDataGenerator.Extensions;
using TestDataGenerator.Scenarios;
+using TestGenerator.IntegrationTesting.Backend.Fixtures;
using Xunit.Abstractions;
namespace Btms.Backend.IntegrationTests.Helpers;
@@ -70,7 +71,7 @@ protected override void ConfigureWebHost(IWebHostBuilder builder)
ConventionRegistry.Register("CamelCase", camelCaseConvention, _ => true);
var dbName = string.IsNullOrEmpty(databaseName) ? Random.Shared.Next().ToString() : databaseName;
- var db = client.GetDatabase($"Btms_MongoDb_{dbName}_Test");
+ var db = client.GetDatabase($"Btms_{dbName}");
// TODO : Use our ILoggerFactory
mongoDbContext = new MongoDbContext(db, new SerilogLoggerFactory());
diff --git a/Btms.Backend.IntegrationTests/Helpers/TestDataGeneratorFactory.cs b/Btms.Backend.IntegrationTests/Helpers/TestDataGeneratorFactory.cs
index b62960da..a23a0444 100644
--- a/Btms.Backend.IntegrationTests/Helpers/TestDataGeneratorFactory.cs
+++ b/Btms.Backend.IntegrationTests/Helpers/TestDataGeneratorFactory.cs
@@ -25,6 +25,7 @@
using SlimMessageBus;
using SlimMessageBus.Host;
using TestDataGenerator.Scenarios;
+using TestGenerator.IntegrationTesting.Backend.Fixtures;
using Xunit.Sdk;
namespace Btms.Backend.IntegrationTests.Helpers;
diff --git a/Btms.Backend.IntegrationTests/LinkingTests.cs b/Btms.Backend.IntegrationTests/LinkingTests.cs
index ebb7e945..deccbdfb 100644
--- a/Btms.Backend.IntegrationTests/LinkingTests.cs
+++ b/Btms.Backend.IntegrationTests/LinkingTests.cs
@@ -1,6 +1,5 @@
using Btms.Backend.IntegrationTests.Helpers;
using Btms.Business.Commands;
-using Btms.Backend.IntegrationTests.JsonApiClient;
using FluentAssertions;
using Xunit;
using Xunit.Abstractions;
diff --git a/Btms.Backend.IntegrationTests/SmokeTests.cs b/Btms.Backend.IntegrationTests/SmokeTests.cs
index d44d43ec..569b7785 100644
--- a/Btms.Backend.IntegrationTests/SmokeTests.cs
+++ b/Btms.Backend.IntegrationTests/SmokeTests.cs
@@ -1,14 +1,13 @@
-using Btms.Business.Commands;
-using Btms.Model;
-using Btms.SyncJob;
-using Btms.Backend.IntegrationTests.JsonApiClient;
-using FluentAssertions;
using System.Net;
using System.Net.Http.Json;
-using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using Btms.Backend.IntegrationTests.Helpers;
+using Btms.Business.Commands;
+using Btms.Model;
+using Btms.SyncJob;
+using FluentAssertions;
+using TestGenerator.IntegrationTesting.Backend;
using Xunit;
using Xunit.Abstractions;
diff --git a/Btms.Business.Tests/Services/Linking/LinkingServiceTests.cs b/Btms.Business.Tests/Services/Linking/LinkingServiceTests.cs
index 043553a0..e7d55b00 100644
--- a/Btms.Business.Tests/Services/Linking/LinkingServiceTests.cs
+++ b/Btms.Business.Tests/Services/Linking/LinkingServiceTests.cs
@@ -297,7 +297,7 @@ private MovementLinkContext CreateMovementContext(Movement? movement, List
{
@@ -280,7 +277,7 @@ private AlvsDecision FindBtmsPairAndUpdate(CdsClearanceRequest clearanceRequest)
// This is an initial implementation
// we want to be smarter about how we 'pair' things, considering the same version of the import notifications
- // can a BTMS decision be 'paired' to multiple ALVS decisions?
+ // Q : can a BTMS decision be 'paired' to multiple ALVS decisions? Probably not...
var btmsDecision = _movement.Decisions?
.Where(d =>
d.Header!.EntryVersionNumber == _movement.EntryVersionNumber)
@@ -301,22 +298,22 @@ private AlvsDecision FindBtmsPairAndUpdate(CdsClearanceRequest clearanceRequest)
AlvsDecisionNumber = clearanceRequest!.Header!.DecisionNumber!.Value,
BtmsDecisionNumber = btmsDecision == null ? 0 : btmsDecision!.Header!.DecisionNumber!.Value,
EntryVersionNumber = clearanceRequest!.Header!.EntryVersionNumber!.Value,
- Paired = btmsDecision != null
- },
- Checks = clearanceRequest
- .Items!.SelectMany(i => i.Checks!.Select(c => new { Item = i, Check = c }))
- .Select(ic =>
- {
- var decisionCode = btmsChecks == null ? null : btmsChecks!.GetValueOrDefault((ic.Item.ItemNumber!.Value, ic.Check.CheckCode!), null);
- return new ItemCheck()
+ Paired = btmsDecision != null,
+ Checks = clearanceRequest
+ .Items!.SelectMany(i => i.Checks!.Select(c => new { Item = i, Check = c }))
+ .Select(ic =>
{
- ItemNumber = ic.Item!.ItemNumber!.Value,
- CheckCode = ic.Check!.CheckCode!,
- AlvsDecisionCode = ic.Check!.DecisionCode!,
- BtmsDecisionCode = decisionCode
- };
- })
- .ToList()
+ var decisionCode = btmsChecks == null ? null : btmsChecks!.GetValueOrDefault((ic.Item.ItemNumber!.Value, ic.Check.CheckCode!), null);
+ return new ItemCheck()
+ {
+ ItemNumber = ic.Item!.ItemNumber!.Value,
+ CheckCode = ic.Check!.CheckCode!,
+ AlvsDecisionCode = ic.Check!.DecisionCode!,
+ BtmsDecisionCode = decisionCode
+ };
+ })
+ .ToList()
+ }
};
if (btmsDecision != null)
@@ -340,34 +337,36 @@ private void GuardNullMovement()
private void CompareDecisions(AlvsDecision alvsDecision, CdsClearanceRequest btmsDecision)
{
GuardNullMovement();
+ var alvsChecks = alvsDecision.Context.Checks;
+ var btmsChecks = alvsDecision.Context.Checks;
alvsDecision.Context.AlvsCheckStatus = new StatusChecker()
{
- AllMatch = alvsDecision.Checks.All(c => !c.AlvsDecisionCode.StartsWith('X')),
- AnyMatch = alvsDecision.Checks.Any(c => !c.AlvsDecisionCode.StartsWith('X')),
- AllNoMatch = alvsDecision.Checks.All(c => c.AlvsDecisionCode.StartsWith('X')),
- AnyNoMatch = alvsDecision.Checks.Any(c => c.AlvsDecisionCode.StartsWith('X')),
- AllRefuse = alvsDecision.Checks.All(c => c.AlvsDecisionCode.StartsWith('N')),
- AnyRefuse = alvsDecision.Checks.Any(c => c.AlvsDecisionCode.StartsWith('N')),
- AllRelease = alvsDecision.Checks.All(c => c.AlvsDecisionCode.StartsWith('C')),
- AnyRelease = alvsDecision.Checks.Any(c => c.AlvsDecisionCode.StartsWith('C')),
- AllHold = alvsDecision.Checks.All(c => c.AlvsDecisionCode.StartsWith('H')),
- AnyHold = alvsDecision.Checks.Any(c => c.AlvsDecisionCode.StartsWith('H'))
+ AllMatch = alvsChecks.All(c => !c.AlvsDecisionCode.StartsWith('X')),
+ AnyMatch = alvsChecks.Any(c => !c.AlvsDecisionCode.StartsWith('X')),
+ AllNoMatch = alvsChecks.All(c => c.AlvsDecisionCode.StartsWith('X')),
+ AnyNoMatch = alvsChecks.Any(c => c.AlvsDecisionCode.StartsWith('X')),
+ AllRefuse = alvsChecks.All(c => c.AlvsDecisionCode.StartsWith('N')),
+ AnyRefuse = alvsChecks.Any(c => c.AlvsDecisionCode.StartsWith('N')),
+ AllRelease = alvsChecks.All(c => c.AlvsDecisionCode.StartsWith('C')),
+ AnyRelease = alvsChecks.Any(c => c.AlvsDecisionCode.StartsWith('C')),
+ AllHold = alvsChecks.All(c => c.AlvsDecisionCode.StartsWith('H')),
+ AnyHold = alvsChecks.Any(c => c.AlvsDecisionCode.StartsWith('H'))
};
alvsDecision.Context.BtmsCheckStatus = new StatusChecker()
{
- AllMatch = alvsDecision.Checks.All(c => c.BtmsDecisionCode.HasValue() && c.BtmsDecisionCode.StartsWith('X')),
- AnyMatch = alvsDecision.Checks.Any(c => !(c.BtmsDecisionCode.HasValue() && c.BtmsDecisionCode.StartsWith('X'))),
- AllNoMatch = alvsDecision.Checks.All(c => c.BtmsDecisionCode.HasValue() && c.BtmsDecisionCode.StartsWith('X')),
- AnyNoMatch = alvsDecision.Checks.Any(c => c.BtmsDecisionCode.HasValue() && c.BtmsDecisionCode.StartsWith('X')),
- AllRefuse = alvsDecision.Checks.All(c => c.BtmsDecisionCode.HasValue() && c.BtmsDecisionCode.StartsWith('N')),
- AnyRefuse = alvsDecision.Checks.Any(c => c.BtmsDecisionCode.HasValue() && c.BtmsDecisionCode.StartsWith('N')),
- AllRelease = alvsDecision.Checks.All(c => c.BtmsDecisionCode.HasValue() && c.BtmsDecisionCode.StartsWith('C')),
- AnyRelease = alvsDecision.Checks.Any(c => c.BtmsDecisionCode.HasValue() && c.BtmsDecisionCode.StartsWith('C')),
- AllHold = alvsDecision.Checks.All(c => c.BtmsDecisionCode.HasValue() && c.BtmsDecisionCode.StartsWith('H')),
- AnyHold = alvsDecision.Checks.Any(c => c.BtmsDecisionCode.HasValue() && c.BtmsDecisionCode.StartsWith('H'))
+ AllMatch = btmsChecks.All(c => c.BtmsDecisionCode.HasValue() && c.BtmsDecisionCode.StartsWith('X')),
+ AnyMatch = btmsChecks.Any(c => !(c.BtmsDecisionCode.HasValue() && c.BtmsDecisionCode.StartsWith('X'))),
+ AllNoMatch = btmsChecks.All(c => c.BtmsDecisionCode.HasValue() && c.BtmsDecisionCode.StartsWith('X')),
+ AnyNoMatch = btmsChecks.Any(c => c.BtmsDecisionCode.HasValue() && c.BtmsDecisionCode.StartsWith('X')),
+ AllRefuse = btmsChecks.All(c => c.BtmsDecisionCode.HasValue() && c.BtmsDecisionCode.StartsWith('N')),
+ AnyRefuse = btmsChecks.Any(c => c.BtmsDecisionCode.HasValue() && c.BtmsDecisionCode.StartsWith('N')),
+ AllRelease = btmsChecks.All(c => c.BtmsDecisionCode.HasValue() && c.BtmsDecisionCode.StartsWith('C')),
+ AnyRelease = btmsChecks.Any(c => c.BtmsDecisionCode.HasValue() && c.BtmsDecisionCode.StartsWith('C')),
+ AllHold = btmsChecks.All(c => c.BtmsDecisionCode.HasValue() && c.BtmsDecisionCode.StartsWith('H')),
+ AnyHold = btmsChecks.Any(c => c.BtmsDecisionCode.HasValue() && c.BtmsDecisionCode.StartsWith('H'))
};
var pairStatus = "Investigation Needed";
@@ -378,7 +377,7 @@ private void CompareDecisions(AlvsDecision alvsDecision, CdsClearanceRequest btm
}
else
{
- var checksMatch = alvsDecision.Checks.All(c => c.AlvsDecisionCode == c.BtmsDecisionCode);
+ var checksMatch = alvsChecks.All(c => c.AlvsDecisionCode == c.BtmsDecisionCode);
if (checksMatch)
{
diff --git a/Btms.Business/Extensions/MovementExtensions.cs b/Btms.Business/Extensions/MovementExtensions.cs
index c1e2e9e1..380cc858 100644
--- a/Btms.Business/Extensions/MovementExtensions.cs
+++ b/Btms.Business/Extensions/MovementExtensions.cs
@@ -1,4 +1,5 @@
using Btms.Model;
+using Btms.Model.Cds;
namespace Btms.Business.Extensions;
@@ -6,18 +7,20 @@ public static class MovementExtensions
{
public static void AddLinkStatus(this Movement movement)
{
- var linkStatus = "Not Linked";
-
+ var linkStatus = MovementStatus.NotLinkedStatus;
+ var linked = false;
+
if (movement.Relationships.Notifications.Data.Count > 0)
{
- linkStatus = "Linked";
+ linkStatus = MovementStatus.LinkedStatus;
+ linked = true;
}
else if (movement.AlvsDecisionStatus?.Context?.AlvsCheckStatus?.AnyMatch ?? false)
{
- linkStatus = "Investigate";
+ linkStatus = MovementStatus.InvestigateStatus;
}
- movement.Status.LinkStatus = linkStatus;
+ movement.BtmsStatus.LinkStatus = linkStatus;
+ movement.BtmsStatus.Linked = linked;
}
-
}
\ No newline at end of file
diff --git a/Btms.Common.Testing/Btms.Common.Testing.csproj b/Btms.Common.Testing/Btms.Common.Testing.csproj
new file mode 100644
index 00000000..52ec16e6
--- /dev/null
+++ b/Btms.Common.Testing/Btms.Common.Testing.csproj
@@ -0,0 +1,25 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Btms.Consumers/DecisionsConsumer.cs b/Btms.Consumers/DecisionsConsumer.cs
index 4ea3e9b6..225b7e71 100644
--- a/Btms.Consumers/DecisionsConsumer.cs
+++ b/Btms.Consumers/DecisionsConsumer.cs
@@ -8,7 +8,7 @@
namespace Btms.Consumers;
-public class DecisionsConsumer(IMongoDbContext dbContext, MovementBuilder movementBuilder)
+public class DecisionsConsumer(IMongoDbContext dbContext, MovementBuilder existingMovementBuilder)
: IConsumer, IConsumerWithContext
{
public async Task OnHandle(Decision message)
@@ -21,15 +21,15 @@ public async Task OnHandle(Decision message)
var auditId = Context.Headers["messageId"].ToString();
var notificationContext = Context.Headers.GetValueOrDefault("notifications", null) as List;
- movementBuilder = movementBuilder
+ existingMovementBuilder = existingMovementBuilder
.From(existingMovement!)
.MergeDecision(auditId!, internalClearanceRequest, notificationContext);
// .Build();
// var merged = existingMovement.MergeDecision(auditId!, internalClearanceRequest);
- if (movementBuilder.HasChanges)
+ if (existingMovementBuilder.HasChanges)
{
- await dbContext.Movements.Update(movementBuilder.Build(), existingMovement._Etag);
+ await dbContext.Movements.Update(existingMovementBuilder.Build(), existingMovement._Etag);
}
}
}
diff --git a/Btms.Model/Cds/AlvsDecision.cs b/Btms.Model/Cds/AlvsDecision.cs
index 2c9ba1d5..73b68c02 100644
--- a/Btms.Model/Cds/AlvsDecision.cs
+++ b/Btms.Model/Cds/AlvsDecision.cs
@@ -93,28 +93,44 @@ public class StatusChecker
public class MovementStatus
{
+ public const string NotLinkedStatus = "Not Linked";
+ public const string LinkedStatus = "Linked";
+ public const string InvestigateStatus = "Investigate";
+
public static MovementStatus Default()
{
- return new MovementStatus() { ChedTypes = [] };
+ return new MovementStatus()
+ {
+ ChedTypes = [],
+ Linked = false,
+ LinkStatus = NotLinkedStatus
+ };
}
[Attr]
[System.ComponentModel.Description("")]
[MongoDB.Bson.Serialization.Attributes.BsonRepresentation(MongoDB.Bson.BsonType.String)]
- public required ImportNotificationTypeEnum[]? ChedTypes { get; set; }
+ public required ImportNotificationTypeEnum[] ChedTypes { get; set; }
[Attr]
[System.ComponentModel.Description("")]
- public string LinkStatus { get; set; } = "Not Linked";
+ public required bool Linked { get; set; }
+
+ [Attr]
+ [System.ComponentModel.Description("")]
+ public required string LinkStatus { get; set; }
+
+ // [Attr]
+ // [System.ComponentModel.Description("")]
+ // public required string[] CountriesOfOrigin { get; set; }
}
+
public partial class DecisionContext : IAuditContext //
{
- //TODO : Remove in favour of MovementStatus
[Attr]
[System.ComponentModel.Description("")]
- [MongoDB.Bson.Serialization.Attributes.BsonRepresentation(MongoDB.Bson.BsonType.String)]
- public ImportNotificationTypeEnum[]? ChedTypes { get; set; }
+ public List Checks { get; set; } = new List();
[Attr]
[System.ComponentModel.Description("")]
@@ -166,11 +182,6 @@ public partial class AlvsDecisionStatus //
[Attr]
[System.ComponentModel.Description("")]
public DecisionContext Context { get; set; } = new DecisionContext();
-
- // TODO - should we put the checks into context, and so into audit log?
- [Attr]
- [System.ComponentModel.Description("")]
- public List Checks { get; set; } = new List();
}
public partial class AlvsDecision //
@@ -182,12 +193,6 @@ public partial class AlvsDecision //
[Attr]
[System.ComponentModel.Description("")]
public required DecisionContext Context { get; set; }
-
- // TODO - should we put the checks into context, and so into audit log?
- [Attr]
- [System.ComponentModel.Description("")]
- public required List Checks { get; set; }
-
}
diff --git a/Btms.Model/Ipaffs/ImportNotification.cs b/Btms.Model/Ipaffs/ImportNotification.cs
index c9ac2a02..f84111b1 100644
--- a/Btms.Model/Ipaffs/ImportNotification.cs
+++ b/Btms.Model/Ipaffs/ImportNotification.cs
@@ -28,7 +28,7 @@ public virtual string? Id
get => ReferenceNumber!;
set => ReferenceNumber = value;
}
-
+
[ChangeSetIgnore]
// ReSharper disable once InconsistentNaming - want to use Mongo DB convention to indicate none core schema properties
public string _Etag { get; set; } = default!;
diff --git a/Btms.Model/Movement.cs b/Btms.Model/Movement.cs
index f2896b54..005e41f0 100644
--- a/Btms.Model/Movement.cs
+++ b/Btms.Model/Movement.cs
@@ -24,7 +24,7 @@ public class Movement : IMongoIdentifiable, IDataEntity, IAuditable
[ChangeSetIgnore] //TODO : should we ignore this or not?
[Attr]
- public required MovementStatus Status { get; set; }
+ public required MovementStatus BtmsStatus { get; set; }
// This field is used by the jsonapi-consumer to control the correct casing in the type field
[ChangeSetIgnore]
diff --git a/Btms.Types.Ipaffs.Mapping.V1/ImportNotificationMapper.g.cs b/Btms.Types.Ipaffs.Mapping.V1/ImportNotificationMapper.g.cs
index a12b8300..3880d259 100644
--- a/Btms.Types.Ipaffs.Mapping.V1/ImportNotificationMapper.g.cs
+++ b/Btms.Types.Ipaffs.Mapping.V1/ImportNotificationMapper.g.cs
@@ -10,6 +10,8 @@
#nullable enable
+using Btms.Model.Ipaffs;
+
namespace Btms.Types.Ipaffs.Mapping;
public static class ImportNotificationMapper
@@ -22,6 +24,7 @@ public static Btms.Model.Ipaffs.ImportNotification Map(Btms.Types.Ipaffs.ImportN
}
var to = new Btms.Model.Ipaffs.ImportNotification();
+
to.IpaffsId = from?.IpaffsId;
to.Etag = from?.Etag;
to.ExternalReferences = from?.ExternalReferences?.Select(x => ExternalReferenceMapper.Map(x)).ToArray();
diff --git a/BtmsBackend.sln b/BtmsBackend.sln
index 2d35b648..ca99202c 100644
--- a/BtmsBackend.sln
+++ b/BtmsBackend.sln
@@ -67,6 +67,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Btms.Analytics.Tests", "Btm
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Btms.Metrics", "Btms.Metrics\Btms.Metrics.csproj", "{34731E9B-CF72-44B4-B73F-6921FD21A679}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestGenerator.IntegrationTesting.Backend", "TestGenerator.IntegrationTesting.Backend\TestGenerator.IntegrationTesting.Backend.csproj", "{A0212474-827F-4AE5-A086-F63B3F0C4DA0}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -189,6 +191,10 @@ Global
{34731E9B-CF72-44B4-B73F-6921FD21A679}.Debug|Any CPU.Build.0 = Debug|Any CPU
{34731E9B-CF72-44B4-B73F-6921FD21A679}.Release|Any CPU.ActiveCfg = Release|Any CPU
{34731E9B-CF72-44B4-B73F-6921FD21A679}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A0212474-827F-4AE5-A086-F63B3F0C4DA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A0212474-827F-4AE5-A086-F63B3F0C4DA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A0212474-827F-4AE5-A086-F63B3F0C4DA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A0212474-827F-4AE5-A086-F63B3F0C4DA0}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/TestDataGenerator/ClearanceRequestBuilder.cs b/TestDataGenerator/ClearanceRequestBuilder.cs
index fc6e4954..fa586c37 100644
--- a/TestDataGenerator/ClearanceRequestBuilder.cs
+++ b/TestDataGenerator/ClearanceRequestBuilder.cs
@@ -79,7 +79,7 @@ public ClearanceRequestBuilder WithCreationDate(DateTime entryDate, bool rand
return Do(x => x.ServiceHeader!.ServiceCallTimestamp = entry);
}
- public ClearanceRequestBuilder WithEntryVersionNumber(int version)
+ public ClearanceRequestBuilder WithEntryVersionNumber(int version = 1)
{
return Do(x =>
{
@@ -198,6 +198,7 @@ protected override ClearanceRequestBuilder Validate()
return Do(cr =>
{
cr.Header!.EntryReference.AssertHasValue("Clearance Request EntryReference missing");
+ cr.Header!.EntryVersionNumber.AssertHasValue("Clearance Request EntryVersionNumber missing");
cr.Header!.DeclarationUcr.AssertHasValue("Clearance Request DeclarationUcr missing");
cr.Header!.MasterUcr.AssertHasValue("Clearance Request MasterUcr missing");
// cr.Header!.ArrivalDateTime.AssertHasValue("Clearance Request ArrivalDateTime missing");
diff --git a/TestDataGenerator/DecisionBuilder.cs b/TestDataGenerator/DecisionBuilder.cs
index ed571fd9..e7879455 100644
--- a/TestDataGenerator/DecisionBuilder.cs
+++ b/TestDataGenerator/DecisionBuilder.cs
@@ -31,8 +31,11 @@ public static DecisionBuilder FromFile(string file)
public DecisionBuilder WithReferenceNumber(string chedReference)
{
var id = MatchIdentifier.FromNotification(chedReference);
- //
- // base.Id = id.AsCdsEntryReference();
+ return WithReferenceNumber(id);
+ }
+
+ public DecisionBuilder WithReferenceNumber(MatchIdentifier id)
+ {
return Do(x =>
{
x.Header!.EntryReference = id.AsCdsEntryReference();
diff --git a/TestDataGenerator/Helpers/BuilderHelpers.cs b/TestDataGenerator/Helpers/BuilderHelpers.cs
new file mode 100644
index 00000000..156a9124
--- /dev/null
+++ b/TestDataGenerator/Helpers/BuilderHelpers.cs
@@ -0,0 +1,34 @@
+using Btms.Types.Ipaffs;
+
+namespace TestDataGenerator.Helpers;
+
+public static class BuilderHelpers
+{
+ private static readonly string fullFolder =
+ $"{Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory)}/Scenarios/Samples";
+
+ internal static ClearanceRequestBuilder GetClearanceRequestBuilder(string file, string fileExtension = ".json")
+ {
+ // return BuilderHelpers.GetClearanceRequestBuilder(file, fileExtension);
+ var fullPath = $"{fullFolder}/{file}{fileExtension}";
+ var builder = new ClearanceRequestBuilder(fullPath);
+
+ return builder;
+ }
+
+ internal static DecisionBuilder GetDecisionBuilder(string file, string fileExtension = ".json")
+ {
+ var fullPath = $"{fullFolder}/{file}{fileExtension}";
+ var builder = new DecisionBuilder(fullPath);
+
+ return builder;
+ }
+
+ internal static ImportNotificationBuilder GetNotificationBuilder(string file, string fileExtension = ".json")
+ {
+ var fullPath = $"{fullFolder}/{file}{fileExtension}";
+ var builder = ImportNotificationBuilder.FromFile(fullPath);
+
+ return builder;
+ }
+}
\ No newline at end of file
diff --git a/TestDataGenerator/ScenarioGenerator.cs b/TestDataGenerator/ScenarioGenerator.cs
index 8627e8c0..ac9f4b48 100644
--- a/TestDataGenerator/ScenarioGenerator.cs
+++ b/TestDataGenerator/ScenarioGenerator.cs
@@ -4,6 +4,7 @@
using Btms.Model;
using Btms.Types.Alvs;
using Btms.Types.Ipaffs;
+using TestDataGenerator.Helpers;
using TestDataGenerator.Scenarios;
using Decision = Btms.Types.Alvs.Decision;
@@ -16,27 +17,29 @@ public abstract class ScenarioGenerator
public abstract GeneratorResult Generate(int scenario, int item, DateTime entryDate, ScenarioConfig config);
+ //TODO : remove these Get methods...
internal ImportNotificationBuilder GetNotificationBuilder(string file, string fileExtension = ".json")
{
var fullPath = $"{_fullFolder}/{file}{fileExtension}";
var builder = ImportNotificationBuilder.FromFile(fullPath);
-
+
return builder;
}
internal ClearanceRequestBuilder GetClearanceRequestBuilder(string file, string fileExtension = ".json")
{
- var fullPath = $"{_fullFolder}/{file}{fileExtension}";
- var builder = new ClearanceRequestBuilder(fullPath);
-
- return builder;
+ return BuilderHelpers.GetClearanceRequestBuilder(file, fileExtension);
+ // var fullPath = $"{_fullFolder}/{file}{fileExtension}";
+ // var builder = new ClearanceRequestBuilder(fullPath);
+ //
+ // return builder;
}
-
+
internal DecisionBuilder GetDecisionBuilder(string file, string fileExtension = ".json")
{
var fullPath = $"{_fullFolder}/{file}{fileExtension}";
var builder = new DecisionBuilder(fullPath);
-
+
return builder;
}
diff --git a/TestDataGenerator/Scenarios/CRNoMatch.cs b/TestDataGenerator/Scenarios/CRNoMatch.cs
new file mode 100644
index 00000000..db0f13b4
--- /dev/null
+++ b/TestDataGenerator/Scenarios/CRNoMatch.cs
@@ -0,0 +1,135 @@
+using Btms.Common.Extensions;
+using Btms.Model;
+using Btms.Types.Alvs;
+using Btms.Types.Ipaffs;
+using Microsoft.Extensions.Logging;
+using TestDataGenerator.Helpers;
+using Decision = Btms.Types.Alvs.Decision;
+
+namespace TestDataGenerator.Scenarios;
+
+public static class NoMatchExtensions
+{
+ public static ClearanceRequestBuilder SimpleClearanceRequest(int scenario, int item, DateTime entryDate, ScenarioConfig config)
+ {
+ return BuilderHelpers.GetClearanceRequestBuilder("cr-one-item")
+ .WithCreationDate(entryDate)
+ .WithArrivalDateTimeOffset(DateTime.Today.ToDate(), DateTime.Now.ToTime())
+ .WithReferenceNumberOneToOne(DataHelpers.GenerateReferenceNumber(ImportNotificationTypeEnum.Cveda, scenario,
+ entryDate, item))
+ .WithEntryVersionNumber();
+ }
+
+ public static ClearanceRequestBuilder WithTunaItem(this ClearanceRequestBuilder builder)
+ {
+ return builder
+ .WithItemNoChecks("N853", "16041421", "Tuna ROW CHEDP", 900);
+ }
+
+ public static MatchIdentifier DocumentReferenceFromFirstDoc(this AlvsClearanceRequest clearanceRequest)
+ {
+ return MatchIdentifier.FromCds(clearanceRequest
+ .Items?
+ .First()
+ .Documents?
+ .First()
+ .DocumentReference!);
+ }
+
+ public static DecisionBuilder GetDecisionBuilder(
+ this AlvsClearanceRequest clearanceRequest)
+ {
+ var reference = clearanceRequest
+ .DocumentReferenceFromFirstDoc();
+
+ // TODO - check with Matt what a sensible checkCode, decision & other fields we need to
+ // implement a 'real world' test here
+ var checkCode = "H2019";
+ var decisionCode = "H01";
+
+ return BuilderHelpers.GetDecisionBuilder("decision-one-item")
+ .WithCreationDate(clearanceRequest.ServiceHeader!.ServiceCallTimestamp!.Value.AddHours(1), false)
+ .WithReferenceNumber(reference)
+ .WithEntryVersionNumber(1)
+ .WithDecisionVersionNumber()
+ .WithItemAndCheck(1, checkCode, decisionCode);
+
+ }
+}
+
+public class CrNoMatchSingleItemWithDecisionScenarioGenerator(ILogger logger) : ScenarioGenerator
+{
+ public override GeneratorResult Generate(int scenario, int item, DateTime entryDate, ScenarioConfig config)
+ {
+ var clearanceRequest = NoMatchExtensions
+ .SimpleClearanceRequest(scenario, item, entryDate, config)
+ .WithTunaItem()
+ .WithDispatchCountryCode("FR")
+ .ValidateAndBuild();
+
+ logger.LogInformation("Created {EntryReference}", clearanceRequest.Header!.EntryReference);
+
+ var alvsDecision = clearanceRequest
+ .GetDecisionBuilder()
+ .ValidateAndBuild();
+
+ logger.LogInformation("Created {EntryReference}", alvsDecision.Header!.EntryReference);
+
+ return new GeneratorResult([clearanceRequest, alvsDecision]);
+ }
+}
+public class CrNoMatchNoChecksScenarioGenerator(ILogger logger) : ScenarioGenerator
+{
+ public override GeneratorResult Generate(int scenario, int item, DateTime entryDate, ScenarioConfig config)
+ {
+ var clearanceRequest = NoMatchExtensions
+ .SimpleClearanceRequest(scenario, item, entryDate, config)
+ .WithTunaItem()
+ .ValidateAndBuild();
+
+ logger.LogInformation("Created {EntryReference}", clearanceRequest.Header!.EntryReference);
+
+ return new GeneratorResult([clearanceRequest]);
+ }
+}
+
+public class CrNoMatchNoDecisionScenarioGenerator(ILogger logger) : ScenarioGenerator
+{
+ public override GeneratorResult Generate(int scenario, int item, DateTime entryDate, ScenarioConfig config)
+ {
+ var reference = DataHelpers.GenerateReferenceNumber(ImportNotificationTypeEnum.Cveda, scenario, entryDate, item);
+
+ var clearanceRequest = NoMatchExtensions
+ .SimpleClearanceRequest(scenario, item, entryDate, config)
+ .WithReferenceNumberOneToOne(reference)
+ .WithRandomItems(10, 100)
+ .ValidateAndBuild();
+
+ logger.LogInformation("Created {EntryReference}", clearanceRequest.Header!.EntryReference);
+
+ return new GeneratorResult([clearanceRequest]);
+ }
+}
+
+public class CrNoMatchScenarioGenerator(ILogger logger) : ScenarioGenerator
+{
+ public override GeneratorResult Generate(int scenario, int item, DateTime entryDate, ScenarioConfig config)
+ {
+ // var reference = DataHelpers.GenerateReferenceNumber(ImportNotificationTypeEnum.Cveda, scenario, entryDate, item);
+
+ var clearanceRequest = NoMatchExtensions
+ .SimpleClearanceRequest(scenario, item, entryDate, config)
+ .WithRandomItems(10, 100)
+ .ValidateAndBuild();
+
+ logger.LogInformation("Created {EntryReference}", clearanceRequest.Header!.EntryReference);
+
+ var alvsDecision = clearanceRequest
+ .GetDecisionBuilder()
+ .ValidateAndBuild();
+
+ logger.LogInformation("Created {EntryReference}", alvsDecision.Header!.EntryReference);
+
+ return new GeneratorResult([clearanceRequest, alvsDecision]);
+ }
+}
\ No newline at end of file
diff --git a/TestDataGenerator/Scenarios/CRNoMatchNoChecksScenarioGenerator.cs b/TestDataGenerator/Scenarios/CRNoMatchNoChecksScenarioGenerator.cs
deleted file mode 100644
index 65ca5f17..00000000
--- a/TestDataGenerator/Scenarios/CRNoMatchNoChecksScenarioGenerator.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using Btms.Common.Extensions;
-using Btms.Types.Ipaffs;
-using Microsoft.Extensions.Logging;
-using TestDataGenerator.Helpers;
-
-namespace TestDataGenerator.Scenarios;
-
-public class CrNoMatchNoChecksScenarioGenerator(ILogger logger) : ScenarioGenerator
-{
- public override GeneratorResult Generate(int scenario, int item, DateTime entryDate, ScenarioConfig config)
- {
- var clearanceRequest = GetClearanceRequestBuilder("cr-one-item")
- .WithCreationDate(entryDate)
- .WithArrivalDateTimeOffset(DateTime.Today.ToDate(), DateTime.Now.ToTime())
- .WithReferenceNumberOneToOne(DataHelpers.GenerateReferenceNumber(ImportNotificationTypeEnum.Cveda, scenario, entryDate, item))
- .WithItemNoChecks("N853", "16041421", "Tuna ROW CHEDP", 900)
- .ValidateAndBuild();
-
- logger.LogInformation("Created {EntryReference}", clearanceRequest.Header!.EntryReference);
-
- return new GeneratorResult([clearanceRequest]);
- }
-}
\ No newline at end of file
diff --git a/TestDataGenerator/Scenarios/CRNoMatchNoDecisionScenarioGenerator.cs b/TestDataGenerator/Scenarios/CRNoMatchNoDecisionScenarioGenerator.cs
deleted file mode 100644
index df459305..00000000
--- a/TestDataGenerator/Scenarios/CRNoMatchNoDecisionScenarioGenerator.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using Btms.Common.Extensions;
-using Btms.Types.Ipaffs;
-using Microsoft.Extensions.Logging;
-using TestDataGenerator.Helpers;
-
-namespace TestDataGenerator.Scenarios;
-
-public class CrNoMatchNoDecisionScenarioGenerator(ILogger logger) : ScenarioGenerator
-{
- public override GeneratorResult Generate(int scenario, int item, DateTime entryDate, ScenarioConfig config)
- {
- var reference = DataHelpers.GenerateReferenceNumber(ImportNotificationTypeEnum.Cveda, scenario, entryDate, item);
-
- var clearanceRequest = GetClearanceRequestBuilder("cr-one-item")
- .WithCreationDate(entryDate)
- .WithArrivalDateTimeOffset(DateTime.Today.ToDate(), DateTime.Now.ToTime())
- .WithReferenceNumberOneToOne(reference)
- .WithRandomItems(10, 100)
- .ValidateAndBuild();
-
- logger.LogInformation("Created {EntryReference}", clearanceRequest.Header!.EntryReference);
-
- return new GeneratorResult([clearanceRequest]);
- }
-}
\ No newline at end of file
diff --git a/TestDataGenerator/Scenarios/CRNoMatchScenarioGenerator.cs b/TestDataGenerator/Scenarios/CRNoMatchScenarioGenerator.cs
deleted file mode 100644
index b0f113e7..00000000
--- a/TestDataGenerator/Scenarios/CRNoMatchScenarioGenerator.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using Btms.Common.Extensions;
-using Btms.Types.Ipaffs;
-using Microsoft.Extensions.Logging;
-using TestDataGenerator.Helpers;
-
-namespace TestDataGenerator.Scenarios;
-
-public class CrNoMatchScenarioGenerator(ILogger logger) : ScenarioGenerator
-{
- public override GeneratorResult Generate(int scenario, int item, DateTime entryDate, ScenarioConfig config)
- {
- var reference = DataHelpers.GenerateReferenceNumber(ImportNotificationTypeEnum.Cveda, scenario, entryDate, item);
-
- var clearanceRequest = GetClearanceRequestBuilder("cr-one-item")
- .WithCreationDate(entryDate)
- .WithArrivalDateTimeOffset(DateTime.Today.ToDate(), DateTime.Now.ToTime())
- .WithReferenceNumberOneToOne(reference)
- .WithRandomItems(10, 100)
- .ValidateAndBuild();
-
- logger.LogInformation("Created {EntryReference}", clearanceRequest.Header!.EntryReference);
-
- // TODO - check with Matt what a sensible checkCode, decision & other fields we need to
- // implement a 'real world' test here
- var checkCode = "H2019";
- var decisionCode = "H01";
-
- var alvsDecision = GetDecisionBuilder("decision-one-item")
- .WithCreationDate(clearanceRequest.ServiceHeader!.ServiceCallTimestamp!.Value.AddHours(1), false)
- .WithReferenceNumber(reference)
- .WithEntryVersionNumber(1)
- .WithDecisionVersionNumber()
- .WithItemAndCheck(1, checkCode, decisionCode)
- .ValidateAndBuild();
-
- logger.LogInformation("Created {EntryReference}", alvsDecision.Header!.EntryReference);
-
- return new GeneratorResult([clearanceRequest, alvsDecision]);
- }
-}
\ No newline at end of file
diff --git a/TestDataGenerator/Scenarios/ChedAManyCommoditiesScenarioGenerator.cs b/TestDataGenerator/Scenarios/ChedAManyCommoditiesScenarioGenerator.cs
index b32d99f6..ef8fa22a 100644
--- a/TestDataGenerator/Scenarios/ChedAManyCommoditiesScenarioGenerator.cs
+++ b/TestDataGenerator/Scenarios/ChedAManyCommoditiesScenarioGenerator.cs
@@ -24,6 +24,7 @@ public override GeneratorResult Generate(int scenario, int item, DateTime entryD
.WithCreationDate(entryDate)
.WithArrivalDateTimeOffset(notification.PartOne!.ArrivalDate, notification.PartOne!.ArrivalTime)
.WithReferenceNumberOneToOne(notification.ReferenceNumber!)
+ .WithEntryVersionNumber()
.ValidateAndBuild();
logger.LogInformation("Created {EntryReference}", clearanceRequest.Header!.EntryReference);
diff --git a/TestDataGenerator/Scenarios/ChedASimpleMatchScenarioGenerator.cs b/TestDataGenerator/Scenarios/ChedASimpleMatchScenarioGenerator.cs
index dafb0bcf..e876e00a 100644
--- a/TestDataGenerator/Scenarios/ChedASimpleMatchScenarioGenerator.cs
+++ b/TestDataGenerator/Scenarios/ChedASimpleMatchScenarioGenerator.cs
@@ -22,6 +22,7 @@ public override GeneratorResult Generate(int scenario, int item, DateTime entryD
.WithArrivalDateTimeOffset(notification.PartOne!.ArrivalDate, notification.PartOne!.ArrivalTime)
.WithReferenceNumberOneToOne(notification.ReferenceNumber!)
.WithDispatchCountryCode(notification.PartOne!.Route!.TransitingStates!.FirstOrDefault())
+ .WithEntryVersionNumber()
.ValidateAndBuild();
logger.LogInformation("Created {EntryReference}", clearanceRequest.Header!.EntryReference);
diff --git a/TestGenerator.IntegrationTesting.Backend/BaseTest.cs b/TestGenerator.IntegrationTesting.Backend/BaseTest.cs
new file mode 100644
index 00000000..9829350e
--- /dev/null
+++ b/TestGenerator.IntegrationTesting.Backend/BaseTest.cs
@@ -0,0 +1,45 @@
+using Microsoft.Extensions.DependencyInjection;
+using TestDataGenerator;
+using TestGenerator.IntegrationTesting.Backend.Fixtures;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace TestGenerator.IntegrationTesting.Backend;
+
+public abstract class BaseTest // : IClassFixture, IClassFixture
+ where T : ScenarioGenerator
+{
+ protected readonly BtmsClient Client;
+ protected readonly TestGeneratorFixture TestGeneratorFixture;
+ protected readonly BackendFixture BackendFixture;
+ // internal readonly BackendGeneratorFixture BackendGeneratorFixture;
+ protected readonly ITestOutputHelper TestOutputHelper;
+
+ protected readonly List LoadedData;
+ protected BaseTest(
+ ITestOutputHelper testOutputHelper
+ )
+ {
+ TestOutputHelper = testOutputHelper;
+
+ TestGeneratorFixture = new TestGeneratorFixture();
+ BackendFixture = new BackendFixture(testOutputHelper, GetType().Name);
+
+ // BackendFixture.TestOutputHelper = testOutputHelper;
+ // BackendFixture.DatabaseName = GetType().Name;
+ // BackendFixture.Init(GetType().Name);
+
+ Client = BackendFixture.BtmsClient;
+
+ var data = TestGeneratorFixture.GenerateTestData();
+ LoadedData = BackendFixture
+ .LoadTestData(data)
+ .GetAwaiter()
+ .GetResult();
+ }
+
+ protected async Task ClearDb()
+ {
+ await Client.ClearDb();
+ }
+}
\ No newline at end of file
diff --git a/Btms.Backend.IntegrationTests/Helpers/BtmsClient.cs b/TestGenerator.IntegrationTesting.Backend/BtmsClient.cs
similarity index 81%
rename from Btms.Backend.IntegrationTests/Helpers/BtmsClient.cs
rename to TestGenerator.IntegrationTesting.Backend/BtmsClient.cs
index 8b32487f..3def5d2b 100644
--- a/Btms.Backend.IntegrationTests/Helpers/BtmsClient.cs
+++ b/TestGenerator.IntegrationTesting.Backend/BtmsClient.cs
@@ -5,13 +5,14 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using Btms.Business.Commands;
+using Btms.Model.Ipaffs;
using Btms.SyncJob;
using Elastic.CommonSchema;
using FluentAssertions;
using idunno.Authentication.Basic;
using Xunit;
-namespace Btms.Backend.IntegrationTests.Helpers;
+namespace TestGenerator.IntegrationTesting.Backend.Fixtures;
public class BtmsClient
{
@@ -111,11 +112,29 @@ public Task GetJob(string? jobId)
return (response, Path.GetFileName(response.Headers.Location?.ToString()));
}
- public Task GetAnalyticsDashboard(string charts)
+
+ public Task GetExceptions()
{
return client.GetAsync(
- $"/analytics/dashboard?chartsToRender={charts}");
+ $"/analytics/exceptions");
}
+
+ public Task GetAnalyticsDashboard(string[] charts,
+ ImportNotificationTypeEnum[]? chedTypes = null,
+ string? country = null,
+ DateTime? dateFrom = null,
+ DateTime? dateTo = null)
+ {
+ var chartsFilter = String.Join("&chartsToRender=", charts);
+ var dateFromFilter = dateFrom.HasValue ? $"&dateFrom={dateFrom.Value:yyyy-MM-dd}" : "";
+ var dateToFilter = dateTo.HasValue ? $"&dateTo={dateTo.Value:yyyy-MM-dd}" : "";
+ var countryFilter = country != null ? $"&coo={country}" : "";
+ var chedTypeFilter = chedTypes != null ? "&chedType=" + String.Join("&chedType=", chedTypes) : "";
+
+ return client.GetAsync(
+ $"/analytics/dashboard?chartsToRender={chartsFilter}{dateFromFilter}{dateToFilter}{countryFilter}{chedTypeFilter}");
+ }
+
private async Task PostCommand(T command, string uri)
{
var jsonData = JsonSerializer.Serialize(command);
diff --git a/TestGenerator.IntegrationTesting.Backend/Extensions/HttpExtensions.cs b/TestGenerator.IntegrationTesting.Backend/Extensions/HttpExtensions.cs
new file mode 100644
index 00000000..d2f50314
--- /dev/null
+++ b/TestGenerator.IntegrationTesting.Backend/Extensions/HttpExtensions.cs
@@ -0,0 +1,21 @@
+using System.Text.Json.Nodes;
+using Btms.Common.Extensions;
+
+namespace TestGenerator.IntegrationTesting.Backend.Extensions;
+
+public static class HttpExtensions
+{
+ public static async Task GetString(this HttpResponseMessage? response)
+ {
+ var s = await response!.Content.ReadAsStringAsync();
+ return s;
+ }
+
+ public static async Task> ToJsonDictionary(this HttpResponseMessage? response)
+ {
+ var s = await response!.GetString();
+ var responseDictionary = s.ToJsonDictionary();
+ ArgumentNullException.ThrowIfNull(responseDictionary);
+ return responseDictionary;
+ }
+}
\ No newline at end of file
diff --git a/TestGenerator.IntegrationTesting.Backend/Extensions/JsonExtensions.cs b/TestGenerator.IntegrationTesting.Backend/Extensions/JsonExtensions.cs
new file mode 100644
index 00000000..3f615098
--- /dev/null
+++ b/TestGenerator.IntegrationTesting.Backend/Extensions/JsonExtensions.cs
@@ -0,0 +1,14 @@
+using System.Text.Json.Nodes;
+using FluentAssertions;
+
+namespace TestGenerator.IntegrationTesting.Backend.Extensions;
+
+public static class JsonExtensions
+{
+ public static string[] GetKeys(this JsonNode node)
+ {
+ return node.AsObject()
+ .Select(x => x.As>().Key)
+ .ToArray();
+ }
+}
\ No newline at end of file
diff --git a/Btms.Analytics.Tests/Helpers/ITestOutputHelperExtensions.cs b/TestGenerator.IntegrationTesting.Backend/Extensions/TestOutputHelperExtensions.cs
similarity index 57%
rename from Btms.Analytics.Tests/Helpers/ITestOutputHelperExtensions.cs
rename to TestGenerator.IntegrationTesting.Backend/Extensions/TestOutputHelperExtensions.cs
index e495e103..7d75400b 100644
--- a/Btms.Analytics.Tests/Helpers/ITestOutputHelperExtensions.cs
+++ b/TestGenerator.IntegrationTesting.Backend/Extensions/TestOutputHelperExtensions.cs
@@ -2,15 +2,22 @@
using Microsoft.Extensions.Logging;
using Xunit.Abstractions;
-namespace Btms.Analytics.Tests.Helpers;
+namespace TestGenerator.IntegrationTesting.Backend.Extensions;
-public static class ITestOutputHelperExtensions
+public static class TestOutputHelperExtensions
{
- public static ILogger GetLogger(this ITestOutputHelper helper)
+ public static ILoggerFactory GetLoggerFactory(this ITestOutputHelper helper)
{
var loggerProvider = new XUnitLoggerProvider(helper, new XUnitLoggerOptions());
var factory = new LoggerFactory([loggerProvider]);
+ return factory;
+ }
+
+ public static ILogger GetLogger(this ITestOutputHelper helper)
+ {
+ var factory = helper.GetLoggerFactory();
+
return factory.CreateLogger();
}
}
\ No newline at end of file
diff --git a/TestGenerator.IntegrationTesting.Backend/Fixtures/BackendFixture.cs b/TestGenerator.IntegrationTesting.Backend/Fixtures/BackendFixture.cs
new file mode 100644
index 00000000..e5cbca80
--- /dev/null
+++ b/TestGenerator.IntegrationTesting.Backend/Fixtures/BackendFixture.cs
@@ -0,0 +1,128 @@
+using Btms.Backend.Data;
+using Btms.Backend.Data.Mongo;
+using Btms.BlobService;
+using Btms.Common.Extensions;
+using Btms.Consumers.Extensions;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Mvc.Testing;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+using Microsoft.Extensions.Options;
+using MongoDB.Bson.Serialization.Conventions;
+using MongoDB.Driver;
+using Serilog.Extensions.Logging;
+using TestDataGenerator;
+using Xunit.Abstractions;
+
+using TestGenerator.IntegrationTesting.Backend.Extensions;
+
+namespace TestGenerator.IntegrationTesting.Backend.Fixtures;
+
+public class BackendFixture
+{
+ private readonly IMongoDbContext _mongoDbContext;
+ public readonly BtmsClient BtmsClient;
+
+ private BackendFactory WebApp { get; set; }
+
+ public readonly ITestOutputHelper TestOutputHelper;
+
+ public BackendFixture(ITestOutputHelper testOutputHelper, string databaseName)
+ {
+ TestOutputHelper = testOutputHelper;
+
+ WebApp = new BackendFactory(databaseName, testOutputHelper);
+ (_mongoDbContext, BtmsClient) = WebApp.Start();
+
+ }
+
+ public async Task> LoadTestData(List testData)
+ {
+ await BtmsClient.ClearDb();
+
+ var logger = TestOutputHelper.GetLogger();
+
+ await WebApp.Services.PushToConsumers(logger, testData.Select(d => d.Message));
+
+ return testData;
+ }
+}
+public class BackendFactory(string databaseName, ITestOutputHelper testOutputHelper ) : WebApplicationFactory
+{
+ private IMongoDbContext? mongoDbContext;
+
+ protected override void ConfigureWebHost(IWebHostBuilder builder)
+ {
+ // Any integration test overrides could be added here
+ // And we don't want to load the backend ini file
+ var configurationValues = new Dictionary
+ {
+ { "DisableLoadIniFile", "true" },
+ { "BlobServiceOptions:CachePath", "Scenarios/Samples" },
+ { "BlobServiceOptions:CacheReadEnabled", "true" },
+ { "AuthKeyStore:Credentials:IntTest", "Password" }
+ };
+
+ var configuration = new ConfigurationBuilder()
+ .AddInMemoryCollection(configurationValues!)
+ .Build();
+
+ builder
+ .UseConfiguration(configuration)
+ .ConfigureServices(services =>
+ {
+ var mongoDatabaseDescriptor = services.SingleOrDefault(d => d.ServiceType == typeof(IMongoDatabase))!;
+ services.Remove(mongoDatabaseDescriptor);
+
+ var blobOptionsValidatorDescriptor = services.SingleOrDefault(d => d.ServiceType == typeof(IValidateOptions))!;
+ services.Remove(blobOptionsValidatorDescriptor);
+
+ services.AddSingleton(sp =>
+ {
+ var options = sp.GetService>()!;
+ var settings = MongoClientSettings.FromConnectionString(options.Value.DatabaseUri);
+ var client = new MongoClient(settings);
+
+ // _mongoDbContext = client
+ var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() };
+ // convention must be registered before initialising collection
+ ConventionRegistry.Register("CamelCase", camelCaseConvention, _ => true);
+
+ var dbName = string.IsNullOrEmpty(databaseName) ?
+ Random.Shared.Next().ToString() :
+ databaseName
+ .Replace("ScenarioGenerator", "");
+
+ var db = client.GetDatabase($"btms-{dbName}");
+
+ mongoDbContext = new MongoDbContext(db, testOutputHelper.GetLoggerFactory());
+ return db;
+ });
+
+ if (testOutputHelper.HasValue())
+ {
+ services.AddLogging(lb => lb.AddXUnit(testOutputHelper));
+ }
+ });
+
+ builder.UseEnvironment("Development");
+ }
+
+ public (IMongoDbContext, BtmsClient) Start()
+ {
+ var builder = Host.CreateDefaultBuilder();
+
+ var host = base
+ .CreateHost(builder);
+
+ // Creating the client causes the
+ var client = this.CreateClient(new WebApplicationFactoryClientOptions { AllowAutoRedirect = false });
+ var btmsClient = new BtmsClient(client);
+
+ return (mongoDbContext!, btmsClient);
+ }
+
+}
\ No newline at end of file
diff --git a/TestGenerator.IntegrationTesting.Backend/Fixtures/BackendGeneratorFixture.cs b/TestGenerator.IntegrationTesting.Backend/Fixtures/BackendGeneratorFixture.cs
new file mode 100644
index 00000000..7c56337c
--- /dev/null
+++ b/TestGenerator.IntegrationTesting.Backend/Fixtures/BackendGeneratorFixture.cs
@@ -0,0 +1,13 @@
+using TestDataGenerator;
+
+namespace TestGenerator.IntegrationTesting.Backend.Fixtures;
+
+public class BackendGeneratorFixture(
+ TestGeneratorFixture testGenerator,
+ BackendFixture backend
+)
+ where T : ScenarioGenerator
+{
+ public TestGeneratorFixture TestGenerator { get; set; } = testGenerator;
+ public BackendFixture Backend { get; set; } = backend;
+}
\ No newline at end of file
diff --git a/TestGenerator.IntegrationTesting.Backend/Fixtures/IIntegrationTestsFixture.cs b/TestGenerator.IntegrationTesting.Backend/Fixtures/IIntegrationTestsFixture.cs
new file mode 100644
index 00000000..e228c62c
--- /dev/null
+++ b/TestGenerator.IntegrationTesting.Backend/Fixtures/IIntegrationTestsFixture.cs
@@ -0,0 +1,14 @@
+using Btms.Backend.Data;
+using Microsoft.AspNetCore.Mvc.Testing;
+using Xunit.Abstractions;
+
+namespace TestGenerator.IntegrationTesting.Backend.Fixtures;
+
+// public interface IIntegrationTestsFixture
+// {
+// ITestOutputHelper TestOutputHelper { get; set; }
+// string DatabaseName { get; set; }
+//
+// BtmsClient CreateBtmsClient(WebApplicationFactoryClientOptions options);
+// IMongoDbContext GetDbContext();
+// }
\ No newline at end of file
diff --git a/TestGenerator.IntegrationTesting.Backend/Fixtures/TestGeneratorFixture.cs b/TestGenerator.IntegrationTesting.Backend/Fixtures/TestGeneratorFixture.cs
new file mode 100644
index 00000000..d268bffc
--- /dev/null
+++ b/TestGenerator.IntegrationTesting.Backend/Fixtures/TestGeneratorFixture.cs
@@ -0,0 +1,65 @@
+using Btms.Backend.Data;
+using Btms.Backend.Data.Mongo;
+using Btms.BlobService;
+using Btms.Common.Extensions;
+using Btms.Consumers.Extensions;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Mvc.Testing;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Abstractions;
+using Microsoft.Extensions.Options;
+using MongoDB.Bson.Serialization.Conventions;
+using MongoDB.Driver;
+using Serilog.Extensions.Logging;
+using TestDataGenerator;
+using TestDataGenerator.Extensions;
+using TestDataGenerator.Scenarios;
+using Xunit.Abstractions;
+
+namespace TestGenerator.IntegrationTesting.Backend.Fixtures;
+
+public class TestGeneratorFixture
+{
+
+
+ private IHost TestGeneratorApp { get; set; }
+
+ public TestGeneratorFixture()
+ {
+ // Generate test data
+
+ var generatorBuilder = new HostBuilder();
+ generatorBuilder
+ .ConfigureTestDataGenerator("Scenarios/Samples");
+
+ TestGeneratorApp = generatorBuilder.Build();
+ }
+
+ public List GenerateTestData() where T : ScenarioGenerator
+ {
+ // TODO: Need a logger
+ var logger = NullLogger.Instance;
+
+ var scenarioConfig =
+ TestGeneratorApp.Services.CreateScenarioConfig(1, 1, arrivalDateRange: 0);
+
+ var generatorResults = scenarioConfig
+ .Generate(logger, 0);
+
+ return generatorResults
+ .SelectMany(r => r.Select(m => new { Result = r, Message = m}))
+ .Select(rm => new GeneratedResult()
+ {
+ Count = 1, DateOffset = 1, Scenario = 1,
+ GeneratorResult = rm.Result,
+ Message = rm.Message
+ })
+ // .Select(r =>
+ //
+ // )
+ .ToList();
+ }
+}
\ No newline at end of file
diff --git a/TestGenerator.IntegrationTesting.Backend/GeneratedResult.cs b/TestGenerator.IntegrationTesting.Backend/GeneratedResult.cs
new file mode 100644
index 00000000..5ec13be6
--- /dev/null
+++ b/TestGenerator.IntegrationTesting.Backend/GeneratedResult.cs
@@ -0,0 +1,12 @@
+using TestDataGenerator;
+
+namespace TestGenerator.IntegrationTesting.Backend;
+
+public class GeneratedResult
+{
+ public required ScenarioGenerator.GeneratorResult GeneratorResult { get; set; }
+ public required int Scenario { get; set; }
+ public required int DateOffset { get; set; }
+ public required int Count { get; set; }
+ public required object Message { get; set; }
+}
\ No newline at end of file
diff --git a/Btms.Backend.IntegrationTests/JsonApiClient/JsonApiClient.cs b/TestGenerator.IntegrationTesting.Backend/JsonApiClient/JsonApiClient.cs
similarity index 98%
rename from Btms.Backend.IntegrationTests/JsonApiClient/JsonApiClient.cs
rename to TestGenerator.IntegrationTesting.Backend/JsonApiClient/JsonApiClient.cs
index b7b7ad01..d352f16c 100644
--- a/Btms.Backend.IntegrationTests/JsonApiClient/JsonApiClient.cs
+++ b/TestGenerator.IntegrationTesting.Backend/JsonApiClient/JsonApiClient.cs
@@ -6,7 +6,7 @@
using System.Text.Json;
using JsonSerializer = System.Text.Json.JsonSerializer;
-namespace Btms.Backend.IntegrationTests.JsonApiClient;
+namespace TestGenerator.IntegrationTesting.Backend.JsonApiClient;
public class JsonApiClient(HttpClient client)
{
diff --git a/Btms.Backend.IntegrationTests/JsonApiClient/JsonApiDocument.cs b/TestGenerator.IntegrationTesting.Backend/JsonApiClient/JsonApiDocument.cs
similarity index 93%
rename from Btms.Backend.IntegrationTests/JsonApiClient/JsonApiDocument.cs
rename to TestGenerator.IntegrationTesting.Backend/JsonApiClient/JsonApiDocument.cs
index 86bb0add..dd0d5ba5 100644
--- a/Btms.Backend.IntegrationTests/JsonApiClient/JsonApiDocument.cs
+++ b/TestGenerator.IntegrationTesting.Backend/JsonApiClient/JsonApiDocument.cs
@@ -3,7 +3,7 @@
using JsonApiDotNetCore.Serialization.JsonConverters;
using JsonApiDotNetCore.Serialization.Objects;
-namespace Btms.Backend.IntegrationTests.JsonApiClient;
+namespace TestGenerator.IntegrationTesting.Backend.JsonApiClient;
public abstract class JsonApiDocument
{
diff --git a/Btms.Backend.IntegrationTests/JsonApiClient/ManyItemsJsonApiDocument.cs b/TestGenerator.IntegrationTesting.Backend/JsonApiClient/ManyItemsJsonApiDocument.cs
similarity index 85%
rename from Btms.Backend.IntegrationTests/JsonApiClient/ManyItemsJsonApiDocument.cs
rename to TestGenerator.IntegrationTesting.Backend/JsonApiClient/ManyItemsJsonApiDocument.cs
index ae0b101d..c88e15a5 100644
--- a/Btms.Backend.IntegrationTests/JsonApiClient/ManyItemsJsonApiDocument.cs
+++ b/TestGenerator.IntegrationTesting.Backend/JsonApiClient/ManyItemsJsonApiDocument.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
using JsonApiDotNetCore.Serialization.Objects;
-namespace Btms.Backend.IntegrationTests.JsonApiClient;
+namespace TestGenerator.IntegrationTesting.Backend.JsonApiClient;
public class ManyItemsJsonApiDocument : JsonApiDocument>
{
diff --git a/Btms.Backend.IntegrationTests/JsonApiClient/Response.cs b/TestGenerator.IntegrationTesting.Backend/JsonApiClient/Response.cs
similarity index 82%
rename from Btms.Backend.IntegrationTests/JsonApiClient/Response.cs
rename to TestGenerator.IntegrationTesting.Backend/JsonApiClient/Response.cs
index 1f628754..52431683 100644
--- a/Btms.Backend.IntegrationTests/JsonApiClient/Response.cs
+++ b/TestGenerator.IntegrationTesting.Backend/JsonApiClient/Response.cs
@@ -1,7 +1,7 @@
using System.Net;
using JsonApiSerializer.JsonApi;
-namespace Btms.Backend.IntegrationTests.JsonApiClient;
+namespace TestGenerator.IntegrationTesting.Backend.JsonApiClient;
public class Response
{
diff --git a/Btms.Backend.IntegrationTests/JsonApiClient/SingleItemJsonApiDocument.cs b/TestGenerator.IntegrationTesting.Backend/JsonApiClient/SingleItemJsonApiDocument.cs
similarity index 83%
rename from Btms.Backend.IntegrationTests/JsonApiClient/SingleItemJsonApiDocument.cs
rename to TestGenerator.IntegrationTesting.Backend/JsonApiClient/SingleItemJsonApiDocument.cs
index 5be7c475..652f616c 100644
--- a/Btms.Backend.IntegrationTests/JsonApiClient/SingleItemJsonApiDocument.cs
+++ b/TestGenerator.IntegrationTesting.Backend/JsonApiClient/SingleItemJsonApiDocument.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
using JsonApiDotNetCore.Serialization.Objects;
-namespace Btms.Backend.IntegrationTests.JsonApiClient;
+namespace TestGenerator.IntegrationTesting.Backend.JsonApiClient;
public class SingleItemJsonApiDocument : JsonApiDocument
{
diff --git a/Btms.Backend.IntegrationTests/SyncJobResponse.cs b/TestGenerator.IntegrationTesting.Backend/SyncJobResponse.cs
similarity index 91%
rename from Btms.Backend.IntegrationTests/SyncJobResponse.cs
rename to TestGenerator.IntegrationTesting.Backend/SyncJobResponse.cs
index bcd17568..41f52cf1 100644
--- a/Btms.Backend.IntegrationTests/SyncJobResponse.cs
+++ b/TestGenerator.IntegrationTesting.Backend/SyncJobResponse.cs
@@ -1,6 +1,6 @@
using Btms.SyncJob;
-namespace Btms.Backend.IntegrationTests;
+namespace TestGenerator.IntegrationTesting.Backend;
public class SyncJobResponse
{
diff --git a/TestGenerator.IntegrationTesting.Backend/TestGenerator.IntegrationTesting.Backend.csproj b/TestGenerator.IntegrationTesting.Backend/TestGenerator.IntegrationTesting.Backend.csproj
new file mode 100644
index 00000000..3eed8c9f
--- /dev/null
+++ b/TestGenerator.IntegrationTesting.Backend/TestGenerator.IntegrationTesting.Backend.csproj
@@ -0,0 +1,27 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+ ..\..\..\..\..\..\..\usr\local\share\dotnet\shared\Microsoft.AspNetCore.App\8.0.6\Microsoft.AspNetCore.Hosting.Abstractions.dll
+
+
+
+
+
+
+
+
+