public async Task PostWebhook_Success(User user, FreshdeskWebhookModel model, List <Organization> organizations, SutProvider <FreshdeskController> sutProvider) { model.TicketContactEmail = user.Email; sutProvider.GetDependency <IUserRepository>().GetByEmailAsync(user.Email).Returns(user); sutProvider.GetDependency <IOrganizationRepository>().GetManyByUserIdAsync(user.Id).Returns(organizations); var mockHttpMessageHandler = Substitute.ForPartsOf <MockHttpMessageHandler>(); var mockResponse = new HttpResponseMessage(System.Net.HttpStatusCode.OK); mockHttpMessageHandler.Send(Arg.Any <HttpRequestMessage>(), Arg.Any <CancellationToken>()) .Returns(mockResponse); var httpClient = new HttpClient(mockHttpMessageHandler); sutProvider.GetDependency <IHttpClientFactory>().CreateClient("FreshdeskApi").Returns(httpClient); sutProvider.GetDependency <IOptions <BillingSettings> >().Value.FreshdeskWebhookKey.Returns(WebhookKey); sutProvider.GetDependency <IOptions <BillingSettings> >().Value.FreshdeskApiKey.Returns(ApiKey); var response = await sutProvider.Sut.PostWebhook(WebhookKey, model); var statusCodeResult = Assert.IsAssignableFrom <StatusCodeResult>(response); Assert.Equal(StatusCodes.Status200OK, statusCodeResult.StatusCode); _ = mockHttpMessageHandler.Received(1).Send(Arg.Is <HttpRequestMessage>(m => m.Method == HttpMethod.Put && m.RequestUri.ToString().EndsWith(model.TicketId)), Arg.Any <CancellationToken>()); _ = mockHttpMessageHandler.Received(1).Send(Arg.Is <HttpRequestMessage>(m => m.Method == HttpMethod.Post && m.RequestUri.ToString().EndsWith($"{model.TicketId}/notes")), Arg.Any <CancellationToken>()); }
public async Task PostWebhook_NullRequiredParameters_BadRequest(string freshdeskWebhookKey, FreshdeskWebhookModel model, BillingSettings billingSettings, SutProvider <FreshdeskController> sutProvider) { sutProvider.GetDependency <IOptions <BillingSettings> >().Value.FreshdeskWebhookKey.Returns(billingSettings.FreshdeskWebhookKey); var response = await sutProvider.Sut.PostWebhook(freshdeskWebhookKey, model); var statusCodeResult = Assert.IsAssignableFrom <StatusCodeResult>(response); Assert.Equal(StatusCodes.Status400BadRequest, statusCodeResult.StatusCode); }
public async Task <IActionResult> PostWebhook([FromQuery, Required] string key, [FromBody, Required] FreshdeskWebhookModel model) { if (string.IsNullOrWhiteSpace(key) || !CoreHelpers.FixedTimeEquals(key, _billingSettings.FreshdeskWebhookKey)) { return(new BadRequestResult()); } try { var ticketId = model.TicketId; var ticketContactEmail = model.TicketContactEmail; var ticketTags = model.TicketTags; if (string.IsNullOrWhiteSpace(ticketId) || string.IsNullOrWhiteSpace(ticketContactEmail)) { return(new BadRequestResult()); } var updateBody = new Dictionary <string, object>(); var note = string.Empty; var customFields = new Dictionary <string, object>(); var user = await _userRepository.GetByEmailAsync(ticketContactEmail); if (user != null) { var userLink = $"{_globalSettings.BaseServiceUri.Admin}/users/edit/{user.Id}"; note += $"<li>User, {user.Email}: {userLink}</li>"; customFields.Add("cf_user", userLink); var tags = new HashSet <string>(); if (user.Premium) { tags.Add("Premium"); } var orgs = await _organizationRepository.GetManyByUserIdAsync(user.Id); foreach (var org in orgs) { var orgNote = $"{org.Name} ({org.Seats.GetValueOrDefault()}): " + $"{_globalSettings.BaseServiceUri.Admin}/organizations/edit/{org.Id}"; note += $"<li>Org, {orgNote}</li>"; if (!customFields.Any(kvp => kvp.Key == "cf_org")) { customFields.Add("cf_org", orgNote); } else { customFields["cf_org"] += $"\n{orgNote}"; } var planName = GetAttribute <DisplayAttribute>(org.PlanType).Name.Split(" ").FirstOrDefault(); if (!string.IsNullOrWhiteSpace(planName)) { tags.Add(string.Format("Org: {0}", planName)); } } if (tags.Any()) { var tagsToUpdate = tags.ToList(); if (!string.IsNullOrWhiteSpace(ticketTags)) { var splitTicketTags = ticketTags.Split(','); for (var i = 0; i < splitTicketTags.Length; i++) { tagsToUpdate.Insert(i, splitTicketTags[i]); } } updateBody.Add("tags", tagsToUpdate); } if (customFields.Any()) { updateBody.Add("custom_fields", customFields); } var updateRequest = new HttpRequestMessage(HttpMethod.Put, string.Format("https://bitwarden.freshdesk.com/api/v2/tickets/{0}", ticketId)) { Content = JsonContent.Create(updateBody), }; await CallFreshdeskApiAsync(updateRequest); var noteBody = new Dictionary <string, object> { { "body", $"<ul>{note}</ul>" }, { "private", true } }; var noteRequest = new HttpRequestMessage(HttpMethod.Post, string.Format("https://bitwarden.freshdesk.com/api/v2/tickets/{0}/notes", ticketId)) { Content = JsonContent.Create(noteBody), }; await CallFreshdeskApiAsync(noteRequest); } return(new OkResult()); } catch (Exception e) { _logger.LogError(e, "Error processing freshdesk webhook."); return(new BadRequestResult()); } }