Files
jobtrackingapp/JobTrackerApi.Tests/CorrespondenceControllerTests.cs
T
cesnimda e7cacad7d6
CI and Deploy / test (pull_request) Failing after 2m46s
CI and Deploy / deploy (pull_request) Has been skipped
fix(scale): page mail and batch roles
2026-08-15 21:02:50 +02:00

130 lines
5.8 KiB
C#

using JobTrackerApi.Controllers;
using JobTrackerApi.Data;
using JobTrackerApi.Models;
using JobTrackerApi.Services;
using JobTrackerApi.Tests.TestSupport;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Moq;
using Xunit;
namespace JobTrackerApi.Tests;
public sealed class CorrespondenceControllerTests
{
[Fact]
public async Task Create_tags_manually_entered_correspondence_with_manual_provider()
{
await using var db = TestHostFactory.CreateInMemoryDb();
var company = new Company { Name = "Acme", OwnerUserId = "user-1" };
db.Companies.Add(company);
await db.SaveChangesAsync();
var job = new JobApplication { JobTitle = "Backend Developer", CompanyId = company.Id, OwnerUserId = "user-1" };
db.JobApplications.Add(job);
await db.SaveChangesAsync();
var controller = new CorrespondenceController(db);
var request = new CorrespondenceController.CreateCorrespondenceRequestV2(
job.Id, "Me", "Called to follow up.", "Follow-up call", "Call", null, "outbound", null, null, null, null, null, null);
var result = await controller.Create(request, CancellationToken.None);
Assert.IsType<Correspondence>(((CreatedAtActionResult)result.Result!).Value);
var stored = await db.Correspondences.SingleAsync();
Assert.Equal("manual", stored.Provider);
}
[Fact]
public async Task Message_detail_is_owner_scoped_and_tolerates_bad_metadata()
{
var databaseName = Guid.NewGuid().ToString();
var options = new DbContextOptionsBuilder<JobTrackerContext>().UseInMemoryDatabase(databaseName).Options;
var owner = new Mock<ICurrentUserService>();
owner.SetupGet(service => service.UserId).Returns("user-1");
int messageId;
await using (var ownerDb = new JobTrackerContext(options, owner.Object))
{
var company = new Company { Name = "Acme", OwnerUserId = "user-1" };
ownerDb.Companies.Add(company);
await ownerDb.SaveChangesAsync();
var job = new JobApplication { JobTitle = "Backend Developer", CompanyId = company.Id, OwnerUserId = "user-1" };
ownerDb.JobApplications.Add(job);
await ownerDb.SaveChangesAsync();
var message = new Correspondence
{
JobApplicationId = job.Id,
From = "Company",
Subject = "Interview",
Content = "Safe saved copy",
ExternalLabelsJson = "not-json",
AttachmentMetadataJson = "also-not-json"
};
ownerDb.Correspondences.Add(message);
await ownerDb.SaveChangesAsync();
messageId = message.Id;
var ownerResult = await new CorrespondenceController(ownerDb).GetMessage(messageId, CancellationToken.None);
var ok = Assert.IsType<OkObjectResult>(ownerResult.Result);
var detail = Assert.IsType<EmailMessageDetailDto>(ok.Value);
Assert.Equal("Safe saved copy", detail.BodyText);
Assert.Empty(detail.Labels);
Assert.Empty(detail.Attachments);
var inboxResult = await new CorrespondenceController(ownerDb).GetInbox(null, null, null, CancellationToken.None);
var inbox = Assert.IsType<OkObjectResult>(inboxResult.Result);
var item = Assert.Single(Assert.IsType<List<CorrespondenceController.CorrespondenceInboxItemDto>>(inbox.Value));
Assert.Equal(0, item.LabelCount);
Assert.Equal(0, item.AttachmentCount);
}
var other = new Mock<ICurrentUserService>();
other.SetupGet(service => service.UserId).Returns("user-2");
await using var otherDb = new JobTrackerContext(options, other.Object);
var otherResult = await new CorrespondenceController(otherDb).GetMessage(messageId, CancellationToken.None);
Assert.IsType<NotFoundResult>(otherResult.Result);
}
[Fact]
public async Task Paged_inbox_returns_every_owned_message_without_the_legacy_cap()
{
await using var db = TestHostFactory.CreateInMemoryDb();
var company = new Company { Name = "Scale fixture", OwnerUserId = "user-1" };
var otherCompany = new Company { Name = "Other tenant", OwnerUserId = "user-2" };
db.Companies.AddRange(company, otherCompany);
await db.SaveChangesAsync();
var job = new JobApplication { JobTitle = "Paged role", CompanyId = company.Id, OwnerUserId = "user-1" };
var otherJob = new JobApplication { JobTitle = "Private role", CompanyId = otherCompany.Id, OwnerUserId = "user-2" };
db.JobApplications.AddRange(job, otherJob);
await db.SaveChangesAsync();
db.Correspondences.AddRange(Enumerable.Range(1, 205).Select(index => new Correspondence
{
JobApplicationId = job.Id,
From = "Recruiter",
Subject = $"Message {index}",
Content = $"Content {index}",
Date = new DateTime(2026, 1, 1).AddMinutes(index)
}));
db.Correspondences.Add(new Correspondence
{
JobApplicationId = otherJob.Id,
From = "Other recruiter",
Subject = "Private message",
Content = "Must stay tenant isolated",
Date = new DateTime(2026, 2, 1)
});
await db.SaveChangesAsync();
var result = await new CorrespondenceController(db).GetInboxPage(null, null, null, 3, 100, CancellationToken.None);
var page = Assert.IsType<CorrespondenceController.CorrespondenceInboxPageDto>(Assert.IsType<OkObjectResult>(result.Result).Value);
Assert.Equal(205, page.Total);
Assert.Equal(3, page.TotalPages);
Assert.Equal(3, page.Page);
Assert.Equal(5, page.Items.Count);
Assert.Equal("Message 5", page.Items[0].Subject);
Assert.Equal("Message 1", page.Items[^1].Subject);
}
}