fix(cv): make profile saves atomic

This commit is contained in:
cesnimda
2026-08-29 23:12:33 +02:00
parent 487c5f59a9
commit 8288923e5d
8 changed files with 127 additions and 27 deletions
@@ -34,6 +34,43 @@ public sealed class CareerProfileServiceTests
Assert.False(string.IsNullOrWhiteSpace(saved.Jobs[0].Id));
}
[Fact]
public async Task SaveVersionAsync_replaces_duplicate_item_ids_without_dropping_entries()
{
await using var db = NewContext("user-1");
var service = new CareerProfileService(db);
var profile = new StructuredCvProfile
{
Jobs = { new StructuredCvJob { Id = "shared", Title = "Engineer", Company = "Acme" } },
Education = { new StructuredCvEducation { Id = "shared", Qualification = "BSc", Institution = "University" } },
};
var saved = await service.SaveVersionAsync("user-1", profile, "manual", default);
Assert.Equal("shared", saved.Jobs[0].Id);
Assert.NotEqual(saved.Jobs[0].Id, saved.Education[0].Id);
Assert.Single(await db.CareerExperiences.IgnoreQueryFilters().ToListAsync());
Assert.Single(await db.CareerEducations.IgnoreQueryFilters().ToListAsync());
}
[Fact]
public async Task LoadStructuredAsync_hides_race_affected_duplicate_child_rows()
{
await using var db = NewContext("user-1");
var profile = new CareerProfile { OwnerUserId = "user-1", ProfileJson = "{}", LongTailJson = "{}", Version = 1 };
db.CareerProfiles.Add(profile);
await db.SaveChangesAsync();
db.CareerExperiences.AddRange(
new CareerExperience { CareerProfileId = profile.Id, OwnerUserId = "user-1", ItemKey = "duplicate", SortOrder = 0, Title = "Engineer" },
new CareerExperience { CareerProfileId = profile.Id, OwnerUserId = "user-1", ItemKey = "duplicate", SortOrder = 0, Title = "Engineer" });
await db.SaveChangesAsync();
var loaded = await new CareerProfileService(db).LoadStructuredAsync("user-1", default);
Assert.Single(loaded.Jobs);
Assert.Equal("duplicate", loaded.Jobs[0].Id);
}
[Fact]
public async Task SaveVersionAsync_preserves_existing_ids_across_saves()
{
+11
View File
@@ -537,4 +537,15 @@ public sealed class CvBuilderTests
Assert.Contains("class=\"paragraphs\"><p>I confirm these details.</p>", html);
}
[Fact]
public void Settings_normalization_removes_duplicate_entry_order_keys()
{
var settings = CvVariantSettingsJson.Normalize(new CvVariantSettings
{
Sections = { new CvSectionSetting { Key = "experience", ItemOrder = new() { "first", "first", "second", " " } } },
});
Assert.Equal(new[] { "first", "second" }, settings.Sections[0].ItemOrder);
}
}