feat(cv): qualify templates and reliable local import processing

This commit is contained in:
cesnimda
2026-10-28 14:36:12 +01:00
parent 73ea888375
commit 3f4db8ca81
69 changed files with 2597 additions and 180 deletions
+88
View File
@@ -28,6 +28,94 @@ public sealed class CvBuilderTests
// ---- Resolver (the lens over the master profile) ----
[Theory]
[InlineData("modern")]
[InlineData("ats-classic")]
[InlineData("code")]
public void Revised_design_has_space_below_the_main_title_and_header(string themeId)
{
var settings = new CvVariantSettings { ThemeId = themeId, DesignVersion = 2 };
var html = new ThemedCvRenderer().Render(CvVariantResolver.Build(Rich(), settings, "", null), CvThemeCatalog.Resolve(themeId), settings).Html;
Assert.Contains(".header .name{margin-bottom:3mm;}", html);
Assert.Contains(".header + .main{padding-top:5mm;}", html);
}
[Theory]
[InlineData("technical", "left")]
[InlineData("creative", "left")]
[InlineData("nordic", "right")]
public void Revised_sidebar_background_fills_each_physical_page_including_its_margins(string themeId, string edge)
{
var settings = new CvVariantSettings { ThemeId = themeId, DesignVersion = 2 };
var html = new ThemedCvRenderer().Render(CvVariantResolver.Build(Rich(), settings, "", null), CvThemeCatalog.Resolve(themeId), settings).Html;
Assert.Contains("@top-" + edge + "{content:", html);
Assert.Contains("@bottom-" + edge + "{content:", html);
Assert.Contains("body::before{content:", html);
}
[Fact]
public void Design_revision_missing_and_explicit_one_preserve_identical_legacy_html_for_every_theme()
{
foreach (var theme in CvThemeCatalog.Themes)
{
var legacy = new CvVariantSettings { ThemeId = theme.Id };
var explicitOne = CvVariantSettingsJson.Deserialize("{\"designVersion\":1,\"themeId\":\"" + theme.Id + "\"}");
var renderer = new ThemedCvRenderer();
var model = CvVariantResolver.Build(Rich(), legacy, "Fallback", null);
Assert.Equal(renderer.Render(model, theme, legacy).Html, renderer.Render(model, theme, explicitOne).Html);
Assert.DoesNotContain("designVersion", CvVariantSettingsJson.Serialize(legacy));
}
}
[Fact]
public void Design_revision_two_is_persisted_and_changes_presentation_without_changing_content()
{
var settings = CvVariantSettingsJson.Deserialize("{\"designVersion\":2,\"themeId\":\"modern\"}");
Assert.Contains("\"designVersion\":2", CvVariantSettingsJson.Serialize(settings));
var model = CvVariantResolver.Build(Rich(), settings, "Fallback", null);
var theme = CvThemeCatalog.Resolve("modern");
var renderer = new ThemedCvRenderer();
var revised = renderer.Render(model, theme, settings).Html;
var legacy = renderer.Render(model, theme, new() { ThemeId = "modern" }).Html;
Assert.NotEqual(legacy, revised);
Assert.Contains("Ada Lovelace", revised);
Assert.Contains("Builder of engines.", revised);
Assert.Contains("Built X", revised);
Assert.Contains("AZ-204", revised);
}
[Theory]
[InlineData("technical", "#0f4c5c", "#ffffff")]
[InlineData("nordic", "#eef3f8", "#1f2937")]
[InlineData("creative", "#be185d", "#ffffff")]
public void Design_revision_two_sidebar_uses_its_own_palette_and_room_for_identity(string themeId, string background, string ink)
{
var settings = CvVariantSettingsJson.Deserialize("{\"designVersion\":2,\"themeId\":\"" + themeId + "\"}");
var model = CvVariantResolver.Build(Rich(), settings, "Fallback", null);
var html = new ThemedCvRenderer().Render(model, CvThemeCatalog.Resolve(themeId), settings).Html;
Assert.Contains("--cv-sidebar-bg:" + background, html);
Assert.Contains("--cv-sidebar-ink:" + ink, html);
Assert.Contains("background:var(--cv-sidebar-bg)", html);
Assert.Contains("color:var(--cv-sidebar-ink)", html);
Assert.Contains("padding:8mm", html);
Assert.Contains("68mm", html);
}
[Fact]
public async Task Design_revision_duplicate_and_restore_keep_their_stored_opt_in()
{
var (db, service) = NewService("user-1");
await using var dispose = db;
var created = await service.CreateAsync("user-1", "Legacy design", null, new(), default);
var revisionTwo = CvVariantSettingsJson.Deserialize("{\"designVersion\":2,\"themeId\":\"technical\"}");
await service.SaveAsync("user-1", created.Id, null, revisionTwo, "manual", 1, default);
var copy = (await service.DuplicateAsync("user-1", created.Id, null, default))!;
Assert.Contains("\"designVersion\":2", copy.SettingsJson);
var restored = (await service.RestoreVersionAsync("user-1", created.Id, 1, 2, default))!;
Assert.DoesNotContain("designVersion", restored.SettingsJson);
Assert.Contains("\"designVersion\":2", (await db.CvVariantVersions.SingleAsync(row => row.CvVariantId == created.Id && row.Version == 2)).SettingsJson);
}
[Fact]
public void Explicit_blank_roundtrips_without_inheriting_profile_content_or_header()
{