Fix backup recovery when primary progress save is missing
This commit is contained in:
@@ -87,6 +87,51 @@ namespace MagnetismHeroes.Tests
|
||||
Assert.That(store.TryLoad(out var restored, out error), Is.True, error);
|
||||
Assert.That(restored.puzzleStates.Single().stageId, Is.EqualTo(1));
|
||||
}
|
||||
[Test] public void MissingPrimaryRestoresEntireValidBackup()
|
||||
{
|
||||
var definitions = new[] { _stage,
|
||||
new StageDefinition(2, StageKind.Counting, new[] { 1, 1 }, new[] { 2 }),
|
||||
new StageDefinition(6, StageKind.Composition, new[] { 1, 1 }, new[] { 2 }) };
|
||||
var session = new GameSession(definitions, new LocalProgressStore(_path, definitions));
|
||||
session.StartStage(1); session.MoveGroup(session.Board.Groups[0].id, new Position3(1, 2, 3));
|
||||
session.Count(session.Board.Balls[0].id); session.MarkTutorialSeen("merge");
|
||||
session.StartStage(2); session.MoveAndMerge(session.Board.Groups[0].id, new Position3(2, 1, -3), session.Board.Groups[1].id);
|
||||
session.Count(session.Board.Balls[0].id);
|
||||
session.CommitCamera(new CameraState { target = new Position3(1, 2, 3), rotation = new Rotation4(0, .6f, 0, .8f), distance = 11 });
|
||||
var store = new LocalProgressStore(_path, definitions);
|
||||
Assert.That(store.TryLoad(out var expected, out var error), Is.True, error);
|
||||
var six = new BoardRules(definitions[2]); six.TryMoveGroup(six.Groups[0].id, new Position3(-1, 2, 4));
|
||||
expected.puzzleStates = expected.puzzleStates.Concat(new[] { six.ToPuzzleState(GameSession.DefaultCamera()) }).ToArray();
|
||||
Assert.That(store.TrySave(expected, out error), Is.True, error);
|
||||
var expectedJson = File.ReadAllText(_path);
|
||||
Assert.That(store.TrySave(expected, out error), Is.True, error); File.Delete(_path);
|
||||
Assert.That(store.TryLoad(out var loaded, out error), Is.True, error);
|
||||
Assert.That(error, Does.Contain("Recovered valid backup"));
|
||||
Assert.That(loaded.puzzleStates.Length, Is.EqualTo(2));
|
||||
Assert.That(loaded.puzzleStates.Single(state => state.stageId == 2).countedBallIds.Length, Is.EqualTo(1));
|
||||
Assert.That(store.TrySave(loaded, out error), Is.True, error);
|
||||
Assert.That(File.ReadAllText(_path), Is.EqualTo(expectedJson), "Every contract field, including free play and tutorial progress, must survive.");
|
||||
}
|
||||
[Test] public void MissingPrimaryWithInvalidBackupPreservesEvidenceThroughTwoSaves()
|
||||
{
|
||||
File.WriteAllText(_path + ".bak", "distinct-backup-only-damage");
|
||||
var store = Store(); Assert.That(store.TryLoad(out var loaded, out var error), Is.False);
|
||||
Assert.That(loaded, Is.Null); Assert.That(error, Does.Contain("Invalid primary and backup"));
|
||||
Assert.That(File.Exists(_path), Is.False);
|
||||
Assert.That(File.ReadAllText(_path + ".bak"), Is.EqualTo("distinct-backup-only-damage"));
|
||||
Assert.That(store.TrySave(new ProgressSave(), out error), Is.True, error);
|
||||
Assert.That(store.TrySave(Puzzle(), out error), Is.True, error);
|
||||
Assert.That(Directory.GetFiles(_directory, "*.bak.damaged-*").Select(File.ReadAllText), Does.Contain("distinct-backup-only-damage"));
|
||||
Assert.That(store.TryLoad(out loaded, out error), Is.True, error);
|
||||
Assert.That(loaded.puzzleStates.Single().stageId, Is.EqualTo(1));
|
||||
}
|
||||
[Test] public void MissingPrimaryAndBackupStartsFreshWithoutRecoveryError()
|
||||
{
|
||||
Assert.That(Store().TryLoad(out var loaded, out var error), Is.True, error);
|
||||
Assert.That(error, Is.Null); Assert.That(loaded.puzzleStates, Is.Empty);
|
||||
Assert.That(loaded.completedStageIds, Is.Empty); Assert.That(loaded.seenTutorialIds, Is.Empty);
|
||||
Assert.That(loaded.latestFreePlay, Is.Null); Assert.That(Directory.GetFiles(_directory), Is.Empty);
|
||||
}
|
||||
[Test] public void InvalidGroupMembershipDoesNotReplaceAValidSave()
|
||||
{
|
||||
var store = Store(); var progress = Puzzle(); Assert.That(store.TrySave(progress, out _), Is.True);
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace MagnetismHeroes.UnityRuntime.Persistence
|
||||
public bool TryLoad(out ProgressSave save, out string error)
|
||||
{
|
||||
save = null; error = null;
|
||||
if (!File.Exists(_path)) { save = new ProgressSave(); return true; }
|
||||
if (!File.Exists(_path) && !File.Exists(_path + ".bak")) { save = new ProgressSave(); return true; }
|
||||
if (Read(_path, out save, out error)) return true;
|
||||
var originalError = error;
|
||||
if (Read(_path + ".bak", out save, out var backupError))
|
||||
|
||||
Reference in New Issue
Block a user