using System.Net; using System.Text.Json; using MesaFabApproval.Client.Services; using MesaFabApproval.Shared.Models; using Microsoft.Extensions.Caching.Memory; using Moq; using Moq.Protected; using MudBlazor; namespace MesaFabApproval.Client.Test; public class PCRBServiceTests { private readonly Mock _mockCache; private readonly Mock _mockHttpClientFactory; private readonly Mock _mockSnackbar; private readonly Mock _mockUserService; private readonly PCRBService _pcrbService; private static IEnumerable FOLLOW_UPS = new List() { new PCRBFollowUp { ID = 1, PlanNumber = 1, Step = 1, FollowUpDate = DateTime.Now } }; private static HttpResponseMessage SUCCESSFUL_RESPONSE = new HttpResponseMessage(HttpStatusCode.OK); private static HttpResponseMessage UNSUCCESSFUL_RESPONSE = new HttpResponseMessage(HttpStatusCode.InternalServerError); public static class MockMemoryCacheService { public static Mock GetMemoryCache(object expectedValue) { Mock mockMemoryCache = new Mock(); mockMemoryCache .Setup(x => x.TryGetValue(It.IsAny(), out expectedValue)) .Returns(true); mockMemoryCache .Setup(x => x.CreateEntry(It.IsAny())) .Returns(Mock.Of()); return mockMemoryCache; } } public PCRBServiceTests() { _mockCache = MockMemoryCacheService.GetMemoryCache(FOLLOW_UPS); _mockHttpClientFactory = new Mock(); _mockSnackbar = new Mock(); _mockUserService = new Mock(); _pcrbService = new PCRBService( _mockCache.Object, _mockHttpClientFactory.Object, _mockSnackbar.Object, _mockUserService.Object); } [Fact] public async Task CreateFollowUp_WithValidParams_ShouldCallHttpPost_AndRefreshCache() { PCRBFollowUp followUp = new PCRBFollowUp { ID = 1, PlanNumber = 123, Step = 1, FollowUpDate = DateTime.Now, Comments = "Test" }; HttpResponseMessage getResponse = new HttpResponseMessage { StatusCode = HttpStatusCode.OK, Content = new StringContent(JsonSerializer.Serialize(new List { followUp })) }; var mockHttpMessageHandler = new Mock(); mockHttpMessageHandler.Protected() .Setup>( "SendAsync", ItExpr.Is(_ => _.Method == HttpMethod.Post), ItExpr.IsAny()) .ReturnsAsync(SUCCESSFUL_RESPONSE) .Verifiable(); mockHttpMessageHandler.Protected() .Setup>( "SendAsync", ItExpr.Is(_ => _.Method == HttpMethod.Get), ItExpr.IsAny()) .ReturnsAsync(getResponse) .Verifiable(); var httpClient = new HttpClient(mockHttpMessageHandler.Object) { BaseAddress = new Uri("https://localhost:5000") }; _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny())).Returns(httpClient); await _pcrbService.CreateFollowUp(followUp); mockHttpMessageHandler.Protected().Verify( "SendAsync", Times.Once(), ItExpr.Is( req => req.Method == HttpMethod.Post && req.RequestUri != null && req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUp")), ItExpr.IsAny()); mockHttpMessageHandler.Protected().Verify( "SendAsync", Times.Once(), ItExpr.Is( req => req.Method == HttpMethod.Get && req.RequestUri != null && req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUps?planNumber=123&bypassCache=True")), ItExpr.IsAny()); } [Fact] public async Task CreateFollowUp_WithBadResponse_ShouldThrowException() { PCRBFollowUp followUp = new PCRBFollowUp { ID = 1, PlanNumber = 123, Step = 1, FollowUpDate = DateTime.Now, Comments = "Test" }; var mockHttpMessageHandler = new Mock(); mockHttpMessageHandler.Protected() .Setup>( "SendAsync", ItExpr.Is(_ => _.Method == HttpMethod.Post), ItExpr.IsAny()) .ReturnsAsync(UNSUCCESSFUL_RESPONSE) .Verifiable(); var httpClient = new HttpClient(mockHttpMessageHandler.Object) { BaseAddress = new Uri("https://localhost:5000") }; _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny())).Returns(httpClient); await Assert.ThrowsAsync(() => _pcrbService.CreateFollowUp(followUp)); } [Fact] public async Task CreateFollowUp_WithNullParam_ShouldThrowException() { await Assert.ThrowsAsync(() => _pcrbService.CreateFollowUp(null)); } [Fact] public async Task GetFollowUpsByPlanNumber_WithBypassCache_ShouldCallHttpGetAndReturnFollowUps() { PCRBFollowUp followUp = new PCRBFollowUp { ID = 1, PlanNumber = 123, Step = 1, FollowUpDate = DateTime.Now, Comments = "Test" }; HttpResponseMessage getResponse = new HttpResponseMessage { StatusCode = HttpStatusCode.OK, Content = new StringContent(JsonSerializer.Serialize(new List { followUp })) }; var mockHttpMessageHandler = new Mock(); mockHttpMessageHandler.Protected() .Setup>( "SendAsync", ItExpr.Is(_ => _.Method == HttpMethod.Get), ItExpr.IsAny()) .ReturnsAsync(getResponse) .Verifiable(); var httpClient = new HttpClient(mockHttpMessageHandler.Object) { BaseAddress = new Uri("https://localhost:5000") }; _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny())).Returns(httpClient); IEnumerable followUps = await _pcrbService.GetFollowUpsByPlanNumber(123, true); mockHttpMessageHandler.Protected().Verify( "SendAsync", Times.Once(), ItExpr.Is( req => req.Method == HttpMethod.Get && req.RequestUri != null && req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUps?planNumber=123&bypassCache=True")), ItExpr.IsAny()); Assert.Single(followUps); } [Fact] public async Task GetFollowUpsByPlanNumber_WithoutBypassCache_ShouldReturnFollowUpsFromCache() { IEnumerable followUps = await _pcrbService.GetFollowUpsByPlanNumber(1, false); Assert.Single(followUps); } [Fact] public async Task GetFollowUpsByPlanNumber_WithBadResponse_ShouldThrowException() { var mockHttpMessageHandler = new Mock(); mockHttpMessageHandler.Protected() .Setup>( "SendAsync", ItExpr.Is(_ => _.Method == HttpMethod.Get), ItExpr.IsAny()) .ReturnsAsync(UNSUCCESSFUL_RESPONSE) .Verifiable(); var httpClient = new HttpClient(mockHttpMessageHandler.Object) { BaseAddress = new Uri("https://localhost:5000") }; _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny())).Returns(httpClient); await Assert.ThrowsAsync(() => _pcrbService.GetFollowUpsByPlanNumber(1, true)); } [Fact] public async Task UpdateFollowUp_WithValidParams_ShouldCallHttpPut() { PCRBFollowUp followUp = new PCRBFollowUp { ID = 1, PlanNumber = 123, Step = 1, FollowUpDate = DateTime.Now, Comments = "Test" }; var mockHttpMessageHandler = new Mock(); mockHttpMessageHandler.Protected() .Setup>( "SendAsync", ItExpr.Is(_ => _.Method == HttpMethod.Put), ItExpr.IsAny()) .ReturnsAsync(SUCCESSFUL_RESPONSE) .Verifiable(); var httpClient = new HttpClient(mockHttpMessageHandler.Object) { BaseAddress = new Uri("https://localhost:5000") }; _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny())).Returns(httpClient); await _pcrbService.UpdateFollowUp(followUp); mockHttpMessageHandler.Protected().Verify( "SendAsync", Times.Once(), ItExpr.Is( req => req.Method == HttpMethod.Put && req.RequestUri != null && req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUp")), ItExpr.IsAny()); } [Fact] public async Task UpdateFollowUp_WithNullParam_ShouldThrowException() { await Assert.ThrowsAsync(() => _pcrbService.UpdateFollowUp(null)); } [Fact] public async Task UpdateFollowUp_WithBadResponse_ShouldThrowException() { PCRBFollowUp followUp = new PCRBFollowUp { ID = 1, PlanNumber = 123, Step = 1, FollowUpDate = DateTime.Now, Comments = "Test" }; var mockHttpMessageHandler = new Mock(); mockHttpMessageHandler.Protected() .Setup>( "SendAsync", ItExpr.Is(_ => _.Method == HttpMethod.Put), ItExpr.IsAny()) .ReturnsAsync(UNSUCCESSFUL_RESPONSE) .Verifiable(); var httpClient = new HttpClient(mockHttpMessageHandler.Object) { BaseAddress = new Uri("https://localhost:5000") }; _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny())).Returns(httpClient); await Assert.ThrowsAsync(() => _pcrbService.UpdateFollowUp(followUp)); } [Fact] public async Task DeleteFollowUp_WithValidParams_ShouldCallHttpDelete() { var mockHttpMessageHandler = new Mock(); mockHttpMessageHandler.Protected() .Setup>( "SendAsync", ItExpr.Is(_ => _.Method == HttpMethod.Delete), ItExpr.IsAny()) .ReturnsAsync(SUCCESSFUL_RESPONSE) .Verifiable(); var httpClient = new HttpClient(mockHttpMessageHandler.Object) { BaseAddress = new Uri("https://localhost:5000") }; _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny())).Returns(httpClient); await _pcrbService.DeleteFollowUp(1); mockHttpMessageHandler.Protected().Verify( "SendAsync", Times.Once(), ItExpr.Is( req => req.Method == HttpMethod.Delete && req.RequestUri != null && req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUp?id=1")), ItExpr.IsAny()); } [Fact] public async Task DeleteFollowUp_WithBadId_ShouldThrowException() { await Assert.ThrowsAsync(() => _pcrbService.DeleteFollowUp(0)); } [Fact] public async Task DeleteFollowUp_WithBadResponse_ShouldThrowException() { var mockHttpMessageHandler = new Mock(); mockHttpMessageHandler.Protected() .Setup>( "SendAsync", ItExpr.Is(_ => _.Method == HttpMethod.Delete), ItExpr.IsAny()) .ReturnsAsync(UNSUCCESSFUL_RESPONSE) .Verifiable(); var httpClient = new HttpClient(mockHttpMessageHandler.Object) { BaseAddress = new Uri("https://localhost:5000") }; _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny())).Returns(httpClient); await Assert.ThrowsAsync(() => _pcrbService.DeleteFollowUp(1)); } }