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 PCRBFollowUpCommentTests { private readonly Mock _mockCache; private readonly Mock _mockHttpClientFactory; private readonly Mock _mockSnackbar; private readonly Mock _mockUserService; private readonly PCRBService _pcrbService; private static PCRBFollowUpComment FOLLOW_UP_COMMENT = new PCRBFollowUpComment { ID = 1, PlanNumber = 123, FollowUpID = 1, Comment = "Test Comment", UserID = 1 }; private static HttpResponseMessage GET_RESPONSE = new HttpResponseMessage { StatusCode = HttpStatusCode.OK, Content = new StringContent(JsonSerializer.Serialize(new List { FOLLOW_UP_COMMENT })) }; private static IEnumerable FOLLOW_UPS_COMMENTS = new List() { FOLLOW_UP_COMMENT }; private static HttpResponseMessage SUCCESSFUL_RESPONSE = new HttpResponseMessage(HttpStatusCode.OK); private static HttpResponseMessage UNSUCCESSFUL_RESPONSE = new HttpResponseMessage(HttpStatusCode.InternalServerError); public PCRBFollowUpCommentTests() { _mockCache = MockMemoryCacheService.GetMemoryCache(FOLLOW_UPS_COMMENTS); _mockHttpClientFactory = new Mock(); _mockSnackbar = new Mock(); _mockUserService = new Mock(); _pcrbService = new PCRBService( _mockCache.Object, _mockHttpClientFactory.Object, _mockSnackbar.Object, _mockUserService.Object); } [Fact] public async Task CreateFollowUpComment_WithValidParams_ShouldCallHttpPost_AndRefreshCache() { Mock 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(GET_RESPONSE) .Verifiable(); HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) { BaseAddress = new Uri("https://localhost:5000") }; _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny())).Returns(httpClient); await _pcrbService.CreateFollowUpComment(FOLLOW_UP_COMMENT); mockHttpMessageHandler.Protected().Verify( "SendAsync", Times.Once(), ItExpr.Is( req => req.Method == HttpMethod.Post && req.RequestUri != null && req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUpComment")), 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/followUpComments?planNumber=123&bypassCache=True")), ItExpr.IsAny()); } [Fact] public async Task CreateFollowUpComment_WithBadResponse_ShouldThrowException() { Mock mockHttpMessageHandler = new Mock(); mockHttpMessageHandler.Protected() .Setup>( "SendAsync", ItExpr.Is(_ => _.Method == HttpMethod.Post), ItExpr.IsAny()) .ReturnsAsync(UNSUCCESSFUL_RESPONSE) .Verifiable(); HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) { BaseAddress = new Uri("https://localhost:5000") }; _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny())).Returns(httpClient); await Assert.ThrowsAsync(() => _pcrbService.CreateFollowUpComment(FOLLOW_UP_COMMENT)); } [Fact] public async Task CreateFollowUpComment_WithNullParam_ShouldThrowException() { await Assert.ThrowsAsync(() => _pcrbService.CreateFollowUpComment(null)); } [Fact] public async Task GetFollowUpCommentsByPlanNumber_WithBypassCache_ShouldCallHttpGetAndReturnFollowUps() { Mock mockHttpMessageHandler = new Mock(); mockHttpMessageHandler.Protected() .Setup>( "SendAsync", ItExpr.Is(_ => _.Method == HttpMethod.Get), ItExpr.IsAny()) .ReturnsAsync(GET_RESPONSE) .Verifiable(); HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) { BaseAddress = new Uri("https://localhost:5000") }; _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny())).Returns(httpClient); IEnumerable comments = await _pcrbService.GetFollowUpCommentsByPlanNumber(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/followUpComments?planNumber=123&bypassCache=True")), ItExpr.IsAny()); Assert.Single(comments); } [Fact] public async Task GetFollowUpCommentsByPlanNumber_WithoutBypassCache_ShouldReturnFollowUpsFromCache() { IEnumerable comments = await _pcrbService.GetFollowUpCommentsByPlanNumber(1, false); Assert.Single(comments); } [Fact] public async Task GetFollowUpCommentsByPlanNumber_WithBadResponse_ShouldThrowException() { Mock mockHttpMessageHandler = new Mock(); mockHttpMessageHandler.Protected() .Setup>( "SendAsync", ItExpr.Is(_ => _.Method == HttpMethod.Get), ItExpr.IsAny()) .ReturnsAsync(UNSUCCESSFUL_RESPONSE) .Verifiable(); HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) { BaseAddress = new Uri("https://localhost:5000") }; _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny())).Returns(httpClient); await Assert.ThrowsAsync(() => _pcrbService.GetFollowUpCommentsByPlanNumber(1, true)); } [Fact] public async Task UpdateFollowUpComment_WithValidParams_ShouldCallHttpPut() { Mock mockHttpMessageHandler = new Mock(); mockHttpMessageHandler.Protected() .Setup>( "SendAsync", ItExpr.Is(_ => _.Method == HttpMethod.Put), ItExpr.IsAny()) .ReturnsAsync(SUCCESSFUL_RESPONSE) .Verifiable(); mockHttpMessageHandler.Protected() .Setup>( "SendAsync", ItExpr.Is(_ => _.Method == HttpMethod.Get), ItExpr.IsAny()) .ReturnsAsync(GET_RESPONSE) .Verifiable(); HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) { BaseAddress = new Uri("https://localhost:5000") }; _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny())).Returns(httpClient); await _pcrbService.UpdateFollowUpComment(FOLLOW_UP_COMMENT); mockHttpMessageHandler.Protected().Verify( "SendAsync", Times.Once(), ItExpr.Is( req => req.Method == HttpMethod.Put && req.RequestUri != null && req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUpComment")), 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/followUpComments?planNumber=123&bypassCache=True")), ItExpr.IsAny()); } [Fact] public async Task UpdateFollowUpComment_WithNullParam_ShouldThrowException() { await Assert.ThrowsAsync(() => _pcrbService.UpdateFollowUpComment(null)); } [Fact] public async Task UpdateFollowUpComment_WithBadResponse_ShouldThrowException() { Mock mockHttpMessageHandler = new Mock(); mockHttpMessageHandler.Protected() .Setup>( "SendAsync", ItExpr.Is(_ => _.Method == HttpMethod.Put), ItExpr.IsAny()) .ReturnsAsync(UNSUCCESSFUL_RESPONSE) .Verifiable(); HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) { BaseAddress = new Uri("https://localhost:5000") }; _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny())).Returns(httpClient); await Assert.ThrowsAsync(() => _pcrbService.UpdateFollowUpComment(FOLLOW_UP_COMMENT)); } [Fact] public async Task DeleteFollowUpComment_WithValidParams_ShouldCallHttpDelete() { Mock mockHttpMessageHandler = new Mock(); mockHttpMessageHandler.Protected() .Setup>( "SendAsync", ItExpr.Is(_ => _.Method == HttpMethod.Delete), ItExpr.IsAny()) .ReturnsAsync(SUCCESSFUL_RESPONSE) .Verifiable(); HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) { BaseAddress = new Uri("https://localhost:5000") }; _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny())).Returns(httpClient); await _pcrbService.DeleteFollowUpComment(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/followUpComment?id=1")), ItExpr.IsAny()); } [Fact] public async Task DeleteFollowUpComment_WithBadId_ShouldThrowException() { await Assert.ThrowsAsync(() => _pcrbService.DeleteFollowUpComment(0)); } [Fact] public async Task DeleteFollowUpComment_WithBadResponse_ShouldThrowException() { Mock mockHttpMessageHandler = new Mock(); mockHttpMessageHandler.Protected() .Setup>( "SendAsync", ItExpr.Is(_ => _.Method == HttpMethod.Delete), ItExpr.IsAny()) .ReturnsAsync(UNSUCCESSFUL_RESPONSE) .Verifiable(); HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) { BaseAddress = new Uri("https://localhost:5000") }; _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny())).Returns(httpClient); await Assert.ThrowsAsync(() => _pcrbService.DeleteFollowUpComment(1)); } }