Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,93 @@ public async Task GetTransactionMixSummaryQuery_ReturnsRequestedBreakdown()
It.IsAny<CancellationToken>()),
Times.Once);
}

[Fact]
public async Task GetRecentActivityReceiptReportQuery_ReturnsMockedResultsForOneDate()
{
Mock<IReportsService> reportsService = new();
Mock<IApplicationCache> applicationCache = new();
MerchantDetailsModel merchantDetails = new()
{
MerchantReportingId = 12345
};

DateTime reportDate = new(2026, 7, 6);

applicationCache.Setup(a => a.GetMerchantDetails()).Returns(merchantDetails);
reportsService.Setup(r => r.GetRecentActivityReceiptReport(
merchantDetails.MerchantReportingId,
reportDate,
"TXN-10001",
1,
5,
It.IsAny<CancellationToken>()))
.ReturnsAsync(Result.Success(RecentActivityReceiptReportModel.CreateMock(reportDate, "TXN-10001")));

ReportRequestHandler handler = new(reportsService.Object, applicationCache.Object);

Result<RecentActivityReceiptReportModel> result = await handler.Handle(
new ReportQueries.GetRecentActivityReceiptReportQuery(
ReportDate: reportDate,
SearchText: "TXN-10001",
PageNumber: 1,
PageSize: 5),
CancellationToken.None);

result.IsSuccess.ShouldBeTrue();
result.Data.ReportDate.ShouldBe(reportDate);
result.Data.Items.ShouldNotBeEmpty();
result.Data.Items.All(item => item.TransactionDateTime.Date == reportDate).ShouldBeTrue();
reportsService.Verify(r => r.GetRecentActivityReceiptReport(
merchantDetails.MerchantReportingId,
reportDate,
"TXN-10001",
1,
5,
It.IsAny<CancellationToken>()),
Times.Once);
}

[Fact]
public async Task GetRecentActivityReceiptReportQuery_PassesPagingToService()
{
Mock<IReportsService> reportsService = new();
Mock<IApplicationCache> applicationCache = new();
MerchantDetailsModel merchantDetails = new()
{
MerchantReportingId = 12345
};

DateTime reportDate = new(2026, 7, 6);

applicationCache.Setup(a => a.GetMerchantDetails()).Returns(merchantDetails);
reportsService.Setup(r => r.GetRecentActivityReceiptReport(
merchantDetails.MerchantReportingId,
reportDate,
null,
2,
5,
It.IsAny<CancellationToken>()))
.ReturnsAsync(Result.Success(RecentActivityReceiptReportModel.CreateMock(reportDate, null)));

ReportRequestHandler handler = new(reportsService.Object, applicationCache.Object);

Result<RecentActivityReceiptReportModel> result = await handler.Handle(
new ReportQueries.GetRecentActivityReceiptReportQuery(
ReportDate: reportDate,
SearchText: null,
PageNumber: 2,
PageSize: 5),
CancellationToken.None);

result.IsSuccess.ShouldBeTrue();
reportsService.Verify(r => r.GetRecentActivityReceiptReport(
merchantDetails.MerchantReportingId,
reportDate,
null,
2,
5,
It.IsAny<CancellationToken>()),
Times.Once);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,176 @@ public async Task GetTransactionMixSummary_SendsRequestAndMapsResponse()
requestPayload.ShouldContain("\"merchant_reporting_id\": 12345");
requestPayload.ShouldContain("\"top_n\": 5");
}

[Fact]
public async Task GetRecentActivityReceiptReport_SendsRequestAndMapsResponse()
{
RecentActivityReceiptSearchResponseDto response = new()
{
ReportDate = new DateTime(2026, 7, 6),
PageNumber = 1,
PageSize = 5,
TotalCount = 2,
Items =
[
new RecentActivityReceiptSearchItemDto
{
Reference = "TXN-10002",
TransactionType = "Bill Payment",
Product = "Bill Pay (Post)",
Operator = "PataPawa PostPay",
Status = "Success",
Amount = 250.00m,
TransactionDateTime = new DateTime(2026, 7, 6, 10, 15, 0),
ReceiptReference = "RCPT-10002"
},
new RecentActivityReceiptSearchItemDto
{
Reference = "TXN-10001",
TransactionType = "Mobile Topup",
Product = "Custom",
Operator = "Safaricom",
Status = "Success",
Amount = 100.00m,
TransactionDateTime = new DateTime(2026, 7, 6, 9, 30, 0),
ReceiptReference = "RCPT-10001"
}
]
};

String requestPayload = string.Empty;
this.MockHttpMessageHandler.When(HttpMethod.Post, "http://localhost/api/reporting/recentactivityreceiptsearch")
.Respond(req =>
{
requestPayload = req.Content!.ReadAsStringAsync().GetAwaiter().GetResult();
return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(StringSerialiser.Serialise(response), Encoding.UTF8, "application/json")
};
});

Result<RecentActivityReceiptReportModel> result = await this.ReportsService.GetRecentActivityReceiptReport(12345,
new DateTime(2026, 7, 6),
"TXN-10001",
1,
5,
CancellationToken.None);

result.IsSuccess.ShouldBeTrue();
result.Data.ReportDate.ShouldBe(new DateTime(2026, 7, 6));
result.Data.Items.Count.ShouldBe(2);
result.Data.Items[0].Reference.ShouldBe("TXN-10002");
result.Data.Items[1].Reference.ShouldBe("TXN-10001");
result.Data.PageNumber.ShouldBe(1);
result.Data.PageSize.ShouldBe(5);
result.Data.TotalCount.ShouldBe(2);
requestPayload.ShouldContain("\"application_version\": \"1.2.3\"");
requestPayload.ShouldContain("\"merchant_reporting_id\": 12345");
requestPayload.ShouldContain("\"report_date\"");
requestPayload.ShouldContain("2026-07-06");
requestPayload.ShouldContain("\"search_text\": \"TXN-10001\"");
}

[Fact]
public async Task GetRecentActivityReceiptReport_ReturnsSecondPage()
{
RecentActivityReceiptSearchResponseDto response = new()
{
ReportDate = new DateTime(2026, 7, 6),
PageNumber = 2,
PageSize = 5,
TotalCount = 10,
Items =
[
new RecentActivityReceiptSearchItemDto
{
Reference = "TXN-10005",
TransactionType = "Bill Payment",
Product = "Prepaid Power",
Operator = "KPLC",
Status = "Failed",
Amount = 75.00m,
TransactionDateTime = new DateTime(2026, 7, 6, 13, 5, 0),
ReceiptReference = "RCPT-10005"
}
]
};

this.MockHttpMessageHandler.When(HttpMethod.Post, "http://localhost/api/reporting/recentactivityreceiptsearch")
.Respond(_ => new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(StringSerialiser.Serialise(response), Encoding.UTF8, "application/json")
});

Result<RecentActivityReceiptReportModel> result = await this.ReportsService.GetRecentActivityReceiptReport(12345,
new DateTime(2026, 7, 6),
null,
2,
5,
CancellationToken.None);

result.IsSuccess.ShouldBeTrue();
result.Data.PageNumber.ShouldBe(2);
result.Data.PageSize.ShouldBe(5);
result.Data.TotalCount.ShouldBe(10);
result.Data.Items.Count.ShouldBe(1);
}

[Fact]
public async Task ResendRecentActivityReceipt_SendsRequestAndMapsSuccessResponse()
{
RecentActivityReceiptResendResponseDto response = new()
{
Success = true,
Message = "Receipt resend requested.",
Reference = "TXN-10001",
ReceiptReference = "RCPT-10001",
TransactionReference = "TXN-10001"
};

String requestPayload = string.Empty;
this.MockHttpMessageHandler.When(HttpMethod.Post, "http://localhost/api/transactions/resendreceipt")
.Respond(req =>
{
requestPayload = req.Content!.ReadAsStringAsync().GetAwaiter().GetResult();
return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(StringSerialiser.Serialise(response), Encoding.UTF8, "application/json")
};
});

Result<RecentActivityReceiptResendResultModel> result = await this.ReportsService.ResendRecentActivityReceipt("TXN-10001",
"customer@example.com",
CancellationToken.None);

result.IsSuccess.ShouldBeTrue();
result.Data.Success.ShouldBeTrue();
result.Data.Message.ShouldBe("Receipt resend requested.");
result.Data.Reference.ShouldBe("TXN-10001");
requestPayload.ShouldContain("\"reference\": \"TXN-10001\"");
requestPayload.ShouldContain("\"recipient_email_address\": \"customer@example.com\"");
}

[Fact]
public async Task ResendRecentActivityReceipt_ReturnsFailureWhenApiRejectsRequest()
{
RecentActivityReceiptResendResponseDto response = new()
{
Success = false,
Message = "Recipient email address is not valid."
};

this.MockHttpMessageHandler.When(HttpMethod.Post, "http://localhost/api/transactions/resendreceipt")
.Respond(_ => new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(StringSerialiser.Serialise(response), Encoding.UTF8, "application/json")
});

Result<RecentActivityReceiptResendResultModel> result = await this.ReportsService.ResendRecentActivityReceipt("TXN-10001",
"invalid@example",
CancellationToken.None);

result.IsFailed.ShouldBeTrue();
result.Message.ShouldBe("Recipient email address is not valid.");
}
}
Loading
Loading