#nullable enable using MBN_STOCK_WEBVIEW.DbWriteSmoke; namespace MBN_STOCK_WEBVIEW.DbWriteSmoke.Tests; public sealed class DevelopmentDatabaseSmokeScenarioTests { [Fact] public async Task SuccessfulScenario_InvokesEachOperationExactlyOnceInOrder() { var calls = new List(); var scenario = CreateScenario(calls); var result = await scenario.RunAsync(); Assert.True(result.Passed); Assert.True(result.CleanupAttempted); Assert.True(result.CleanupVerified); Assert.Equal( ["preflight", "create", "create-readback", "save", "save-readback", "cleanup", "absent"], calls); } [Fact] public async Task UnknownCreate_DoesNotRetryCleanupOrContinue() { var calls = new List(); var scenario = CreateScenario( calls, create: _ => { calls.Add("create"); return Task.FromException(new UnknownTestException()); }); var result = await scenario.RunAsync(); Assert.False(result.Passed); Assert.True(result.OutcomeUnknown); Assert.Equal(nameof(UnknownTestException), result.FailureClass); Assert.True(result.ManualCleanupMayBeRequired); Assert.False(result.CleanupAttempted); Assert.Equal(["preflight", "create"], calls); } [Fact] public async Task UnknownSave_DoesNotIssueReadbackOrCleanupMutation() { var calls = new List(); var scenario = CreateScenario( calls, save: _ => { calls.Add("save"); return Task.FromException(new UnknownTestException()); }); var result = await scenario.RunAsync(); Assert.False(result.Passed); Assert.True(result.OutcomeUnknown); Assert.True(result.ManualCleanupMayBeRequired); Assert.False(result.CleanupAttempted); Assert.Equal(["preflight", "create", "create-readback", "save"], calls); } [Fact] public async Task KnownReadbackFailure_StillCleansKnownCreatedRecordInFinally() { var calls = new List(); var scenario = CreateScenario( calls, verifyCreate: _ => { calls.Add("create-readback"); return Task.FromException(new InvalidOperationException("bad readback")); }); var result = await scenario.RunAsync(); Assert.False(result.Passed); Assert.False(result.OutcomeUnknown); Assert.Equal(nameof(InvalidOperationException), result.FailureClass); Assert.Equal(DevelopmentDatabaseSmokeStage.CreateReadback, result.FailureStage); Assert.True(result.CleanupAttempted); Assert.True(result.CleanupVerified); Assert.Equal( ["preflight", "create", "create-readback", "cleanup", "absent"], calls); } [Fact] public async Task UnknownCleanup_IsNotRetriedAndSkipsAbsenceRead() { var calls = new List(); var scenario = CreateScenario( calls, cleanup: _ => { calls.Add("cleanup"); return Task.FromException(new UnknownTestException()); }); var result = await scenario.RunAsync(); Assert.False(result.Passed); Assert.True(result.OutcomeUnknown); Assert.Equal(DevelopmentDatabaseSmokeStage.Cleanup, result.FailureStage); Assert.True(result.CleanupAttempted); Assert.False(result.CleanupVerified); Assert.Equal( ["preflight", "create", "create-readback", "save", "save-readback", "cleanup"], calls); } private static DevelopmentDatabaseSmokeScenario CreateScenario( List calls, Func? create = null, Func? verifyCreate = null, Func? save = null, Func? cleanup = null) => new( "fake production workflow", Record(calls, "preflight"), create ?? Record(calls, "create"), verifyCreate ?? Record(calls, "create-readback"), save ?? Record(calls, "save"), Record(calls, "save-readback"), cleanup ?? Record(calls, "cleanup"), Record(calls, "absent"), exception => exception is UnknownTestException); private static Func Record( ICollection calls, string value) => _ => { calls.Add(value); return Task.CompletedTask; }; private sealed class UnknownTestException : Exception; }