feat(cv): rebuild professional resume studio

This commit is contained in:
cesnimda
2026-08-24 20:21:23 +02:00
parent dca5daa1a2
commit 367b70681a
27 changed files with 827 additions and 187 deletions
+63
View File
@@ -249,6 +249,54 @@ public sealed class CvBuilderTests
Assert.Contains("#123456", result.Html);
}
[Fact]
public void Design_and_layout_overrides_are_normalized_and_reach_the_shared_renderer()
{
var settings = CvVariantSettingsJson.Normalize(new CvVariantSettings
{
ThemeId = "modern",
Layout = "sidebar-right",
TextColor = "#123456",
MutedColor = "#456789",
BackgroundColor = "#fafafa",
BaseFontSizePt = 99,
HeadingSizePt = 15,
LineHeight = 1.55,
PageMarginMm = 20,
SidebarWidthMm = 70,
SidebarSections = new() { "skills", "languages" },
SkillsStyle = "text",
});
var model = CvVariantResolver.Build(Rich(), settings, "F", null);
var html = new ThemedCvRenderer().Render(model, CvThemeCatalog.Resolve("modern"), settings).Html;
Assert.Equal(13, settings.BaseFontSizePt);
Assert.Contains("grid-template-columns:minmax(0,1fr) 70mm", html);
Assert.Contains("color:#123456", html);
Assert.Contains("background:#fafafa", html);
Assert.Contains("line-height:1.55", html);
Assert.Contains("font-size:13pt", html);
Assert.Contains("class=\"skills-text\">C# · SQL</p>", html);
}
[Fact]
public void Norwegian_variant_localizes_default_labels_dates_and_keeps_custom_links_clickable()
{
var profile = Rich();
profile.Jobs[0].StartDate = "2020-01";
profile.Contact.GitHub = "github.com/ada";
profile.Contact.Links.Add(new StructuredCvLink { Label = "Portfolio", Url = "https://ada.example/work" });
var settings = new CvVariantSettings { Language = "no", DateFormat = "year" };
var model = CvVariantResolver.Build(profile, settings, "F", null);
var html = new ThemedCvRenderer().Render(model, CvThemeCatalog.Resolve("modern"), settings).Html;
Assert.Equal("Arbeidserfaring", model.Sections.First(section => section.Key == "experience").Title);
Assert.Equal("2020 nå", model.Sections.First(section => section.Key == "experience").Entries[0].Meta);
Assert.Contains("href=\"https://github.com/ada\"", html);
Assert.Contains("href=\"https://ada.example/work\">Portfolio</a>", html);
}
// ---- Variant service (CRUD, autosave history, public, render) ----
private static (JobTrackerContext db, CvVariantService svc) NewService(string userId, string? dbName = null)
@@ -303,6 +351,21 @@ public sealed class CvBuilderTests
Assert.Equal("elegant", CvVariantSettingsJson.Deserialize(copy.SettingsJson).ThemeId);
}
[Fact]
public async Task Create_rejects_a_job_application_owned_by_another_user()
{
var (db, svc) = NewService("user-1");
await using var _ = db;
var company = new Company { OwnerUserId = "user-2", Name = "Other tenant" };
var foreignJob = new JobApplication { OwnerUserId = "user-2", JobTitle = "Private role", Company = company };
db.Add(foreignJob);
await db.SaveChangesAsync();
await Assert.ThrowsAsync<ArgumentException>(() =>
svc.CreateAsync("user-1", "CV", foreignJob.Id, new CvVariantSettings(), default));
Assert.Empty(await db.CvVariants.IgnoreQueryFilters().ToListAsync());
}
[Fact]
public async Task Delete_removes_the_variant_and_its_versions()
{