using Mr.BrickAdventures.Progression.Adapters; namespace Mr.BrickAdventures.Progression.Tests; public sealed class JsonProfileStoreTests : IDisposable { private readonly string _directory = Path.Combine(Path.GetTempPath(), "ppc-progression-" + Guid.NewGuid().ToString("N")); private static readonly LevelId Level = LevelId.Of("village_1"); public void Dispose() { if (Directory.Exists(_directory)) Directory.Delete(_directory, recursive: true); } [Fact] public void A_profile_survives_a_round_trip_through_a_real_file() { var store = new JsonProfileStore(_directory); var profile = Profile.Empty(); profile.RecordTime(Level, LevelTime.Of(31.25)); profile.UnlockAchievement(AchievementId.Of("rescue_ten_kids")); profile.Record(StatName.Deaths, 7); store.Save(profile); var result = store.Load(); Assert.Equal(LoadOutcome.Loaded, result.Outcome); Assert.Equal(LevelTime.Of(31.25), result.Value!.BestTimeFor(Level)); Assert.True(result.Value.HasAchievement(AchievementId.Of("rescue_ten_kids"))); Assert.Equal(7, result.Value.ReadStat(StatName.Deaths)); } [Fact] public void On_a_first_run_there_is_no_profile_file_and_that_is_absent() { Assert.Equal(LoadOutcome.Absent, new JsonProfileStore(_directory).Load().Outcome); } [Fact] public void Saving_a_playthrough_does_not_touch_the_profile_file() { // The point of one file per aggregate. A run being saved on every level completion must not // rewrite achievements and best times, and a corrupt slot must not cost them. var profiles = new JsonProfileStore(_directory); var playthroughs = new JsonPlaythroughStore(_directory); var profile = Profile.Empty(); profile.RecordTime(Level, LevelTime.Of(31.25)); profiles.Save(profile); var profilePath = Directory.GetFiles(_directory, "profile*.json").Single(); var before = File.GetLastWriteTimeUtc(profilePath); var contentBefore = File.ReadAllText(profilePath); playthroughs.Save(Playthrough.StartNew( PlaythroughId.Of(Guid.NewGuid()), Campaign.Of(new[] { Level }), Lives.Of(3))); Assert.Equal(before, File.GetLastWriteTimeUtc(profilePath)); Assert.Equal(contentBefore, File.ReadAllText(profilePath)); Assert.Equal(2, Directory.GetFiles(_directory, "*.json").Length); } }