using Bit.Billing.Controllers; using Bit.Billing.Models; using Bit.Core.Entities; using Bit.Core.Repositories; using Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture.Attributes; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using NSubstitute; using Xunit; namespace Bit.Billing.Test.Controllers; [ControllerCustomize(typeof(FreshdeskController))] [SutProviderCustomize] public class FreshdeskControllerTests { private const string ApiKey = "TESTFRESHDESKAPIKEY"; private const string WebhookKey = "TESTKEY"; [Theory] [BitAutoData((string)null, null)] [BitAutoData((string)null)] [BitAutoData(WebhookKey, null)] public async Task PostWebhook_NullRequiredParameters_BadRequest(string freshdeskWebhookKey, FreshdeskWebhookModel model, BillingSettings billingSettings, SutProvider sutProvider) { sutProvider.GetDependency>().Value.FreshdeskWebhookKey.Returns(billingSettings.FreshdeskWebhookKey); var response = await sutProvider.Sut.PostWebhook(freshdeskWebhookKey, model); var statusCodeResult = Assert.IsAssignableFrom(response); Assert.Equal(StatusCodes.Status400BadRequest, statusCodeResult.StatusCode); } [Theory] [BitAutoData] public async Task PostWebhook_Success(User user, FreshdeskWebhookModel model, List organizations, SutProvider sutProvider) { model.TicketContactEmail = user.Email; sutProvider.GetDependency().GetByEmailAsync(user.Email).Returns(user); sutProvider.GetDependency().GetManyByUserIdAsync(user.Id).Returns(organizations); var mockHttpMessageHandler = Substitute.ForPartsOf(); var mockResponse = new HttpResponseMessage(System.Net.HttpStatusCode.OK); mockHttpMessageHandler.Send(Arg.Any(), Arg.Any()) .Returns(mockResponse); var httpClient = new HttpClient(mockHttpMessageHandler); sutProvider.GetDependency().CreateClient("FreshdeskApi").Returns(httpClient); sutProvider.GetDependency>().Value.FreshdeskWebhookKey.Returns(WebhookKey); sutProvider.GetDependency>().Value.FreshdeskApiKey.Returns(ApiKey); var response = await sutProvider.Sut.PostWebhook(WebhookKey, model); var statusCodeResult = Assert.IsAssignableFrom(response); Assert.Equal(StatusCodes.Status200OK, statusCodeResult.StatusCode); _ = mockHttpMessageHandler.Received(1).Send(Arg.Is(m => m.Method == HttpMethod.Put && m.RequestUri.ToString().EndsWith(model.TicketId)), Arg.Any()); _ = mockHttpMessageHandler.Received(1).Send(Arg.Is(m => m.Method == HttpMethod.Post && m.RequestUri.ToString().EndsWith($"{model.TicketId}/notes")), Arg.Any()); } public class MockHttpMessageHandler : HttpMessageHandler { protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { return Send(request, cancellationToken); } public virtual Task Send(HttpRequestMessage request, CancellationToken cancellationToken) { throw new NotImplementedException(); } } }