ce76046a29
- consolidate API ownership and remove dead vendor code - add Stripe billing, learning paths, and public CV hardening - add migration, recovery, security, audit, and browser gates
62 lines
2.8 KiB
C#
62 lines
2.8 KiB
C#
using JobTrackerApi.Controllers;
|
|
using JobTrackerApi.Models;
|
|
using JobTrackerApi.Services;
|
|
using JobTrackerApi.Tests.TestSupport;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.AspNetCore.RateLimiting;
|
|
using Moq;
|
|
using System.Reflection;
|
|
using Xunit;
|
|
|
|
namespace JobTrackerApi.Tests;
|
|
|
|
public sealed class PublicCvControllerTests
|
|
{
|
|
[Fact]
|
|
public void Pdf_download_is_rate_limited()
|
|
{
|
|
var attribute = typeof(PublicCvController).GetMethod(nameof(PublicCvController.DownloadPdf))!
|
|
.GetCustomAttribute<EnableRateLimitingAttribute>();
|
|
|
|
Assert.Equal("public-pdf", attribute?.PolicyName);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Pdf_download_uses_the_public_variant_render()
|
|
{
|
|
var user = new ApplicationUser { Id = "owner-1", FirstName = "Ada", LastName = "Lovelace" };
|
|
var variants = new Mock<ICvVariantService>();
|
|
var pdf = new Mock<ICvPdfExporter>();
|
|
var render = new ThemedCvRenderResult("modern", "ada-cv.pdf", "<html>CV</html>");
|
|
variants.Setup(x => x.GetPublicOwnerAsync("public-slug", It.IsAny<CancellationToken>())).ReturnsAsync(user.Id);
|
|
variants.Setup(x => x.RenderPublicAsync("public-slug", It.IsAny<CvRenderPerson>(), It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync((render, user.Id));
|
|
pdf.Setup(x => x.ExportAsync(It.IsAny<TailoredCvRenderResult>(), It.IsAny<CancellationToken>()))
|
|
.ReturnsAsync(new CvPdfArtifact("ada-cv.pdf", "unused", [1, 2, 3]));
|
|
|
|
var controller = new PublicCvController(TestHostFactory.CreateUserManager(user).Object, variants.Object, pdf.Object);
|
|
|
|
var result = Assert.IsType<FileContentResult>(await controller.DownloadPdf("public-slug", CancellationToken.None));
|
|
|
|
Assert.Equal("application/pdf", result.ContentType);
|
|
Assert.Equal("ada-cv.pdf", result.FileDownloadName);
|
|
Assert.Equal([1, 2, 3], result.FileContents);
|
|
pdf.Verify(x => x.ExportAsync(
|
|
It.Is<TailoredCvRenderResult>(value => value.TemplateId == "modern" && value.Html == "<html>CV</html>"),
|
|
It.IsAny<CancellationToken>()), Times.Once);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Pdf_download_does_not_render_an_unknown_or_private_slug()
|
|
{
|
|
var variants = new Mock<ICvVariantService>();
|
|
variants.Setup(x => x.GetPublicOwnerAsync("private-slug", It.IsAny<CancellationToken>())).ReturnsAsync((string?)null);
|
|
var pdf = new Mock<ICvPdfExporter>();
|
|
var controller = new PublicCvController(TestHostFactory.CreateUserManager().Object, variants.Object, pdf.Object);
|
|
|
|
Assert.IsType<NotFoundResult>(await controller.DownloadPdf("private-slug", CancellationToken.None));
|
|
variants.Verify(x => x.RenderPublicAsync(It.IsAny<string>(), It.IsAny<CvRenderPerson>(), It.IsAny<CancellationToken>()), Times.Never);
|
|
pdf.VerifyNoOtherCalls();
|
|
}
|
|
}
|