Files
przygody-pana-cegly/progression.tests/PlaythroughSnapshotTests.cs
Gabriel Kaszewski 003ec4b010 feat(progression): snapshots, ports, in-memory adapters (slice 5)
flat snapshot record per aggregate - separate files mean saving a run
doesn't rewrite the Profile, deleting a slot is deleting a file, and a
corrupt slot doesn't cost achievements or best times.

snapshots hold primitives so Restore re-runs the value-object factories;
a serialiser building LevelId directly would bypass every guard.

LoadResult has three outcomes: Absent != Corrupt. Collapsing them is the
bug where a version bump made ContinueGame overwrite the save.

Profile.Restore writes collections directly - replaying UnlockAchievement
would re-fire popups and Steam pushes on every load. 44 tests.
2026-07-28 19:02:41 +02:00

34 lines
1.4 KiB
C#

namespace Mr.BrickAdventures.Progression.Tests;
public class PlaythroughSnapshotTests
{
private static readonly LevelId First = LevelId.Of("village_1");
private static readonly LevelId Second = LevelId.Of("village_2");
private static Campaign TwoLevels() => Campaign.Of(new[] { First, Second });
[Fact]
public void A_playthrough_survives_a_round_trip_through_its_snapshot()
{
var brickThrow = SkillId.Of("brick_throw");
var campaign = TwoLevels();
var original = Playthrough.StartNew(
PlaythroughId.Of(new Guid("22222222-2222-2222-2222-222222222222")), campaign, Lives.Of(3));
var attempt = new Attempt(First);
attempt.RecordCoinsFound(Coins.Of(50));
attempt.TryRecordPurchase(brickThrow, SkillLevel.Of(2), Coins.Of(30));
original.SettleCompletion(attempt, campaign);
original.SettleDeath(new Attempt(Second));
var restored = Playthrough.Restore(original.Export());
Assert.Equal(original.Id, restored.Id);
Assert.Equal(original.Lives.Value, restored.Lives.Value);
Assert.Equal(original.Bank, restored.Bank);
Assert.Equal(original.CurrentLevel, restored.CurrentLevel);
Assert.Equal(SkillLevel.Of(2), restored.OwnedSkills[brickThrow]);
Assert.Equal(original.ClearedLevels.OrderBy(l => l.Value), restored.ClearedLevels.OrderBy(l => l.Value));
}
}