From 937dbbfe6cd70cf5901a86d951bc9bda1733bf7a Mon Sep 17 00:00:00 2001 From: Stuart Ferguson Date: Sat, 7 Oct 2023 05:27:18 +0100 Subject: [PATCH 01/12] Adding Integration Tests --- .github/workflows/createrelease.yml | 4 + .github/workflows/nightlybuild.yml | 5 +- .github/workflows/pullrequest.yml | 10 +- .../ReportingManager.cs | 4 +- .../ControllerTestsBase.cs | 61 ++ .../CustomWebApplicationFactory.cs | 40 ++ .../DatabaseHelper.cs | 148 +++++ .../DimensionControllerTests.cs | 117 ++++ ...EstateReportingAPI.IntegrationTests.csproj | 39 ++ .../Extensions.cs | 53 ++ .../FactSettlementsControllerTests.cs | 59 ++ .../FactTransactionsControllerTests.cs | 603 ++++++++++++++++++ EstateReportingAPI.sln | 7 + .../Bootstrapper/RepositoryRegistry.cs | 8 +- ...{Dimensions.cs => DimensionsController.cs} | 0 EstateReportingAPI/Startup.cs | 20 +- 16 files changed, 1166 insertions(+), 12 deletions(-) create mode 100644 EstateReportingAPI.IntegrationTests/ControllerTestsBase.cs create mode 100644 EstateReportingAPI.IntegrationTests/CustomWebApplicationFactory.cs create mode 100644 EstateReportingAPI.IntegrationTests/DatabaseHelper.cs create mode 100644 EstateReportingAPI.IntegrationTests/DimensionControllerTests.cs create mode 100644 EstateReportingAPI.IntegrationTests/EstateReportingAPI.IntegrationTests.csproj create mode 100644 EstateReportingAPI.IntegrationTests/Extensions.cs create mode 100644 EstateReportingAPI.IntegrationTests/FactSettlementsControllerTests.cs create mode 100644 EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs rename EstateReportingAPI/Controllers/{Dimensions.cs => DimensionsController.cs} (100%) diff --git a/.github/workflows/createrelease.yml b/.github/workflows/createrelease.yml index 899cc69..4759098 100644 --- a/.github/workflows/createrelease.yml +++ b/.github/workflows/createrelease.yml @@ -29,6 +29,10 @@ jobs: run: | echo "ASPNETCORE_ENVIRONMENT are > ${ASPNETCORE_ENVIRONMENT}" dotnet test "EstateReportingAPI.Tests\EstateReportingAPI.Tests.csproj" + + - name: Run Integration Tests + run: | + dotnet test "EstateReportingAPI.IntegrationTests\EstateReportingAPI.IntegrationTests.csproj" - name: Publish Images to Docker Hub - Pre Release if: ${{ github.event.release.prerelease == true }} diff --git a/.github/workflows/nightlybuild.yml b/.github/workflows/nightlybuild.yml index 7a4926e..021492e 100644 --- a/.github/workflows/nightlybuild.yml +++ b/.github/workflows/nightlybuild.yml @@ -67,8 +67,9 @@ jobs: - name: Build Docker Image run: docker build . --file EstateReportingAPI/Dockerfile --tag estatereportingapi:latest - #- name: Run Integration Tests - #run: dotnet test "EstateReportingAPI.IntegrationTests\EstateReportingAPI.IntegrationTests.csproj" + - name: Run Integration Tests + run: | + dotnet test "EstateReportingAPI.IntegrationTests\EstateReportingAPI.IntegrationTests.csproj" - uses: actions/upload-artifact@v2 if: ${{ failure() }} diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index e074aaa..6e7822b 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -26,12 +26,10 @@ jobs: run: | echo "ASPNETCORE_ENVIRONMENT are > ${ASPNETCORE_ENVIRONMENT}" dotnet test "EstateReportingAPI.Tests\EstateReportingAPI.Tests.csproj" - - - name: Build Docker Image - run: docker build . --file EstateReportingAPI/Dockerfile --tag estatereportingapi:latest - - #- name: Run Integration Tests - #run: dotnet test "EstateReportingAPI.IntegrationTests\EstateReportingAPI.IntegrationTests.csproj" --filter Category=PRTest + + - name: Run Integration Tests + run: | + dotnet test "EstateReportingAPI.IntegrationTests\EstateReportingAPI.IntegrationTests.csproj" - uses: actions/upload-artifact@v2 if: ${{ failure() }} diff --git a/EstateReportingAPI.BusinessLogic/ReportingManager.cs b/EstateReportingAPI.BusinessLogic/ReportingManager.cs index c728ac7..47b2822 100644 --- a/EstateReportingAPI.BusinessLogic/ReportingManager.cs +++ b/EstateReportingAPI.BusinessLogic/ReportingManager.cs @@ -10,6 +10,8 @@ public class ReportingManager : IReportingManager{ private readonly Shared.EntityFramework.IDbContextFactory ContextFactory; + private Guid Id; + #endregion #region Constructors @@ -76,7 +78,7 @@ public async Task> GetCalendarDates(Guid estateId, CancellationTo public async Task> GetCalendarYears(Guid estateId, CancellationToken cancellationToken){ EstateManagementGenericContext? context = await this.ContextFactory.GetContext(estateId, ReportingManager.ConnectionStringIdentifier, cancellationToken); - + List years = context.Calendar.Where(c => c.Date <= DateTime.Now.Date).GroupBy(c => c.Year).Select(y => y.Key).ToList(); return years; diff --git a/EstateReportingAPI.IntegrationTests/ControllerTestsBase.cs b/EstateReportingAPI.IntegrationTests/ControllerTestsBase.cs new file mode 100644 index 0000000..56845dc --- /dev/null +++ b/EstateReportingAPI.IntegrationTests/ControllerTestsBase.cs @@ -0,0 +1,61 @@ +namespace EstateReportingAPI.IntegrationTests; + +using Common; +using Ductus.FluentDocker.Services; +using Ductus.FluentDocker.Services.Extensions; +using NLog; +using Shared.IntegrationTesting; +using Shared.Logger; + +public abstract class ControllerTestsBase{ + + protected readonly HttpClient Client; + + protected readonly CustomWebApplicationFactory factory; + + protected readonly Guid TestId; + + public ControllerTestsBase(){ + this.StartSqlContainer(); + + this.TestId = Guid.NewGuid(); + String dbConnString = GetLocalConnectionString($"EstateReportingReadModel{this.TestId}"); + + this.factory = new CustomWebApplicationFactory(dbConnString); + this.Client = this.factory.CreateClient(); + } + + internal async Task CreateAndSendHttpRequestMessage(String url) + { + HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, url); + requestMessage.Headers.Add("estateId", this.TestId.ToString()); + + HttpResponseMessage result = await this.Client.SendAsync(requestMessage, CancellationToken.None); + + return result; + } + public static IContainerService DatabaseServerContainer; + public static INetworkService DatabaseServerNetwork; + public static (String usename, String password) SqlCredentials = ("sa", "thisisalongpassword123!"); + + public static String GetLocalConnectionString(String databaseName) + { + Int32 databaseHostPort = DatabaseServerContainer.ToHostExposedEndpoint("1433/tcp").Port; + + return $"server=localhost,{databaseHostPort};database={databaseName};user id={SqlCredentials.usename};password={SqlCredentials.password};Encrypt=false"; + } + + internal void StartSqlContainer(){ + DockerHelper dockerHelper = new DockerHelper(); + + NlogLogger logger = new NlogLogger(); + logger.Initialise(LogManager.GetLogger("Specflow"), "Specflow"); + LogManager.AddHiddenAssembly(typeof(NlogLogger).Assembly); + dockerHelper.Logger = logger; + dockerHelper.SqlCredentials = SqlCredentials; + dockerHelper.SqlServerContainerName = "sharedsqlserver"; + + DatabaseServerNetwork = dockerHelper.SetupTestNetwork("sharednetwork", true); + DatabaseServerContainer = dockerHelper.SetupSqlServerContainer(DatabaseServerNetwork); + } +} \ No newline at end of file diff --git a/EstateReportingAPI.IntegrationTests/CustomWebApplicationFactory.cs b/EstateReportingAPI.IntegrationTests/CustomWebApplicationFactory.cs new file mode 100644 index 0000000..c0fddda --- /dev/null +++ b/EstateReportingAPI.IntegrationTests/CustomWebApplicationFactory.cs @@ -0,0 +1,40 @@ +namespace EstateReportingAPI.IntegrationTests; + +using BusinessLogic; +using EstateManagement.Database.Contexts; +using EstateReportingAPI.Common; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.Extensions.DependencyInjection; +using Shared.EntityFramework; +using Shouldly; + +public class CustomWebApplicationFactory : WebApplicationFactory where TStartup : class +{ + private readonly string DatabaseConnectionString; + + public CustomWebApplicationFactory(string databaseConnectionString) + { + DatabaseConnectionString = databaseConnectionString; + Environment.SetEnvironmentVariable("InTestMode", "true"); + } + + protected override void ConfigureWebHost(IWebHostBuilder builder) + { + builder.ConfigureServices(containerBuilder => + { + var context = new EstateManagementSqlServerContext(DatabaseConnectionString); + Func f = connectionString => context; + + IDbContextFactory factory = new DbContextFactory(new ConfigurationReaderConnectionStringRepository(), f); + + IReportingManager manager = new ReportingManager(factory); + + containerBuilder.AddSingleton(manager); + + bool b = context.Database.EnsureCreated(); + + b.ShouldBeTrue(); + }); + } +} \ No newline at end of file diff --git a/EstateReportingAPI.IntegrationTests/DatabaseHelper.cs b/EstateReportingAPI.IntegrationTests/DatabaseHelper.cs new file mode 100644 index 0000000..63428de --- /dev/null +++ b/EstateReportingAPI.IntegrationTests/DatabaseHelper.cs @@ -0,0 +1,148 @@ +namespace EstateReportingAPI.IntegrationTests; + +using EstateManagement.Database.Contexts; +using EstateManagement.Database.Entities; +using EstateManagement.Database.Migrations.MySql; +using Microsoft.EntityFrameworkCore; + +public class DatabaseHelper{ + private readonly EstateManagementGenericContext Context; + + public DatabaseHelper(EstateManagementGenericContext context){ + this.Context = context; + } + + public async Task AddCalendarYear(Int32 year){ + List datesInYear = this.GetDatesForYear(year); + await this.AddCalendarDates(datesInYear); + } + + public async Task AddCalendarDates(List dates){ + foreach (DateTime dateTime in dates){ + EstateManagement.Database.Entities.Calendar c = dateTime.ToCalendar(); + await this.Context.Calendar.AddAsync(c); + } + + await this.Context.SaveChangesAsync(); + } + + public async Task AddCalendarDate(DateTime date){ + Calendar c = date.ToCalendar(); + await this.Context.Calendar.AddAsync(c); + await this.Context.SaveChangesAsync(); + } + + public List GetDatesForYear(Int32 year){ + List datesInYear = new List(); + DateTime startDate = new DateTime(year, 1, 1); + DateTime endDate = new DateTime(year, 12, 31); + + for (DateTime currentDate = startDate; currentDate <= endDate; currentDate = currentDate.AddDays(1)) + { + datesInYear.Add(currentDate); + } + return datesInYear; + } + + public async Task AddSettlementRecordWithFees(DateTime dateTime, Int32 estateReportingId, Int32 merchantReportingId, + List<(Decimal feeValue, Decimal calulatedValue, Int32 transactionFeeReportingId)> feesList){ + Settlement settlementRecord = new Settlement{ + ProcessingStarted = true, + IsCompleted = true, + EstateReportingId = estateReportingId, + MerchantReportingId = merchantReportingId, + ProcessingStartedDateTIme = dateTime, + SettlementDate = dateTime, + SettlementId = Guid.NewGuid(), + }; + await this.Context.Settlements.AddAsync(settlementRecord, CancellationToken.None); + + await this.Context.SaveChangesAsync(CancellationToken.None); + + var settlement = await this.Context.Settlements.Where(s => s.SettlementId == settlementRecord.SettlementId).SingleAsync(CancellationToken.None); + + Int32 counter = 1; + foreach ((Decimal feeValue, Decimal calulatedValue, Int32 transactionFeeReportingId) fee in feesList){ + MerchantSettlementFee merchantSettlementFee = new MerchantSettlementFee{ + MerchantReportingId = merchantReportingId, + SettlementReportingId = settlement.SettlementReportingId, + IsSettled = true, + FeeCalculatedDateTime = dateTime, + TransactionReportingId = counter, + TransactionFeeReportingId = fee.transactionFeeReportingId, + CalculatedValue = fee.calulatedValue, + FeeValue = fee.feeValue + }; + counter++; + await this.Context.MerchantSettlementFees.AddAsync(merchantSettlementFee, CancellationToken.None); + } + + await this.Context.SaveChangesAsync(CancellationToken.None); + } + + public async Task AddTransaction(DateTime dateTime, Int32 merchantReportingId,String operatorIdentifier, Int32 contractProductReportingId, + String responseCode, Decimal transactionAmount){ + + Transaction transaction = new Transaction{ + MerchantReportingId = merchantReportingId, + TransactionDate = dateTime.Date, + TransactionDateTime = dateTime, + IsCompleted = true, + AuthorisationCode = "ABCD1234", + DeviceIdentifier = "testdevice1", + OperatorIdentifier = operatorIdentifier, + ContractReportingId = 1, + ContractProductReportingId = contractProductReportingId, + IsAuthorised = responseCode == "0000", + ResponseCode = responseCode, + TransactionAmount = transactionAmount, + TransactionId = Guid.NewGuid(), + TransactionTime = dateTime.TimeOfDay, + TransactionType = "Sale" + }; + await this.Context.Transactions.AddAsync(transaction, CancellationToken.None); + await this.Context.SaveChangesAsync(CancellationToken.None); + return transaction; + } + + public async Task AddMerchant(Int32 estateReportingId, String merchantName, DateTime lastSaleDateTime){ + Merchant merchant = new Merchant{ + EstateReportingId = estateReportingId, + MerchantId = Guid.NewGuid(), + Name = merchantName, + LastSaleDate = lastSaleDateTime.Date, + LastSaleDateTime = lastSaleDateTime + }; + + await this.Context.Merchants.AddAsync(merchant); + await this.Context.SaveChangesAsync(CancellationToken.None); + } + + public async Task AddContractProduct(String productName){ + ContractProduct contractProduct = new ContractProduct{ + ContractReportingId = 1, + DisplayText = productName, + ProductId = Guid.NewGuid(), + ProductName = productName, + ProductType = 1, + Value = null + }; + + await this.Context.ContractProducts.AddAsync(contractProduct); + await this.Context.SaveChangesAsync(CancellationToken.None); + } + + public async Task AddEstateOperator(String operatorIdentifier){ + EstateOperator estateOperator = new EstateOperator{ + EstateReportingId = 1, + Name = operatorIdentifier, + OperatorId = Guid.NewGuid(), + RequireCustomMerchantNumber = false, + RequireCustomTerminalNumber = false + }; + + await this.Context.EstateOperators.AddAsync(estateOperator); + await this.Context.SaveChangesAsync(CancellationToken.None); + } + +} \ No newline at end of file diff --git a/EstateReportingAPI.IntegrationTests/DimensionControllerTests.cs b/EstateReportingAPI.IntegrationTests/DimensionControllerTests.cs new file mode 100644 index 0000000..75b702e --- /dev/null +++ b/EstateReportingAPI.IntegrationTests/DimensionControllerTests.cs @@ -0,0 +1,117 @@ +namespace EstateReportingAPI.IntegrationTests; + +using Common; +using DataTrasferObjects; +using EstateManagement.Database.Contexts; +using Newtonsoft.Json; +using Shouldly; +using Xunit; + +public class DimensionsControllerTests :ControllerTestsBase, IDisposable{ + + #region Methods + + [Fact] + public async Task DimensionsController_GetCalendarYears_NoDataInDatabase(){ + HttpResponseMessage response = await this.CreateAndSendHttpRequestMessage("api/dimensions/calendar/years"); + + response.IsSuccessStatusCode.ShouldBeTrue(); + String content = await response.Content.ReadAsStringAsync(CancellationToken.None); + List? years = JsonConvert.DeserializeObject>(content); + years.Count.ShouldBe(0); + } + + [Fact] + public async Task DimensionsController_GetCalendarYears_YearsReturned(){ + EstateManagementGenericContext context = new EstateManagementSqlServerContext(GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); + + DatabaseHelper helper = new DatabaseHelper(context); + + List yearList = new(){ + 2023, + 2022, + 2021 + }; + + foreach (Int32 year in yearList){ + await helper.AddCalendarYear(year); + } + + HttpResponseMessage response = await this.CreateAndSendHttpRequestMessage("api/dimensions/calendar/years"); + + response.IsSuccessStatusCode.ShouldBeTrue(); + String content = await response.Content.ReadAsStringAsync(CancellationToken.None); + List? years = JsonConvert.DeserializeObject>(content); + years.Count.ShouldBe(yearList.Count); + } + + [Fact] + public async Task DimensionsController_GetCalendarComparisonDates_DatesReturned(){ + EstateManagementGenericContext context = new EstateManagementSqlServerContext(GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); + + DatabaseHelper helper = new DatabaseHelper(context); + + List datesInYear = helper.GetDatesForYear(2023); + await helper.AddCalendarDates(datesInYear); + + HttpResponseMessage response = await this.CreateAndSendHttpRequestMessage("api/dimensions/calendar/comparisondates"); + + response.IsSuccessStatusCode.ShouldBeTrue(); + String content = await response.Content.ReadAsStringAsync(CancellationToken.None); + List dates = JsonConvert.DeserializeObject>(content); + + List expectedDates = datesInYear.Where(d => d <= DateTime.Now.Date.AddDays(-1)).ToList(); + Int32 expectedCount = expectedDates.Count + 2; + dates.Count.ShouldBe(expectedCount); + foreach (DateTime date in expectedDates){ + dates.Select(d => d.Date).Contains(date.Date).ShouldBeTrue(); + } + + dates.Select(d => d.Description).Contains("Yesterday"); + dates.Select(d => d.Description).Contains("Last Week"); + dates.Select(d => d.Description).Contains("Last Month"); + } + + [Fact] + public async Task DimensionsController_GetCalendarDates_DatesReturned(){ + EstateManagementGenericContext context = new EstateManagementSqlServerContext(GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); + + DatabaseHelper helper = new DatabaseHelper(context); + + List datesInYear = helper.GetDatesForYear(2023); + await helper.AddCalendarDates(datesInYear); + + HttpResponseMessage response = await this.CreateAndSendHttpRequestMessage("api/dimensions/calendar/2023/dates"); + + response.IsSuccessStatusCode.ShouldBeTrue(); + String content = await response.Content.ReadAsStringAsync(CancellationToken.None); + List dates = JsonConvert.DeserializeObject>(content); + dates.Count.ShouldBe(datesInYear.Where(d => d <= DateTime.Now.Date).ToList().Count); + + foreach (DateTime date in datesInYear.Where(d => d <= DateTime.Now.Date).ToList()){ + CalendarDate? x = dates.SingleOrDefault(d => d.Date == date); + x.ShouldNotBeNull(); + } + } + + [Fact] + public async Task DimensionsController_GetCalendarDates_NoDataInDatabase(){ + HttpResponseMessage response = await this.CreateAndSendHttpRequestMessage("api/dimensions/calendar/2023/dates"); + + response.IsSuccessStatusCode.ShouldBeTrue(); + String content = await response.Content.ReadAsStringAsync(CancellationToken.None); + List dates = JsonConvert.DeserializeObject>(content); + dates.Count.ShouldBe(0); + } + + #endregion + + public void Dispose(){ + EstateManagementGenericContext context = new EstateManagementSqlServerContext(GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); + + Console.WriteLine($"About to delete database EstateReportingReadModel{this.TestId.ToString()}"); + Boolean result = context.Database.EnsureDeleted(); + Console.WriteLine($"Delete result is {result}"); + result.ShouldBeTrue(); + } +} \ No newline at end of file diff --git a/EstateReportingAPI.IntegrationTests/EstateReportingAPI.IntegrationTests.csproj b/EstateReportingAPI.IntegrationTests/EstateReportingAPI.IntegrationTests.csproj new file mode 100644 index 0000000..00d47c2 --- /dev/null +++ b/EstateReportingAPI.IntegrationTests/EstateReportingAPI.IntegrationTests.csproj @@ -0,0 +1,39 @@ + + + + net7.0 + enable + enable + + false + true + + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + + + + + + + + diff --git a/EstateReportingAPI.IntegrationTests/Extensions.cs b/EstateReportingAPI.IntegrationTests/Extensions.cs new file mode 100644 index 0000000..a1d9fab --- /dev/null +++ b/EstateReportingAPI.IntegrationTests/Extensions.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EstateReportingAPI.IntegrationTests +{ + using BusinessLogic; + using EstateManagement.Database.Entities; + using EstateReportingAPI.Common; + using Microsoft.Extensions.DependencyInjection; + using Shared.EntityFramework; + using System.Globalization; + using Calendar = System.Globalization.Calendar; + + public static class Extensions{ + public static EstateManagement.Database.Entities.Calendar ToCalendar(this DateTime date){ + return new EstateManagement.Database.Entities.Calendar{ + Date = date, + DayOfWeek = date.DayOfWeek.ToString(), + DayOfWeekShort = date.DayOfWeek.ToString().Substring(0, 3), + YearWeekNumber = $"{date.Year}{date.GetWeekNumber().ToString().PadLeft(2, '0')}", + WeekNumberString = date.GetWeekNumber().ToString().PadLeft(2, '0'), + MonthNameLong = date.ToString("MMMM"), + MonthNameShort = date.ToString("MMM"), + Year = date.Year, + DayOfWeekNumber = date.GetDayOfWeekNumber(), + MonthNumber = date.Month, + WeekNumber = date.GetWeekNumber() + }; + } + + public static Int32 GetWeekNumber(this DateTime date){ + // Define the calendar to use (in this case, the Gregorian calendar) + Calendar calendar = CultureInfo.InvariantCulture.Calendar; + + // Get the week number for the current date + int weekNumber = calendar.GetWeekOfYear(date, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday); + return weekNumber; + } + + public static Int32 GetDayOfWeekNumber(this DateTime date) + { + // Define the calendar to use (in this case, the Gregorian calendar) + Calendar calendar = CultureInfo.InvariantCulture.Calendar; + + // Get the week number for the current date + int dayOfWeekNumber = (Int32)calendar.GetDayOfWeek(date); + return dayOfWeekNumber; + } + } +} diff --git a/EstateReportingAPI.IntegrationTests/FactSettlementsControllerTests.cs b/EstateReportingAPI.IntegrationTests/FactSettlementsControllerTests.cs new file mode 100644 index 0000000..1eeea39 --- /dev/null +++ b/EstateReportingAPI.IntegrationTests/FactSettlementsControllerTests.cs @@ -0,0 +1,59 @@ +namespace EstateReportingAPI.IntegrationTests +{ + using DataTransferObjects; + using EstateManagement.Database.Contexts; + using Newtonsoft.Json; + using Shouldly; + using Xunit; + + public class FactSettlementsControllerTests : ControllerTestsBase, IDisposable + { + public void Dispose() + { + EstateManagementGenericContext context = new EstateManagementSqlServerContext(GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); + + Console.WriteLine($"About to delete database EstateReportingReadModel{this.TestId.ToString()}"); + Boolean result = context.Database.EnsureDeleted(); + Console.WriteLine($"Delete result is {result}"); + result.ShouldBeTrue(); + } + + [Fact] + public async Task FactSettlementsController_TodaysSettlement_SettlementReturned(){ + EstateManagementGenericContext context = new EstateManagementSqlServerContext(GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); + + DatabaseHelper helper = new DatabaseHelper(context); + List<(Decimal feeValue, Decimal calulatedValue, Int32 transactionFeeReportingId)> todaysSettlementFees = new(); + + Int32 todaysSettlementTransactionCount = 15; + for (int i = 1; i <= todaysSettlementTransactionCount; i++){ + todaysSettlementFees.Add((0.5m, 0.5m * i, i)); + } + + await helper.AddSettlementRecordWithFees(DateTime.Now, 1, 1, todaysSettlementFees); + + List<(Decimal feeValue, Decimal calulatedValue, Int32 transactionFeeReportingId)> comparisonDateSettlementFees = new(); + + Int32 comparisonDateSettlementTransactionCount = 9; + for (int i = 1; i <= comparisonDateSettlementTransactionCount; i++) + { + comparisonDateSettlementFees.Add((0.5m, 0.5m * i, i)); + } + + DateTime comparisonDate = DateTime.Now.AddDays(-1); + await helper.AddSettlementRecordWithFees(comparisonDate, 1, 1, comparisonDateSettlementFees); + + HttpResponseMessage response = await this.CreateAndSendHttpRequestMessage($"api/facts/settlements/todayssettlement?comparisonDate={comparisonDate.ToString("yyyy-MM-dd")}"); + + response.IsSuccessStatusCode.ShouldBeTrue(); + String content = await response.Content.ReadAsStringAsync(CancellationToken.None); + TodaysSettlement? todaysSettlement = JsonConvert.DeserializeObject(content); + todaysSettlement.ComparisonSettlementCount.ShouldBe(comparisonDateSettlementTransactionCount); + todaysSettlement.ComparisonSettlementValue.ShouldBe(comparisonDateSettlementFees.Sum(c => c.calulatedValue)); + + todaysSettlement.TodaysSettlementCount.ShouldBe(todaysSettlementTransactionCount); + todaysSettlement.TodaysSettlementValue.ShouldBe(todaysSettlementFees.Sum(c => c.calulatedValue)); + } + } +} + diff --git a/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs b/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs new file mode 100644 index 0000000..236711c --- /dev/null +++ b/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs @@ -0,0 +1,603 @@ +namespace EstateReportingAPI.IntegrationTests; + +using DataTransferObjects; +using EstateManagement.Database.Contexts; +using EstateManagement.Database.Entities; +using Newtonsoft.Json; +using Shouldly; +using Xunit; + +public class FactTransactionsControllerTests : ControllerTestsBase, IDisposable{ + [Fact] + public async Task FactTransactionsControllerController_TodaysSales_SalesReturned(){ + EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); + var todaysTransactions = new List(); + var comparisonDateTransactions = new List(); + DatabaseHelper helper = new DatabaseHelper(context); + // TODO: make counts dynamic + DateTime todaysDateTime = DateTime.Now; + + for (int i = 0; i < 25; i++){ + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(todaysDateTime.AddHours(-1), 1, "Safaricom", 1, "0000", amount ); + todaysTransactions.Add(transaction); + } + + DateTime comparisonDate = DateTime.Now.AddDays(-1).AddHours(-1); + for (int i = 0; i < 21; i++) + { + Decimal amount = 100 + i; + Transaction transaction= await helper.AddTransaction(comparisonDate, 1, "Safaricom", 1, "0000", amount); + comparisonDateTransactions.Add(transaction); + } + + HttpResponseMessage response = await this.CreateAndSendHttpRequestMessage($"api/facts/transactions/todayssales?comparisonDate={comparisonDate.ToString("yyyy-MM-dd")}"); + + response.IsSuccessStatusCode.ShouldBeTrue(); + String content = await response.Content.ReadAsStringAsync(CancellationToken.None); + TodaysSales? todaysSales = JsonConvert.DeserializeObject(content); + todaysSales.ComparisonSalesCount.ShouldBe(comparisonDateTransactions.Count); + todaysSales.ComparisonSalesValue.ShouldBe(comparisonDateTransactions.Sum(c => c.TransactionAmount)); + + todaysSales.TodaysSalesCount.ShouldBe(todaysTransactions.Count); + todaysSales.ComparisonSalesValue.ShouldBe(comparisonDateTransactions.Sum(c => c.TransactionAmount)); + } + + [Fact] + public async Task FactTransactionsControllerController_TodaysSalesCountByHour_SalesReturned() + { + EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); + var todaysTransactions = new List(); + var comparisonDateTransactions = new List(); + DatabaseHelper helper = new DatabaseHelper(context); + // TODO: make counts dynamic + DateTime todaysDateTime = DateTime.Now; + + for (int hour = 0; hour < 24; hour++){ + DateTime date = new DateTime(todaysDateTime.Year, todaysDateTime.Month, todaysDateTime.Day, hour, 0, 0); + for (int i = 0; i < 25; i++){ + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(date, 1, "Safaricom", 1, "0000", amount); + todaysTransactions.Add(transaction); + } + } + + DateTime comparisonDate = todaysDateTime.AddDays(-1); + for (int hour = 0; hour < 24; hour++){ + DateTime date = new DateTime(comparisonDate.Year, comparisonDate.Month, comparisonDate.Day, hour, 0, 0); + for (int i = 0; i < 21; i++){ + Decimal amount = 100 + i; + + Transaction transaction = await helper.AddTransaction(comparisonDate, 1, "Safaricom", 1, "0000", amount); + comparisonDateTransactions.Add(transaction); + } + } + + HttpResponseMessage response = await this.CreateAndSendHttpRequestMessage($"api/facts/transactions/todayssales/countbyhour?comparisonDate={comparisonDate.ToString("yyyy-MM-dd")}"); + + response.IsSuccessStatusCode.ShouldBeTrue(); + String content = await response.Content.ReadAsStringAsync(CancellationToken.None); + List? todaysSalesCountByHour = JsonConvert.DeserializeObject>(content); + + foreach (TodaysSalesCountByHour salesCountByHour in todaysSalesCountByHour){ + var todayHour = todaysTransactions.Where(t => t.TransactionDateTime.Hour == salesCountByHour.Hour); + var comparisonHour = todaysTransactions.Where(t => t.TransactionDateTime.Hour == salesCountByHour.Hour); + salesCountByHour.ComparisonSalesCount.ShouldBe(comparisonHour.Count()); + salesCountByHour.TodaysSalesCount.ShouldBe(todayHour.Count()); + } + } + + [Fact] + public async Task FactTransactionsControllerController_TodaysSalesValueByHour_SalesReturned() + { + EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); + var todaysTransactions = new List(); + var comparisonDateTransactions = new List(); + DatabaseHelper helper = new DatabaseHelper(context); + // TODO: make counts dynamic + DateTime todaysDateTime = DateTime.Now; + + for (int hour = 0; hour < 24; hour++) + { + DateTime date = new DateTime(todaysDateTime.Year, todaysDateTime.Month, todaysDateTime.Day, hour, 0, 0); + for (int i = 0; i < 25; i++) + { + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(date, 1, "Safaricom", 1, "0000", amount); + todaysTransactions.Add(transaction); + } + } + + DateTime comparisonDate = todaysDateTime.AddDays(-1); + for (int hour = 0; hour < 24; hour++) + { + DateTime date = new DateTime(comparisonDate.Year, comparisonDate.Month, comparisonDate.Day, hour, 0, 0); + for (int i = 0; i < 21; i++) + { + Decimal amount = 100 + i; + + Transaction transaction = await helper.AddTransaction(comparisonDate, 1, "Safaricom", 1, "0000", amount); + comparisonDateTransactions.Add(transaction); + } + } + + HttpResponseMessage response = await this.CreateAndSendHttpRequestMessage($"api/facts/transactions/todayssales/valuebyhour?comparisonDate={comparisonDate.ToString("yyyy-MM-dd")}"); + + response.IsSuccessStatusCode.ShouldBeTrue(); + String content = await response.Content.ReadAsStringAsync(CancellationToken.None); + List? todaysSalesValueByHour = JsonConvert.DeserializeObject>(content); + + foreach (TodaysSalesValueByHour salesValueByHour in todaysSalesValueByHour) + { + var todayHour = todaysTransactions.Where(t => t.TransactionDateTime.Hour == salesValueByHour.Hour); + var comparisonHour = todaysTransactions.Where(t => t.TransactionDateTime.Hour == salesValueByHour.Hour); + salesValueByHour.ComparisonSalesValue.ShouldBe(comparisonHour.Sum(c => c.TransactionAmount)); + salesValueByHour.ComparisonSalesValue.ShouldBe(todayHour.Sum(c => c.TransactionAmount)); + } + } + + [Fact] + public async Task FactTransactionsControllerController_TodaysFailedSales_SalesReturned() + { + EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); + var todaysTransactions = new List(); + var comparisonDateTransactions = new List(); + DatabaseHelper helper = new DatabaseHelper(context); + // TODO: make counts dynamic + DateTime todaysDateTime = DateTime.Now; + + for (int i = 0; i < 25; i++) + { + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(todaysDateTime.AddHours(-1), 1, "Safaricom", 1, "1009", amount); + todaysTransactions.Add(transaction); + } + + DateTime comparisonDate = DateTime.Now.AddDays(-1).AddHours(-1); + for (int i = 0; i < 21; i++) + { + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(comparisonDate, 1, "Safaricom", 1, "1009", amount); + comparisonDateTransactions.Add(transaction); + } + + HttpResponseMessage response = await this.CreateAndSendHttpRequestMessage($"api/facts/transactions/todaysfailedsales?responseCode=1009&comparisonDate={comparisonDate.ToString("yyyy-MM-dd")}"); + + response.IsSuccessStatusCode.ShouldBeTrue(); + String content = await response.Content.ReadAsStringAsync(CancellationToken.None); + TodaysSales? todaysSales = JsonConvert.DeserializeObject(content); + todaysSales.ComparisonSalesCount.ShouldBe(comparisonDateTransactions.Count); + todaysSales.ComparisonSalesValue.ShouldBe(comparisonDateTransactions.Sum(c => c.TransactionAmount)); + + todaysSales.TodaysSalesCount.ShouldBe(todaysTransactions.Count); + todaysSales.ComparisonSalesValue.ShouldBe(comparisonDateTransactions.Sum(c => c.TransactionAmount)); + } + + [Fact] + public async Task FactTransactionsControllerController_GetMerchantsTransactionKpis_SalesReturned() + { + EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); + + DatabaseHelper helper = new DatabaseHelper(context); + + DateTime todaysDateTime = DateTime.Now; + + // Last Hour + await helper.AddMerchant(1, "Merchant 1", todaysDateTime.AddMinutes(-10)); + await helper.AddMerchant(1, "Merchant 2", todaysDateTime.AddMinutes(-10)); + await helper.AddMerchant(1, "Merchant 3", todaysDateTime.AddMinutes(-10)); + await helper.AddMerchant(1, "Merchant 4", todaysDateTime.AddMinutes(-10)); + + // Yesterday + await helper.AddMerchant(1, "Merchant 5", todaysDateTime.AddDays(-1)); + await helper.AddMerchant(1, "Merchant 6", todaysDateTime.AddDays(-1)); + await helper.AddMerchant(1, "Merchant 7", todaysDateTime.AddDays(-1)); + await helper.AddMerchant(1, "Merchant 8", todaysDateTime.AddDays(-1)); + await helper.AddMerchant(1, "Merchant 9", todaysDateTime.AddDays(-1)); + await helper.AddMerchant(1, "Merchant 10", todaysDateTime.AddDays(-1)); + + // 10 Days Ago + await helper.AddMerchant(1, "Merchant 11", todaysDateTime.AddDays(-10)); + await helper.AddMerchant(1, "Merchant 12", todaysDateTime.AddDays(-10)); + await helper.AddMerchant(1, "Merchant 13", todaysDateTime.AddDays(-10)); + await helper.AddMerchant(1, "Merchant 14", todaysDateTime.AddDays(-10)); + await helper.AddMerchant(1, "Merchant 15", todaysDateTime.AddDays(-10)); + await helper.AddMerchant(1, "Merchant 16", todaysDateTime.AddDays(-10)); + await helper.AddMerchant(1, "Merchant 17", todaysDateTime.AddDays(-10)); + await helper.AddMerchant(1, "Merchant 18", todaysDateTime.AddDays(-10)); + + HttpResponseMessage response = await this.CreateAndSendHttpRequestMessage($"api/facts/transactions/merchantkpis"); + + response.IsSuccessStatusCode.ShouldBeTrue(); + String content = await response.Content.ReadAsStringAsync(CancellationToken.None); + MerchantKpi? merchantKpi = JsonConvert.DeserializeObject(content); + merchantKpi.MerchantsWithSaleInLastHour.ShouldBe(4); + merchantKpi.MerchantsWithNoSaleToday.ShouldBe(6); + merchantKpi.MerchantsWithNoSaleInLast7Days.ShouldBe(8); + } + + [Fact] + public async Task FactTransactionsController_GetTopBottomProductsByValue_BottomProducts_ProductsReturned(){ + EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); + + DatabaseHelper helper = new DatabaseHelper(context); + List product1Transactions = new List(); + List product2Transactions = new List(); + List product3Transactions = new List(); + List product4Transactions = new List(); + + DateTime todaysDateTime = DateTime.Now.AddHours(-1); + // Product 1 + for (int i = 0; i < 25; i++){ + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(todaysDateTime, 1, "Safaricom", 1, "0000", amount); + product1Transactions.Add(transaction); + } + + // Product 2 + for (int i = 0; i < 15; i++) + { + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(todaysDateTime, 1, "Safaricom", 2, "0000", amount); + product2Transactions.Add(transaction); + } + + // Product 3 + for (int i = 0; i < 45; i++) + { + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(todaysDateTime, 1, "Safaricom", 3, "0000", amount); + product3Transactions.Add(transaction); + } + + // Product 4 + for (int i = 0; i < 8; i++) + { + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(todaysDateTime, 1, "Safaricom", 4, "0000", amount); + product4Transactions.Add(transaction); + } + + await helper.AddContractProduct("Product 1"); + await helper.AddContractProduct("Product 2"); + await helper.AddContractProduct("Product 3"); + await helper.AddContractProduct("Product 4"); + + HttpResponseMessage response = await this.CreateAndSendHttpRequestMessage($"api/facts/transactions/products/topbottombyvalue?count=3&topOrBottom=bottom"); + + response.IsSuccessStatusCode.ShouldBeTrue(); + String content = await response.Content.ReadAsStringAsync(CancellationToken.None); + List? topBottomProductData = JsonConvert.DeserializeObject>(content); + + topBottomProductData[0].ProductName.ShouldBe("Product 4"); + topBottomProductData[0].SalesValue.ShouldBe(product4Transactions.Sum(p => p.TransactionAmount)); + topBottomProductData[1].ProductName.ShouldBe("Product 2"); + topBottomProductData[1].SalesValue.ShouldBe(product2Transactions.Sum(p => p.TransactionAmount)); + topBottomProductData[2].ProductName.ShouldBe("Product 1"); + topBottomProductData[2].SalesValue.ShouldBe(product1Transactions.Sum(p => p.TransactionAmount)); + } + + [Fact] + public async Task FactTransactionsController_GetTopBottomProductsByValue_Top_ProductsReturned() + { + EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); + + DatabaseHelper helper = new DatabaseHelper(context); + List product1Transactions = new List(); + List product2Transactions = new List(); + List product3Transactions = new List(); + List product4Transactions = new List(); + + DateTime todaysDateTime = DateTime.Now.AddHours(-1); + // Product 1 + for (int i = 0; i < 25; i++) + { + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(todaysDateTime, 1, "Safaricom", 1, "0000", amount); + product1Transactions.Add(transaction); + } + + // Product 2 + for (int i = 0; i < 15; i++) + { + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(todaysDateTime, 1, "Safaricom", 2, "0000", amount); + product2Transactions.Add(transaction); + } + + // Product 3 + for (int i = 0; i < 45; i++) + { + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(todaysDateTime, 1, "Safaricom", 3, "0000", amount); + product3Transactions.Add(transaction); + } + + for (int i = 0; i < 8; i++) + { + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(todaysDateTime, 1, "Safaricom", 4, "0000", amount); + product4Transactions.Add(transaction); + } + + await helper.AddContractProduct("Product 1"); + await helper.AddContractProduct("Product 2"); + await helper.AddContractProduct("Product 3"); + await helper.AddContractProduct("Product 4"); + + HttpResponseMessage response = await this.CreateAndSendHttpRequestMessage($"api/facts/transactions/products/topbottombyvalue?count=3&topOrBottom=top"); + + response.IsSuccessStatusCode.ShouldBeTrue(); + String content = await response.Content.ReadAsStringAsync(CancellationToken.None); + List? topBottomProductData = JsonConvert.DeserializeObject>(content); + + topBottomProductData[0].ProductName.ShouldBe("Product 3"); + topBottomProductData[0].SalesValue.ShouldBe(product3Transactions.Sum(p => p.TransactionAmount)); + topBottomProductData[1].ProductName.ShouldBe("Product 1"); + topBottomProductData[1].SalesValue.ShouldBe(product1Transactions.Sum(p => p.TransactionAmount)); + topBottomProductData[2].ProductName.ShouldBe("Product 2"); + topBottomProductData[2].SalesValue.ShouldBe(product2Transactions.Sum(p => p.TransactionAmount)); + } + + [Fact] + public async Task FactTransactionsController_GetTopBottomOperatorsByValue_BottomOperators_OperatorsReturned() + { + EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); + + DatabaseHelper helper = new DatabaseHelper(context); + List operator1Transactions = new List(); + List operator2Transactions = new List(); + List operator3Transactions = new List(); + List operator4Transactions = new List(); + + DateTime todaysDateTime = DateTime.Now.AddHours(-1); + // Operator 1 + for (int i = 0; i < 25; i++) + { + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(todaysDateTime, 1, "Operator 1", 1, "0000", amount); + operator1Transactions.Add(transaction); + } + + // Operator 2 + for (int i = 0; i < 15; i++) + { + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(todaysDateTime, 1, "Operator 2", 2, "0000", amount); + operator2Transactions.Add(transaction); + } + + // Operator 3 + for (int i = 0; i < 45; i++) + { + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(todaysDateTime, 1, "Operator 3", 3, "0000", amount); + operator3Transactions.Add(transaction); + } + + // Operator 4 + for (int i = 0; i < 8; i++) + { + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(todaysDateTime, 1, "Operator 4", 4, "0000", amount); + operator4Transactions.Add(transaction); + } + + await helper.AddEstateOperator("Operator 1"); + await helper.AddEstateOperator("Operator 2"); + await helper.AddEstateOperator("Operator 3"); + await helper.AddEstateOperator("Operator 4"); + + HttpResponseMessage response = await this.CreateAndSendHttpRequestMessage($"api/facts/transactions/operators/topbottombyvalue?count=3&topOrBottom=bottom"); + + response.IsSuccessStatusCode.ShouldBeTrue(); + String content = await response.Content.ReadAsStringAsync(CancellationToken.None); + List? topBottomOperatorData = JsonConvert.DeserializeObject>(content); + + topBottomOperatorData[0].OperatorName.ShouldBe("Operator 4"); + topBottomOperatorData[0].SalesValue.ShouldBe(operator4Transactions.Sum(p => p.TransactionAmount)); + topBottomOperatorData[1].OperatorName.ShouldBe("Operator 2"); + topBottomOperatorData[1].SalesValue.ShouldBe(operator2Transactions.Sum(p => p.TransactionAmount)); + topBottomOperatorData[2].OperatorName.ShouldBe("Operator 1"); + topBottomOperatorData[2].SalesValue.ShouldBe(operator1Transactions.Sum(p => p.TransactionAmount)); + } + + [Fact] + public async Task FactTransactionsController_GetTopBottomOperatorsByValue_TopOperators_OperatorsReturned() + { + EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); + + DatabaseHelper helper = new DatabaseHelper(context); + List operator1Transactions = new List(); + List operator2Transactions = new List(); + List operator3Transactions = new List(); + List operator4Transactions = new List(); + + DateTime todaysDateTime = DateTime.Now.AddHours(-1); + // Operator 1 + for (int i = 0; i < 25; i++) + { + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(todaysDateTime, 1, "Operator 1", 1, "0000", amount); + operator1Transactions.Add(transaction); + } + + // Operator 2 + for (int i = 0; i < 15; i++) + { + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(todaysDateTime, 1, "Operator 2", 2, "0000", amount); + operator2Transactions.Add(transaction); + } + + // Operator 3 + for (int i = 0; i < 45; i++) + { + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(todaysDateTime, 1, "Operator 3", 3, "0000", amount); + operator3Transactions.Add(transaction); + } + + // Operator 4 + for (int i = 0; i < 8; i++) + { + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(todaysDateTime, 1, "Operator 4", 4, "0000", amount); + operator4Transactions.Add(transaction); + } + + await helper.AddEstateOperator("Operator 1"); + await helper.AddEstateOperator("Operator 2"); + await helper.AddEstateOperator("Operator 3"); + await helper.AddEstateOperator("Operator 4"); + + HttpResponseMessage response = await this.CreateAndSendHttpRequestMessage($"api/facts/transactions/operators/topbottombyvalue?count=3&topOrBottom=top"); + + response.IsSuccessStatusCode.ShouldBeTrue(); + String content = await response.Content.ReadAsStringAsync(CancellationToken.None); + List? topBottomOperatorData = JsonConvert.DeserializeObject>(content); + + topBottomOperatorData[0].OperatorName.ShouldBe("Operator 3"); + topBottomOperatorData[0].SalesValue.ShouldBe(operator3Transactions.Sum(p => p.TransactionAmount)); + topBottomOperatorData[1].OperatorName.ShouldBe("Operator 1"); + topBottomOperatorData[1].SalesValue.ShouldBe(operator1Transactions.Sum(p => p.TransactionAmount)); + topBottomOperatorData[2].OperatorName.ShouldBe("Operator 2"); + topBottomOperatorData[2].SalesValue.ShouldBe(operator2Transactions.Sum(p => p.TransactionAmount)); + } + + [Fact] + public async Task FactTransactionsController_GetTopBottoMerchantsByValue_BottomMerchants_MerchantsReturned() + { + EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); + + DatabaseHelper helper = new DatabaseHelper(context); + List merchant1Transactions = new List(); + List merchant2Transactions = new List(); + List merchant3Transactions = new List(); + List merchant4Transactions = new List(); + + DateTime todaysDateTime = DateTime.Now.AddHours(-1); + // Merchants 1 + for (int i = 0; i < 25; i++) + { + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(todaysDateTime, 1, "Safaricom", 1, "0000", amount); + merchant1Transactions.Add(transaction); + } + + // Merchants 2 + for (int i = 0; i < 15; i++) + { + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(todaysDateTime, 2, "Safaricom", 2, "0000", amount); + merchant2Transactions.Add(transaction); + } + + // Merchants 3 + for (int i = 0; i < 45; i++) + { + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(todaysDateTime, 3, "Safaricom", 3, "0000", amount); + merchant3Transactions.Add(transaction); + } + + // Merchants 4 + for (int i = 0; i < 8; i++) + { + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(todaysDateTime, 4, "Safaricom", 4, "0000", amount); + merchant4Transactions.Add(transaction); + } + + await helper.AddMerchant(1, "Merchant 1", DateTime.Now); + await helper.AddMerchant(1, "Merchant 2", DateTime.Now); + await helper.AddMerchant(1, "Merchant 3", DateTime.Now); + await helper.AddMerchant(1, "Merchant 4", DateTime.Now); + + HttpResponseMessage response = await this.CreateAndSendHttpRequestMessage($"api/facts/transactions/merchants/topbottombyvalue?count=3&topOrBottom=bottom"); + + response.IsSuccessStatusCode.ShouldBeTrue(); + String content = await response.Content.ReadAsStringAsync(CancellationToken.None); + List? topBottomMerchantData = JsonConvert.DeserializeObject>(content); + + topBottomMerchantData[0].MerchantName.ShouldBe("Merchant 4"); + topBottomMerchantData[0].SalesValue.ShouldBe(merchant4Transactions.Sum(p => p.TransactionAmount)); + topBottomMerchantData[1].MerchantName.ShouldBe("Merchant 2"); + topBottomMerchantData[1].SalesValue.ShouldBe(merchant2Transactions.Sum(p => p.TransactionAmount)); + topBottomMerchantData[2].MerchantName.ShouldBe("Merchant 1"); + topBottomMerchantData[2].SalesValue.ShouldBe(merchant1Transactions.Sum(p => p.TransactionAmount)); + } + + [Fact] + public async Task FactTransactionsController_GetTopBottoMerchantsByValue_TopMerchants_MerchantsReturned() + { + EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); + + DatabaseHelper helper = new DatabaseHelper(context); + List merchant1Transactions = new List(); + List merchant2Transactions = new List(); + List merchant3Transactions = new List(); + List merchant4Transactions = new List(); + + DateTime todaysDateTime = DateTime.Now.AddHours(-1); + // Merchants 1 + for (int i = 0; i < 25; i++) + { + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(todaysDateTime, 1, "Safaricom", 1, "0000", amount); + merchant1Transactions.Add(transaction); + } + + // Merchants 2 + for (int i = 0; i < 15; i++) + { + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(todaysDateTime, 2, "Safaricom", 2, "0000", amount); + merchant2Transactions.Add(transaction); + } + + // Merchants 3 + for (int i = 0; i < 45; i++) + { + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(todaysDateTime, 3, "Safaricom", 3, "0000", amount); + merchant3Transactions.Add(transaction); + } + + // Merchants 4 + for (int i = 0; i < 8; i++) + { + Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(todaysDateTime, 4, "Safaricom", 4, "0000", amount); + merchant4Transactions.Add(transaction); + } + + await helper.AddMerchant(1, "Merchant 1", DateTime.Now); + await helper.AddMerchant(1, "Merchant 2", DateTime.Now); + await helper.AddMerchant(1, "Merchant 3", DateTime.Now); + await helper.AddMerchant(1, "Merchant 4", DateTime.Now); + + HttpResponseMessage response = await this.CreateAndSendHttpRequestMessage($"api/facts/transactions/merchants/topbottombyvalue?count=3&topOrBottom=top"); + + response.IsSuccessStatusCode.ShouldBeTrue(); + String content = await response.Content.ReadAsStringAsync(CancellationToken.None); + List? topBottomMerchantData = JsonConvert.DeserializeObject>(content); + + topBottomMerchantData[0].MerchantName.ShouldBe("Merchant 3"); + topBottomMerchantData[0].SalesValue.ShouldBe(merchant3Transactions.Sum(p => p.TransactionAmount)); + topBottomMerchantData[1].MerchantName.ShouldBe("Merchant 1"); + topBottomMerchantData[1].SalesValue.ShouldBe(merchant1Transactions.Sum(p => p.TransactionAmount)); + topBottomMerchantData[2].MerchantName.ShouldBe("Merchant 2"); + topBottomMerchantData[2].SalesValue.ShouldBe(merchant2Transactions.Sum(p => p.TransactionAmount)); + } + + public void Dispose() + { + EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); + + Console.WriteLine($"About to delete database EstateReportingReadModel{this.TestId.ToString()}"); + Boolean result = context.Database.EnsureDeleted(); + Console.WriteLine($"Delete result is {result}"); + result.ShouldBeTrue(); + } +} \ No newline at end of file diff --git a/EstateReportingAPI.sln b/EstateReportingAPI.sln index 0d27a61..07da541 100644 --- a/EstateReportingAPI.sln +++ b/EstateReportingAPI.sln @@ -19,6 +19,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EstateReportingAPI.Business EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EstateReportingAPI.Models", "EstateReportingAPI.Models\EstateReportingAPI.Models.csproj", "{B3BE4743-D80E-4247-BAC0-1224D5A6D472}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EstateReportingAPI.IntegrationTests", "EstateReportingAPI.IntegrationTests\EstateReportingAPI.IntegrationTests.csproj", "{85555B3A-FC04-4291-B0CB-F0835AC23D3E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -49,6 +51,10 @@ Global {B3BE4743-D80E-4247-BAC0-1224D5A6D472}.Debug|Any CPU.Build.0 = Debug|Any CPU {B3BE4743-D80E-4247-BAC0-1224D5A6D472}.Release|Any CPU.ActiveCfg = Release|Any CPU {B3BE4743-D80E-4247-BAC0-1224D5A6D472}.Release|Any CPU.Build.0 = Release|Any CPU + {85555B3A-FC04-4291-B0CB-F0835AC23D3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {85555B3A-FC04-4291-B0CB-F0835AC23D3E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {85555B3A-FC04-4291-B0CB-F0835AC23D3E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {85555B3A-FC04-4291-B0CB-F0835AC23D3E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -60,6 +66,7 @@ Global {8C38147F-7556-44BE-BF60-5DF40BC57EC8} = {713556C8-BFC0-4AB6-8F13-7631C1C82D07} {B71070E8-85FC-4C22-BF94-4E56D477466F} = {713556C8-BFC0-4AB6-8F13-7631C1C82D07} {B3BE4743-D80E-4247-BAC0-1224D5A6D472} = {713556C8-BFC0-4AB6-8F13-7631C1C82D07} + {85555B3A-FC04-4291-B0CB-F0835AC23D3E} = {C48C544B-7C3B-4AA2-8A37-E49296A86499} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B2BE269B-F142-45A3-9B75-483227C765A6} diff --git a/EstateReportingAPI/Bootstrapper/RepositoryRegistry.cs b/EstateReportingAPI/Bootstrapper/RepositoryRegistry.cs index 6889e66..8766cae 100644 --- a/EstateReportingAPI/Bootstrapper/RepositoryRegistry.cs +++ b/EstateReportingAPI/Bootstrapper/RepositoryRegistry.cs @@ -26,8 +26,12 @@ public RepositoryRegistry(){ { this.AddSingleton(); } - - this.AddSingleton(); + + String? inTestMode = Environment.GetEnvironmentVariable("InTestMode"); + if (String.Compare(inTestMode, Boolean.TrueString, StringComparison.InvariantCultureIgnoreCase) != 0){ + this.AddSingleton(); + } + this.AddSingleton, DbContextFactory>(); this.AddSingleton>(cont => connectionString => diff --git a/EstateReportingAPI/Controllers/Dimensions.cs b/EstateReportingAPI/Controllers/DimensionsController.cs similarity index 100% rename from EstateReportingAPI/Controllers/Dimensions.cs rename to EstateReportingAPI/Controllers/DimensionsController.cs diff --git a/EstateReportingAPI/Startup.cs b/EstateReportingAPI/Startup.cs index 9f80c1e..060c2d9 100644 --- a/EstateReportingAPI/Startup.cs +++ b/EstateReportingAPI/Startup.cs @@ -9,6 +9,9 @@ namespace EstateReportingAPI { + using BusinessLogic; + using Org.BouncyCastle.Asn1.Cmp; + public class Startup { public static IConfigurationRoot Configuration { get; set; } @@ -32,7 +35,6 @@ public Startup(IWebHostEnvironment webHostEnvironment) public void ConfigureContainer(ServiceRegistry services) { - ConfigurationReader.Initialise(Configuration); services.IncludeRegistry(); @@ -41,6 +43,22 @@ public void ConfigureContainer(ServiceRegistry services) Container = new Container(services); } + public void ConfigureServices(IServiceCollection services){ + // ConfigurationReader.Initialise(Configuration); + // ServiceRegistry registry = new ServiceRegistry(services); + // registry.IncludeRegistry(); + // registry.IncludeRegistry(); + + // Container = new Container(registry); + String? inTestMode = Environment.GetEnvironmentVariable("InTestMode"); + if (String.Compare(inTestMode, Boolean.TrueString, StringComparison.InvariantCultureIgnoreCase) == 0) + { + services.AddSingleton(); + } + + + } + public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) { string nlogConfigFilename = "nlog.config"; From 25bf83eeb0b47ed0daa0d2ede7916339711113ca Mon Sep 17 00:00:00 2001 From: Stuart Ferguson Date: Sat, 7 Oct 2023 08:27:53 +0100 Subject: [PATCH 02/12] .. --- EstateReportingAPI/appsettings.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/EstateReportingAPI/appsettings.json b/EstateReportingAPI/appsettings.json index 4204bfd..36bf196 100644 --- a/EstateReportingAPI/appsettings.json +++ b/EstateReportingAPI/appsettings.json @@ -9,6 +9,8 @@ "AppSettings": { "DatabaseEngine": "SqlServer" //"DatabaseEngine": "MySql", + }, + "ConnectionStrings": { } } From 60792d1a523fe3dea0b87ee70811e9ceedb67a1d Mon Sep 17 00:00:00 2001 From: Stuart Ferguson Date: Sat, 7 Oct 2023 08:38:30 +0100 Subject: [PATCH 03/12] missing config added --- EstateReportingAPI/appsettings.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/EstateReportingAPI/appsettings.json b/EstateReportingAPI/appsettings.json index 36bf196..1b82e99 100644 --- a/EstateReportingAPI/appsettings.json +++ b/EstateReportingAPI/appsettings.json @@ -7,10 +7,17 @@ }, "AllowedHosts": "*", "AppSettings": { + "UseConnectionStringConfig": false, "DatabaseEngine": "SqlServer" //"DatabaseEngine": "MySql", }, "ConnectionStrings": { + "HealthCheck": "", + "EstateReportingReadModel": "" + }, + "SecurityConfiguration": { + "ApiName": "", + "Authority": "" } } From 71e3fd55fc1de33f10e9aca1d92cf19a571f7bbc Mon Sep 17 00:00:00 2001 From: Stuart Ferguson Date: Sat, 7 Oct 2023 08:47:34 +0100 Subject: [PATCH 04/12] debug added --- .../DimensionControllerTests.cs | 12 +++---- .../FactSettlementsControllerTests.cs | 2 +- .../FactTransactionsControllerTests.cs | 33 ++++++++++++------- 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/EstateReportingAPI.IntegrationTests/DimensionControllerTests.cs b/EstateReportingAPI.IntegrationTests/DimensionControllerTests.cs index 75b702e..9fe28ed 100644 --- a/EstateReportingAPI.IntegrationTests/DimensionControllerTests.cs +++ b/EstateReportingAPI.IntegrationTests/DimensionControllerTests.cs @@ -8,10 +8,10 @@ using Xunit; public class DimensionsControllerTests :ControllerTestsBase, IDisposable{ - + #region Methods - [Fact] + [Fact(Skip = "")] public async Task DimensionsController_GetCalendarYears_NoDataInDatabase(){ HttpResponseMessage response = await this.CreateAndSendHttpRequestMessage("api/dimensions/calendar/years"); @@ -21,7 +21,7 @@ public async Task DimensionsController_GetCalendarYears_NoDataInDatabase(){ years.Count.ShouldBe(0); } - [Fact] + [Fact(Skip = "")] public async Task DimensionsController_GetCalendarYears_YearsReturned(){ EstateManagementGenericContext context = new EstateManagementSqlServerContext(GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -45,7 +45,7 @@ public async Task DimensionsController_GetCalendarYears_YearsReturned(){ years.Count.ShouldBe(yearList.Count); } - [Fact] + [Fact(Skip = "")] public async Task DimensionsController_GetCalendarComparisonDates_DatesReturned(){ EstateManagementGenericContext context = new EstateManagementSqlServerContext(GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -72,7 +72,7 @@ public async Task DimensionsController_GetCalendarComparisonDates_DatesReturned( dates.Select(d => d.Description).Contains("Last Month"); } - [Fact] + [Fact(Skip = "")] public async Task DimensionsController_GetCalendarDates_DatesReturned(){ EstateManagementGenericContext context = new EstateManagementSqlServerContext(GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -94,7 +94,7 @@ public async Task DimensionsController_GetCalendarDates_DatesReturned(){ } } - [Fact] + [Fact(Skip = "")] public async Task DimensionsController_GetCalendarDates_NoDataInDatabase(){ HttpResponseMessage response = await this.CreateAndSendHttpRequestMessage("api/dimensions/calendar/2023/dates"); diff --git a/EstateReportingAPI.IntegrationTests/FactSettlementsControllerTests.cs b/EstateReportingAPI.IntegrationTests/FactSettlementsControllerTests.cs index 1eeea39..686b39c 100644 --- a/EstateReportingAPI.IntegrationTests/FactSettlementsControllerTests.cs +++ b/EstateReportingAPI.IntegrationTests/FactSettlementsControllerTests.cs @@ -18,7 +18,7 @@ public void Dispose() result.ShouldBeTrue(); } - [Fact] + [Fact(Skip = "")] public async Task FactSettlementsController_TodaysSettlement_SettlementReturned(){ EstateManagementGenericContext context = new EstateManagementSqlServerContext(GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); diff --git a/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs b/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs index 236711c..80843a4 100644 --- a/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs +++ b/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs @@ -8,7 +8,7 @@ using Xunit; public class FactTransactionsControllerTests : ControllerTestsBase, IDisposable{ - [Fact] + [Fact(Skip = "")] public async Task FactTransactionsControllerController_TodaysSales_SalesReturned(){ EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); var todaysTransactions = new List(); @@ -54,23 +54,32 @@ public async Task FactTransactionsControllerController_TodaysSalesCountByHour_Sa DateTime todaysDateTime = DateTime.Now; for (int hour = 0; hour < 24; hour++){ + List localList = new List(); DateTime date = new DateTime(todaysDateTime.Year, todaysDateTime.Month, todaysDateTime.Day, hour, 0, 0); for (int i = 0; i < 25; i++){ Decimal amount = 100 + i; + Transaction transaction = await helper.AddTransaction(date, 1, "Safaricom", 1, "0000", amount); - todaysTransactions.Add(transaction); + localList.Add(transaction); } + + Console.WriteLine($"Today: Added Hour {hour} Sales Value {localList.Sum(t => t.TransactionAmount)}"); + todaysTransactions.AddRange(localList); } DateTime comparisonDate = todaysDateTime.AddDays(-1); for (int hour = 0; hour < 24; hour++){ + List localList = new List(); DateTime date = new DateTime(comparisonDate.Year, comparisonDate.Month, comparisonDate.Day, hour, 0, 0); for (int i = 0; i < 21; i++){ Decimal amount = 100 + i; Transaction transaction = await helper.AddTransaction(comparisonDate, 1, "Safaricom", 1, "0000", amount); - comparisonDateTransactions.Add(transaction); + localList.Add(transaction); } + + Console.WriteLine($"Comparison: Added Hour {hour} Sales Value {localList.Sum(t => t.TransactionAmount)}"); + comparisonDateTransactions.AddRange(localList); } HttpResponseMessage response = await this.CreateAndSendHttpRequestMessage($"api/facts/transactions/todayssales/countbyhour?comparisonDate={comparisonDate.ToString("yyyy-MM-dd")}"); @@ -87,7 +96,7 @@ public async Task FactTransactionsControllerController_TodaysSalesCountByHour_Sa } } - [Fact] + [Fact(Skip = "")] public async Task FactTransactionsControllerController_TodaysSalesValueByHour_SalesReturned() { EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -136,7 +145,7 @@ public async Task FactTransactionsControllerController_TodaysSalesValueByHour_Sa } } - [Fact] + [Fact(Skip = "")] public async Task FactTransactionsControllerController_TodaysFailedSales_SalesReturned() { EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -173,7 +182,7 @@ public async Task FactTransactionsControllerController_TodaysFailedSales_SalesRe todaysSales.ComparisonSalesValue.ShouldBe(comparisonDateTransactions.Sum(c => c.TransactionAmount)); } - [Fact] + [Fact(Skip = "")] public async Task FactTransactionsControllerController_GetMerchantsTransactionKpis_SalesReturned() { EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -216,7 +225,7 @@ public async Task FactTransactionsControllerController_GetMerchantsTransactionKp merchantKpi.MerchantsWithNoSaleInLast7Days.ShouldBe(8); } - [Fact] + [Fact(Skip = "")] public async Task FactTransactionsController_GetTopBottomProductsByValue_BottomProducts_ProductsReturned(){ EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -277,7 +286,7 @@ public async Task FactTransactionsController_GetTopBottomProductsByValue_BottomP topBottomProductData[2].SalesValue.ShouldBe(product1Transactions.Sum(p => p.TransactionAmount)); } - [Fact] + [Fact(Skip = "")] public async Task FactTransactionsController_GetTopBottomProductsByValue_Top_ProductsReturned() { EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -339,7 +348,7 @@ public async Task FactTransactionsController_GetTopBottomProductsByValue_Top_Pro topBottomProductData[2].SalesValue.ShouldBe(product2Transactions.Sum(p => p.TransactionAmount)); } - [Fact] + [Fact(Skip = "")] public async Task FactTransactionsController_GetTopBottomOperatorsByValue_BottomOperators_OperatorsReturned() { EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -402,7 +411,7 @@ public async Task FactTransactionsController_GetTopBottomOperatorsByValue_Bottom topBottomOperatorData[2].SalesValue.ShouldBe(operator1Transactions.Sum(p => p.TransactionAmount)); } - [Fact] + [Fact(Skip = "")] public async Task FactTransactionsController_GetTopBottomOperatorsByValue_TopOperators_OperatorsReturned() { EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -465,7 +474,7 @@ public async Task FactTransactionsController_GetTopBottomOperatorsByValue_TopOpe topBottomOperatorData[2].SalesValue.ShouldBe(operator2Transactions.Sum(p => p.TransactionAmount)); } - [Fact] + [Fact(Skip = "")] public async Task FactTransactionsController_GetTopBottoMerchantsByValue_BottomMerchants_MerchantsReturned() { EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -528,7 +537,7 @@ public async Task FactTransactionsController_GetTopBottoMerchantsByValue_BottomM topBottomMerchantData[2].SalesValue.ShouldBe(merchant1Transactions.Sum(p => p.TransactionAmount)); } - [Fact] + [Fact(Skip = "")] public async Task FactTransactionsController_GetTopBottoMerchantsByValue_TopMerchants_MerchantsReturned() { EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); From c8ce2e2b43d2f2ac98dfa8fcd13acead67995404 Mon Sep 17 00:00:00 2001 From: Stuart Ferguson Date: Sat, 7 Oct 2023 09:37:53 +0100 Subject: [PATCH 05/12] .. --- .../DimensionControllerTests.cs | 10 +++++----- .../FactSettlementsControllerTests.cs | 2 +- .../FactTransactionsControllerTests.cs | 20 +++++++++---------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/EstateReportingAPI.IntegrationTests/DimensionControllerTests.cs b/EstateReportingAPI.IntegrationTests/DimensionControllerTests.cs index 9fe28ed..efd9e9c 100644 --- a/EstateReportingAPI.IntegrationTests/DimensionControllerTests.cs +++ b/EstateReportingAPI.IntegrationTests/DimensionControllerTests.cs @@ -11,7 +11,7 @@ public class DimensionsControllerTests :ControllerTestsBase, IDisposable{ #region Methods - [Fact(Skip = "")] + [Fact(Skip = "A")] public async Task DimensionsController_GetCalendarYears_NoDataInDatabase(){ HttpResponseMessage response = await this.CreateAndSendHttpRequestMessage("api/dimensions/calendar/years"); @@ -21,7 +21,7 @@ public async Task DimensionsController_GetCalendarYears_NoDataInDatabase(){ years.Count.ShouldBe(0); } - [Fact(Skip = "")] + [Fact(Skip = "A")] public async Task DimensionsController_GetCalendarYears_YearsReturned(){ EstateManagementGenericContext context = new EstateManagementSqlServerContext(GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -45,7 +45,7 @@ public async Task DimensionsController_GetCalendarYears_YearsReturned(){ years.Count.ShouldBe(yearList.Count); } - [Fact(Skip = "")] + [Fact(Skip = "A")] public async Task DimensionsController_GetCalendarComparisonDates_DatesReturned(){ EstateManagementGenericContext context = new EstateManagementSqlServerContext(GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -72,7 +72,7 @@ public async Task DimensionsController_GetCalendarComparisonDates_DatesReturned( dates.Select(d => d.Description).Contains("Last Month"); } - [Fact(Skip = "")] + [Fact(Skip = "A")] public async Task DimensionsController_GetCalendarDates_DatesReturned(){ EstateManagementGenericContext context = new EstateManagementSqlServerContext(GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -94,7 +94,7 @@ public async Task DimensionsController_GetCalendarDates_DatesReturned(){ } } - [Fact(Skip = "")] + [Fact(Skip = "A")] public async Task DimensionsController_GetCalendarDates_NoDataInDatabase(){ HttpResponseMessage response = await this.CreateAndSendHttpRequestMessage("api/dimensions/calendar/2023/dates"); diff --git a/EstateReportingAPI.IntegrationTests/FactSettlementsControllerTests.cs b/EstateReportingAPI.IntegrationTests/FactSettlementsControllerTests.cs index 686b39c..d018ea8 100644 --- a/EstateReportingAPI.IntegrationTests/FactSettlementsControllerTests.cs +++ b/EstateReportingAPI.IntegrationTests/FactSettlementsControllerTests.cs @@ -18,7 +18,7 @@ public void Dispose() result.ShouldBeTrue(); } - [Fact(Skip = "")] + [Fact(Skip = "A")] public async Task FactSettlementsController_TodaysSettlement_SettlementReturned(){ EstateManagementGenericContext context = new EstateManagementSqlServerContext(GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); diff --git a/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs b/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs index 80843a4..cd5c2a0 100644 --- a/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs +++ b/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs @@ -8,7 +8,7 @@ using Xunit; public class FactTransactionsControllerTests : ControllerTestsBase, IDisposable{ - [Fact(Skip = "")] + [Fact(Skip = "A")] public async Task FactTransactionsControllerController_TodaysSales_SalesReturned(){ EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); var todaysTransactions = new List(); @@ -96,7 +96,7 @@ public async Task FactTransactionsControllerController_TodaysSalesCountByHour_Sa } } - [Fact(Skip = "")] + [Fact(Skip = "A")] public async Task FactTransactionsControllerController_TodaysSalesValueByHour_SalesReturned() { EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -145,7 +145,7 @@ public async Task FactTransactionsControllerController_TodaysSalesValueByHour_Sa } } - [Fact(Skip = "")] + [Fact(Skip = "A")] public async Task FactTransactionsControllerController_TodaysFailedSales_SalesReturned() { EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -182,7 +182,7 @@ public async Task FactTransactionsControllerController_TodaysFailedSales_SalesRe todaysSales.ComparisonSalesValue.ShouldBe(comparisonDateTransactions.Sum(c => c.TransactionAmount)); } - [Fact(Skip = "")] + [Fact(Skip = "A")] public async Task FactTransactionsControllerController_GetMerchantsTransactionKpis_SalesReturned() { EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -225,7 +225,7 @@ public async Task FactTransactionsControllerController_GetMerchantsTransactionKp merchantKpi.MerchantsWithNoSaleInLast7Days.ShouldBe(8); } - [Fact(Skip = "")] + [Fact(Skip = "A")] public async Task FactTransactionsController_GetTopBottomProductsByValue_BottomProducts_ProductsReturned(){ EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -286,7 +286,7 @@ public async Task FactTransactionsController_GetTopBottomProductsByValue_BottomP topBottomProductData[2].SalesValue.ShouldBe(product1Transactions.Sum(p => p.TransactionAmount)); } - [Fact(Skip = "")] + [Fact(Skip = "A")] public async Task FactTransactionsController_GetTopBottomProductsByValue_Top_ProductsReturned() { EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -348,7 +348,7 @@ public async Task FactTransactionsController_GetTopBottomProductsByValue_Top_Pro topBottomProductData[2].SalesValue.ShouldBe(product2Transactions.Sum(p => p.TransactionAmount)); } - [Fact(Skip = "")] + [Fact(Skip = "A")] public async Task FactTransactionsController_GetTopBottomOperatorsByValue_BottomOperators_OperatorsReturned() { EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -411,7 +411,7 @@ public async Task FactTransactionsController_GetTopBottomOperatorsByValue_Bottom topBottomOperatorData[2].SalesValue.ShouldBe(operator1Transactions.Sum(p => p.TransactionAmount)); } - [Fact(Skip = "")] + [Fact(Skip = "A")] public async Task FactTransactionsController_GetTopBottomOperatorsByValue_TopOperators_OperatorsReturned() { EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -474,7 +474,7 @@ public async Task FactTransactionsController_GetTopBottomOperatorsByValue_TopOpe topBottomOperatorData[2].SalesValue.ShouldBe(operator2Transactions.Sum(p => p.TransactionAmount)); } - [Fact(Skip = "")] + [Fact(Skip = "A")] public async Task FactTransactionsController_GetTopBottoMerchantsByValue_BottomMerchants_MerchantsReturned() { EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -537,7 +537,7 @@ public async Task FactTransactionsController_GetTopBottoMerchantsByValue_BottomM topBottomMerchantData[2].SalesValue.ShouldBe(merchant1Transactions.Sum(p => p.TransactionAmount)); } - [Fact(Skip = "")] + [Fact(Skip = "A")] public async Task FactTransactionsController_GetTopBottoMerchantsByValue_TopMerchants_MerchantsReturned() { EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); From 34c45e338044ba9dcedc00d8b0e65df29ba0f550 Mon Sep 17 00:00:00 2001 From: Stuart Ferguson Date: Sat, 7 Oct 2023 09:48:37 +0100 Subject: [PATCH 06/12] added more debug --- .../FactTransactionsControllerTests.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs b/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs index cd5c2a0..6468d8f 100644 --- a/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs +++ b/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs @@ -64,6 +64,7 @@ public async Task FactTransactionsControllerController_TodaysSalesCountByHour_Sa } Console.WriteLine($"Today: Added Hour {hour} Sales Value {localList.Sum(t => t.TransactionAmount)}"); + Console.WriteLine($"Today: Added Hour {hour} Sales Count {localList.Count}"); todaysTransactions.AddRange(localList); } @@ -79,6 +80,7 @@ public async Task FactTransactionsControllerController_TodaysSalesCountByHour_Sa } Console.WriteLine($"Comparison: Added Hour {hour} Sales Value {localList.Sum(t => t.TransactionAmount)}"); + Console.WriteLine($"Comparison: Added Hour {hour} Sales Count {localList.Count}"); comparisonDateTransactions.AddRange(localList); } @@ -86,8 +88,9 @@ public async Task FactTransactionsControllerController_TodaysSalesCountByHour_Sa response.IsSuccessStatusCode.ShouldBeTrue(); String content = await response.Content.ReadAsStringAsync(CancellationToken.None); + Console.WriteLine(content); List? todaysSalesCountByHour = JsonConvert.DeserializeObject>(content); - + foreach (TodaysSalesCountByHour salesCountByHour in todaysSalesCountByHour){ var todayHour = todaysTransactions.Where(t => t.TransactionDateTime.Hour == salesCountByHour.Hour); var comparisonHour = todaysTransactions.Where(t => t.TransactionDateTime.Hour == salesCountByHour.Hour); From 06b4f006496ac1e91ff45d1c4d9755dcf8bda2a6 Mon Sep 17 00:00:00 2001 From: Stuart Ferguson Date: Sat, 7 Oct 2023 09:55:52 +0100 Subject: [PATCH 07/12] :| --- EstateReportingAPI.IntegrationTests/DatabaseHelper.cs | 1 + .../FactTransactionsControllerTests.cs | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/EstateReportingAPI.IntegrationTests/DatabaseHelper.cs b/EstateReportingAPI.IntegrationTests/DatabaseHelper.cs index 63428de..a97bf8d 100644 --- a/EstateReportingAPI.IntegrationTests/DatabaseHelper.cs +++ b/EstateReportingAPI.IntegrationTests/DatabaseHelper.cs @@ -83,6 +83,7 @@ public async Task AddSettlementRecordWithFees(DateTime dateTime, Int32 estateRep public async Task AddTransaction(DateTime dateTime, Int32 merchantReportingId,String operatorIdentifier, Int32 contractProductReportingId, String responseCode, Decimal transactionAmount){ + Console.WriteLine($"TransactionDate {dateTime:yyyy-MM-dd HH:mm}"); Transaction transaction = new Transaction{ MerchantReportingId = merchantReportingId, TransactionDate = dateTime.Date, diff --git a/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs b/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs index 6468d8f..488153f 100644 --- a/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs +++ b/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs @@ -63,8 +63,8 @@ public async Task FactTransactionsControllerController_TodaysSalesCountByHour_Sa localList.Add(transaction); } - Console.WriteLine($"Today: Added Hour {hour} Sales Value {localList.Sum(t => t.TransactionAmount)}"); - Console.WriteLine($"Today: Added Hour {hour} Sales Count {localList.Count}"); + //Console.WriteLine($"Today: Added Hour {hour} Sales Value {localList.Sum(t => t.TransactionAmount)}"); + //Console.WriteLine($"Today: Added Hour {hour} Sales Count {localList.Count}"); todaysTransactions.AddRange(localList); } @@ -79,8 +79,8 @@ public async Task FactTransactionsControllerController_TodaysSalesCountByHour_Sa localList.Add(transaction); } - Console.WriteLine($"Comparison: Added Hour {hour} Sales Value {localList.Sum(t => t.TransactionAmount)}"); - Console.WriteLine($"Comparison: Added Hour {hour} Sales Count {localList.Count}"); + //Console.WriteLine($"Comparison: Added Hour {hour} Sales Value {localList.Sum(t => t.TransactionAmount)}"); + //Console.WriteLine($"Comparison: Added Hour {hour} Sales Count {localList.Count}"); comparisonDateTransactions.AddRange(localList); } From 1bf15780eac7999655b7ee2e4d9ff1266bc543c8 Mon Sep 17 00:00:00 2001 From: Stuart Ferguson Date: Sat, 7 Oct 2023 12:35:59 +0100 Subject: [PATCH 08/12] Fix failing test --- .../DatabaseHelper.cs | 1 - .../DimensionControllerTests.cs | 10 +++--- .../FactSettlementsControllerTests.cs | 2 +- .../FactTransactionsControllerTests.cs | 31 ++++++++----------- 4 files changed, 19 insertions(+), 25 deletions(-) diff --git a/EstateReportingAPI.IntegrationTests/DatabaseHelper.cs b/EstateReportingAPI.IntegrationTests/DatabaseHelper.cs index a97bf8d..63428de 100644 --- a/EstateReportingAPI.IntegrationTests/DatabaseHelper.cs +++ b/EstateReportingAPI.IntegrationTests/DatabaseHelper.cs @@ -83,7 +83,6 @@ public async Task AddSettlementRecordWithFees(DateTime dateTime, Int32 estateRep public async Task AddTransaction(DateTime dateTime, Int32 merchantReportingId,String operatorIdentifier, Int32 contractProductReportingId, String responseCode, Decimal transactionAmount){ - Console.WriteLine($"TransactionDate {dateTime:yyyy-MM-dd HH:mm}"); Transaction transaction = new Transaction{ MerchantReportingId = merchantReportingId, TransactionDate = dateTime.Date, diff --git a/EstateReportingAPI.IntegrationTests/DimensionControllerTests.cs b/EstateReportingAPI.IntegrationTests/DimensionControllerTests.cs index efd9e9c..20652f3 100644 --- a/EstateReportingAPI.IntegrationTests/DimensionControllerTests.cs +++ b/EstateReportingAPI.IntegrationTests/DimensionControllerTests.cs @@ -11,7 +11,7 @@ public class DimensionsControllerTests :ControllerTestsBase, IDisposable{ #region Methods - [Fact(Skip = "A")] + [Fact] public async Task DimensionsController_GetCalendarYears_NoDataInDatabase(){ HttpResponseMessage response = await this.CreateAndSendHttpRequestMessage("api/dimensions/calendar/years"); @@ -21,7 +21,7 @@ public async Task DimensionsController_GetCalendarYears_NoDataInDatabase(){ years.Count.ShouldBe(0); } - [Fact(Skip = "A")] + [Fact] public async Task DimensionsController_GetCalendarYears_YearsReturned(){ EstateManagementGenericContext context = new EstateManagementSqlServerContext(GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -45,7 +45,7 @@ public async Task DimensionsController_GetCalendarYears_YearsReturned(){ years.Count.ShouldBe(yearList.Count); } - [Fact(Skip = "A")] + [Fact] public async Task DimensionsController_GetCalendarComparisonDates_DatesReturned(){ EstateManagementGenericContext context = new EstateManagementSqlServerContext(GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -72,7 +72,7 @@ public async Task DimensionsController_GetCalendarComparisonDates_DatesReturned( dates.Select(d => d.Description).Contains("Last Month"); } - [Fact(Skip = "A")] + [Fact] public async Task DimensionsController_GetCalendarDates_DatesReturned(){ EstateManagementGenericContext context = new EstateManagementSqlServerContext(GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -94,7 +94,7 @@ public async Task DimensionsController_GetCalendarDates_DatesReturned(){ } } - [Fact(Skip = "A")] + [Fact] public async Task DimensionsController_GetCalendarDates_NoDataInDatabase(){ HttpResponseMessage response = await this.CreateAndSendHttpRequestMessage("api/dimensions/calendar/2023/dates"); diff --git a/EstateReportingAPI.IntegrationTests/FactSettlementsControllerTests.cs b/EstateReportingAPI.IntegrationTests/FactSettlementsControllerTests.cs index d018ea8..1eeea39 100644 --- a/EstateReportingAPI.IntegrationTests/FactSettlementsControllerTests.cs +++ b/EstateReportingAPI.IntegrationTests/FactSettlementsControllerTests.cs @@ -18,7 +18,7 @@ public void Dispose() result.ShouldBeTrue(); } - [Fact(Skip = "A")] + [Fact] public async Task FactSettlementsController_TodaysSettlement_SettlementReturned(){ EstateManagementGenericContext context = new EstateManagementSqlServerContext(GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); diff --git a/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs b/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs index 488153f..7a29bb7 100644 --- a/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs +++ b/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs @@ -8,7 +8,7 @@ using Xunit; public class FactTransactionsControllerTests : ControllerTestsBase, IDisposable{ - [Fact(Skip = "A")] + [Fact] public async Task FactTransactionsControllerController_TodaysSales_SalesReturned(){ EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); var todaysTransactions = new List(); @@ -62,9 +62,6 @@ public async Task FactTransactionsControllerController_TodaysSalesCountByHour_Sa Transaction transaction = await helper.AddTransaction(date, 1, "Safaricom", 1, "0000", amount); localList.Add(transaction); } - - //Console.WriteLine($"Today: Added Hour {hour} Sales Value {localList.Sum(t => t.TransactionAmount)}"); - //Console.WriteLine($"Today: Added Hour {hour} Sales Count {localList.Count}"); todaysTransactions.AddRange(localList); } @@ -75,12 +72,10 @@ public async Task FactTransactionsControllerController_TodaysSalesCountByHour_Sa for (int i = 0; i < 21; i++){ Decimal amount = 100 + i; - Transaction transaction = await helper.AddTransaction(comparisonDate, 1, "Safaricom", 1, "0000", amount); + Transaction transaction = await helper.AddTransaction(date, 1, "Safaricom", 1, "0000", amount); localList.Add(transaction); } - //Console.WriteLine($"Comparison: Added Hour {hour} Sales Value {localList.Sum(t => t.TransactionAmount)}"); - //Console.WriteLine($"Comparison: Added Hour {hour} Sales Count {localList.Count}"); comparisonDateTransactions.AddRange(localList); } @@ -88,18 +83,18 @@ public async Task FactTransactionsControllerController_TodaysSalesCountByHour_Sa response.IsSuccessStatusCode.ShouldBeTrue(); String content = await response.Content.ReadAsStringAsync(CancellationToken.None); - Console.WriteLine(content); + List? todaysSalesCountByHour = JsonConvert.DeserializeObject>(content); foreach (TodaysSalesCountByHour salesCountByHour in todaysSalesCountByHour){ var todayHour = todaysTransactions.Where(t => t.TransactionDateTime.Hour == salesCountByHour.Hour); - var comparisonHour = todaysTransactions.Where(t => t.TransactionDateTime.Hour == salesCountByHour.Hour); + var comparisonHour = comparisonDateTransactions.Where(t => t.TransactionDateTime.Hour == salesCountByHour.Hour); salesCountByHour.ComparisonSalesCount.ShouldBe(comparisonHour.Count()); salesCountByHour.TodaysSalesCount.ShouldBe(todayHour.Count()); } } - [Fact(Skip = "A")] + [Fact] public async Task FactTransactionsControllerController_TodaysSalesValueByHour_SalesReturned() { EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -148,7 +143,7 @@ public async Task FactTransactionsControllerController_TodaysSalesValueByHour_Sa } } - [Fact(Skip = "A")] + [Fact] public async Task FactTransactionsControllerController_TodaysFailedSales_SalesReturned() { EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -185,7 +180,7 @@ public async Task FactTransactionsControllerController_TodaysFailedSales_SalesRe todaysSales.ComparisonSalesValue.ShouldBe(comparisonDateTransactions.Sum(c => c.TransactionAmount)); } - [Fact(Skip = "A")] + [Fact] public async Task FactTransactionsControllerController_GetMerchantsTransactionKpis_SalesReturned() { EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -228,7 +223,7 @@ public async Task FactTransactionsControllerController_GetMerchantsTransactionKp merchantKpi.MerchantsWithNoSaleInLast7Days.ShouldBe(8); } - [Fact(Skip = "A")] + [Fact] public async Task FactTransactionsController_GetTopBottomProductsByValue_BottomProducts_ProductsReturned(){ EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -289,7 +284,7 @@ public async Task FactTransactionsController_GetTopBottomProductsByValue_BottomP topBottomProductData[2].SalesValue.ShouldBe(product1Transactions.Sum(p => p.TransactionAmount)); } - [Fact(Skip = "A")] + [Fact] public async Task FactTransactionsController_GetTopBottomProductsByValue_Top_ProductsReturned() { EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -351,7 +346,7 @@ public async Task FactTransactionsController_GetTopBottomProductsByValue_Top_Pro topBottomProductData[2].SalesValue.ShouldBe(product2Transactions.Sum(p => p.TransactionAmount)); } - [Fact(Skip = "A")] + [Fact] public async Task FactTransactionsController_GetTopBottomOperatorsByValue_BottomOperators_OperatorsReturned() { EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -414,7 +409,7 @@ public async Task FactTransactionsController_GetTopBottomOperatorsByValue_Bottom topBottomOperatorData[2].SalesValue.ShouldBe(operator1Transactions.Sum(p => p.TransactionAmount)); } - [Fact(Skip = "A")] + [Fact] public async Task FactTransactionsController_GetTopBottomOperatorsByValue_TopOperators_OperatorsReturned() { EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -477,7 +472,7 @@ public async Task FactTransactionsController_GetTopBottomOperatorsByValue_TopOpe topBottomOperatorData[2].SalesValue.ShouldBe(operator2Transactions.Sum(p => p.TransactionAmount)); } - [Fact(Skip = "A")] + [Fact] public async Task FactTransactionsController_GetTopBottoMerchantsByValue_BottomMerchants_MerchantsReturned() { EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); @@ -540,7 +535,7 @@ public async Task FactTransactionsController_GetTopBottoMerchantsByValue_BottomM topBottomMerchantData[2].SalesValue.ShouldBe(merchant1Transactions.Sum(p => p.TransactionAmount)); } - [Fact(Skip = "A")] + [Fact] public async Task FactTransactionsController_GetTopBottoMerchantsByValue_TopMerchants_MerchantsReturned() { EstateManagementGenericContext context = new EstateManagementSqlServerContext(ControllerTestsBase.GetLocalConnectionString($"EstateReportingReadModel{this.TestId.ToString()}")); From f30842f9757c12b0c61593804f87b5b61a45714a Mon Sep 17 00:00:00 2001 From: Stuart Ferguson Date: Sat, 7 Oct 2023 14:14:45 +0100 Subject: [PATCH 09/12] .. --- EstateReportingAPI.IntegrationTests/ControllerTestsBase.cs | 4 +++- .../FactTransactionsControllerTests.cs | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/EstateReportingAPI.IntegrationTests/ControllerTestsBase.cs b/EstateReportingAPI.IntegrationTests/ControllerTestsBase.cs index 56845dc..53aa2be 100644 --- a/EstateReportingAPI.IntegrationTests/ControllerTestsBase.cs +++ b/EstateReportingAPI.IntegrationTests/ControllerTestsBase.cs @@ -56,6 +56,8 @@ internal void StartSqlContainer(){ dockerHelper.SqlServerContainerName = "sharedsqlserver"; DatabaseServerNetwork = dockerHelper.SetupTestNetwork("sharednetwork", true); - DatabaseServerContainer = dockerHelper.SetupSqlServerContainer(DatabaseServerNetwork); + Retry.For(async () => { + DatabaseServerContainer = dockerHelper.SetupSqlServerContainer(DatabaseServerNetwork); + }); } } \ No newline at end of file diff --git a/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs b/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs index 7a29bb7..27b4bc9 100644 --- a/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs +++ b/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs @@ -4,6 +4,7 @@ using EstateManagement.Database.Contexts; using EstateManagement.Database.Entities; using Newtonsoft.Json; +using Shared.IntegrationTesting; using Shouldly; using Xunit; From 9b8fa3049175a219bb38e9953f1de59f38c4f388 Mon Sep 17 00:00:00 2001 From: Stuart Ferguson Date: Sat, 7 Oct 2023 15:15:48 +0100 Subject: [PATCH 10/12] ... --- .../EstateReportingAPI.IntegrationTests.csproj | 6 ++++++ EstateReportingAPI.IntegrationTests/xunit.runner.json | 3 +++ 2 files changed, 9 insertions(+) create mode 100644 EstateReportingAPI.IntegrationTests/xunit.runner.json diff --git a/EstateReportingAPI.IntegrationTests/EstateReportingAPI.IntegrationTests.csproj b/EstateReportingAPI.IntegrationTests/EstateReportingAPI.IntegrationTests.csproj index 00d47c2..cf124a8 100644 --- a/EstateReportingAPI.IntegrationTests/EstateReportingAPI.IntegrationTests.csproj +++ b/EstateReportingAPI.IntegrationTests/EstateReportingAPI.IntegrationTests.csproj @@ -36,4 +36,10 @@ + + + Always + + + diff --git a/EstateReportingAPI.IntegrationTests/xunit.runner.json b/EstateReportingAPI.IntegrationTests/xunit.runner.json new file mode 100644 index 0000000..1a74a1d --- /dev/null +++ b/EstateReportingAPI.IntegrationTests/xunit.runner.json @@ -0,0 +1,3 @@ +{ + "maxParallelThreads": 1 +} \ No newline at end of file From a7805158311e5acdf70e0d8dc599aa132a7bb5bb Mon Sep 17 00:00:00 2001 From: Stuart Ferguson Date: Sat, 7 Oct 2023 15:20:24 +0100 Subject: [PATCH 11/12] :| --- .../FactTransactionsControllerTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs b/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs index 27b4bc9..22ce57c 100644 --- a/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs +++ b/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs @@ -124,7 +124,7 @@ public async Task FactTransactionsControllerController_TodaysSalesValueByHour_Sa { Decimal amount = 100 + i; - Transaction transaction = await helper.AddTransaction(comparisonDate, 1, "Safaricom", 1, "0000", amount); + Transaction transaction = await helper.AddTransaction(date, 1, "Safaricom", 1, "0000", amount); comparisonDateTransactions.Add(transaction); } } @@ -138,7 +138,7 @@ public async Task FactTransactionsControllerController_TodaysSalesValueByHour_Sa foreach (TodaysSalesValueByHour salesValueByHour in todaysSalesValueByHour) { var todayHour = todaysTransactions.Where(t => t.TransactionDateTime.Hour == salesValueByHour.Hour); - var comparisonHour = todaysTransactions.Where(t => t.TransactionDateTime.Hour == salesValueByHour.Hour); + var comparisonHour = comparisonDateTransactions.Where(t => t.TransactionDateTime.Hour == salesValueByHour.Hour); salesValueByHour.ComparisonSalesValue.ShouldBe(comparisonHour.Sum(c => c.TransactionAmount)); salesValueByHour.ComparisonSalesValue.ShouldBe(todayHour.Sum(c => c.TransactionAmount)); } From 7944c7a5d0d8ab4c0ec3d3aa8167c62d487b9cdb Mon Sep 17 00:00:00 2001 From: Stuart Ferguson Date: Sat, 7 Oct 2023 15:31:34 +0100 Subject: [PATCH 12/12] fixed failing test --- .../FactTransactionsControllerTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs b/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs index 22ce57c..036035c 100644 --- a/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs +++ b/EstateReportingAPI.IntegrationTests/FactTransactionsControllerTests.cs @@ -140,7 +140,7 @@ public async Task FactTransactionsControllerController_TodaysSalesValueByHour_Sa var todayHour = todaysTransactions.Where(t => t.TransactionDateTime.Hour == salesValueByHour.Hour); var comparisonHour = comparisonDateTransactions.Where(t => t.TransactionDateTime.Hour == salesValueByHour.Hour); salesValueByHour.ComparisonSalesValue.ShouldBe(comparisonHour.Sum(c => c.TransactionAmount)); - salesValueByHour.ComparisonSalesValue.ShouldBe(todayHour.Sum(c => c.TransactionAmount)); + salesValueByHour.TodaysSalesValue.ShouldBe(todayHour.Sum(c => c.TransactionAmount)); } }