using System.Net; using System.Text; using FindAndDrive.API; using FindAndDrive.Domain.Helpers; using FindAndDrive.Domain.Models.DTO.Request; using FindAndDrive.Domain.Models.DTO.Response; using FindAndDrive.Domain.Models.Entities; using FindAndDrive.Persistence; using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json; namespace FindAndDrive.Tests.IntegrationTests.Controllers; public class FinancingControllerTests : IClassFixture>, IAsyncLifetime { private readonly IntegrationTestAppFactory _factory; private Guid _clientId; private Guid _apiKeyId; private string _apiKeySecret; private string? _token = null; private Guid? _applicantId = null; private Guid? _preVettingApplicantId = null; private const string TokenHeader = "Authorization"; public FinancingControllerTests(IntegrationTestAppFactory factory) { _factory = factory; } [Fact] public async Task PreVettingRequest() { if (_token is null) await Authenticate(); var httpClient = _factory.CreateClient(); var payload = new PreVettingRequest { Deposit = 1000, FirstName = "first", LastName = "last", MobileNumber = "+27834213406", MonthlyBudget = 100, NetIncome = 500 }; using var request = new HttpRequestMessage(HttpMethod.Post, "api/Financing/Pre-Qualification"); request.Headers.Add(TokenHeader, $"Bearer {_token}"); request.Content = new StringContent( JsonConvert.SerializeObject(payload), Encoding.UTF8, "application/json" ); var response = await httpClient.SendAsync(request); Assert.True(response.StatusCode == HttpStatusCode.OK); var body = await response.Content.ReadAsStringAsync(); var responseObject = JsonConvert.DeserializeObject(body); Assert.True(responseObject is not null); Assert.True(responseObject.StatusCode == 200); _preVettingApplicantId = responseObject.ApplicantId; } [Fact] public async Task Prediction() { if (_token is null) await Authenticate(); var httpClient = _factory.CreateClient(); var payload = new AnalyticsRequest { ApplicantId = _applicantId.Value, NetIncome = 500, EmailAddress = "email@test.com", GrossIncome = 100, LivingExpenses = 100, IDNumber = "2001015800085" }; using var request = new HttpRequestMessage(HttpMethod.Post, "api/Financing/Prediction"); request.Headers.Add(TokenHeader, $"Bearer {_token}"); request.Content = new StringContent( JsonConvert.SerializeObject(payload), Encoding.UTF8, "application/json" ); var response = await httpClient.SendAsync(request); Assert.True(response.StatusCode == HttpStatusCode.OK); var body = await response.Content.ReadAsStringAsync(); var responseObject = JsonConvert.DeserializeObject(body); Assert.True(responseObject is not null); Assert.True(responseObject.ApplicantId == _applicantId); } private async Task Authenticate() { var httpClient = _factory.CreateClient(); var payload = new TokenRequest { ApiSecret = _apiKeySecret, ApiKeyId = _apiKeyId.ToString() }; using var request = new HttpRequestMessage(HttpMethod.Post, "api/Authentication/token"); request.Content = new StringContent( JsonConvert.SerializeObject(payload), Encoding.UTF8, "application/json" ); var response = await httpClient.SendAsync(request); var body = await response.Content.ReadAsStringAsync(); var responseObject = JsonConvert.DeserializeObject(body); _token = responseObject.Token; } public async Task InitializeAsync() { using var scope = _factory.Services.CreateScope(); var db = scope.ServiceProvider.GetRequiredService(); var client = new Client { Active = true, ClientName = $"test client {Guid.NewGuid()}", CreatedAt = DateTime.Now, ModifiedAt = DateTime.Now }; db.Clients.Add(client); await db.SaveChangesAsync(); var financingRole = db.Roles.First(f => f.RoleName == "Financing"); _apiKeySecret = ApiKeyHelper.GenerateApiKey(); var apiKey = new ApiKey { ClientId = client.ClientId, KeySecretHash = ApiKeyHelper.HashString(_apiKeySecret), Revoked = false, RoleId = financingRole.RoleId, }; db.ApiKeys.Add(apiKey); await db.SaveChangesAsync(); var applicant = new Applicant { ClientId = client.ClientId, FirstName = "test", MobileNumber = "+2782456135", LastName = "lastName", EmailAddress = "test@email.com" }; db.Applicants.Add(applicant); await db.SaveChangesAsync(); _applicantId = applicant.ApplicantId; _clientId = client.ClientId; _apiKeyId = apiKey.ApiKeyId; } async Task IAsyncLifetime.DisposeAsync() { using var scope = _factory.Services.CreateScope(); var db = scope.ServiceProvider.GetRequiredService(); var applicantFraudAlerts = db.ApplicantFraudAlert.Where(w => w.ApplicantId == _applicantId); var applicantCredits = db.ApplicantCredit.Where(w => w.ApplicantId == _applicantId); var applicantFinances = db.ApplicantFinance.Where(w => w.ApplicantId == _applicantId); var applicantPredicitions = db.ApplicantPredicition.Where(w => w.ApplicantId == _applicantId); var applicantAuditLogs = db.ApplicantAuditLog.Where(w => w.ApplicantId == _applicantId); db.ApplicantFraudAlert.RemoveRange(applicantFraudAlerts); db.ApplicantCredit.RemoveRange(applicantCredits); db.ApplicantFinance.RemoveRange(applicantFinances); db.ApplicantPredicition.RemoveRange(applicantPredicitions); db.ApplicantAuditLog.RemoveRange(applicantAuditLogs); await db.SaveChangesAsync(); if (_preVettingApplicantId is not null) { var preVettingApplicant = db.Applicants.First(w => w.ApplicantId == _preVettingApplicantId); db.Applicants.Remove(preVettingApplicant); } var applicant = db.Applicants.First(w => w.ApplicantId == _applicantId); db.Applicants.Remove(applicant); await db.SaveChangesAsync(); var apiKey = db.ApiKeys.First(f => f.ApiKeyId == _apiKeyId); var client = db.Clients.First(f => f.ClientId == _clientId); db.ApiKeys.Remove(apiKey); db.Clients.Remove(client); await db.SaveChangesAsync(); } }