diff --git a/OpenNest.Data/SetReleaseText.cs b/OpenNest.Data/SetReleaseText.cs index d95e4ccd..77232025 100644 --- a/OpenNest.Data/SetReleaseText.cs +++ b/OpenNest.Data/SetReleaseText.cs @@ -75,6 +75,25 @@ public static class SetReleaseText + "\n\nUndo the rest and leave these as they are, or restore them from their history."; } + /// + /// What the release did to one of its nests, and what undoing it did: "Created", + /// "Merged (revision 3 → 4)", "Created; undo deleted it". + /// + public static string Change(SetReleaseNest nest) + { + ArgumentNullException.ThrowIfNull(nest); + var text = nest.Kind == SetReleaseNestKind.Merged + ? $"Merged (revision {nest.RevisionBefore} → {nest.RevisionAfter})" + : "Created"; + return nest.Undo switch + { + SetReleaseNestUndo.Deleted => text + "; undo deleted it", + SetReleaseNestUndo.Restored => text + $"; undo restored revision {nest.RevisionBefore}", + SetReleaseNestUndo.Skipped => text + "; undo left it as it was", + _ => text, + }; + } + /// The state of one nest of a release: its status name, or "Deleted". public static string NestState(SetReleaseNest nest) { diff --git a/OpenNest.Tests/Data/InMemoryDrawingSets.cs b/OpenNest.Tests/Data/InMemoryDrawingSets.cs index fa3e8097..36cfb19e 100644 --- a/OpenNest.Tests/Data/InMemoryDrawingSets.cs +++ b/OpenNest.Tests/Data/InMemoryDrawingSets.cs @@ -165,8 +165,19 @@ internal sealed class InMemoryDrawingSets : IDrawingSetStore }); } - public Task UndoReleaseAsync(Guid id, SetReleaseUndoRequest request, CancellationToken cancellationToken = default) => - throw new NotSupportedException("The in-memory store does not hold nests, so it cannot undo a release."); + /// Every undo request, in order. + public List<(Guid Id, SetReleaseUndoRequest Request)> UndoRequests { get; } = new(); + + /// Answers an undo; this store holds no nests, so a test decides what the server says. + public Func? UndoHandler { get; set; } + + public Task UndoReleaseAsync(Guid id, SetReleaseUndoRequest request, CancellationToken cancellationToken = default) + { + UndoRequests.Add((id, new SetReleaseUndoRequest { UndoneBy = request.UndoneBy, SkipNests = request.SkipNests.ToList() })); + return UndoHandler is { } handler + ? Task.FromResult(handler(id, request)) + : throw new NotSupportedException("The in-memory store does not hold nests, so it cannot undo a release."); + } private Task SetArchived(Guid id, int expectedRevision, bool archived) { diff --git a/OpenNest.Tests/Data/SetReleaseTextTests.cs b/OpenNest.Tests/Data/SetReleaseTextTests.cs index cc0bf4d4..25c4f5ba 100644 --- a/OpenNest.Tests/Data/SetReleaseTextTests.cs +++ b/OpenNest.Tests/Data/SetReleaseTextTests.cs @@ -53,6 +53,25 @@ public class SetReleaseTextTests Assert.Equal("Released from set 'Synthetic kit' revision 3 ×2 by Synthetic operator", text); } + [Theory] + [InlineData(SetReleaseNestKind.Created, null, "Created")] + [InlineData(SetReleaseNestKind.Created, SetReleaseNestUndo.Deleted, "Created; undo deleted it")] + [InlineData(SetReleaseNestKind.Merged, null, "Merged (revision 3 → 4)")] + [InlineData(SetReleaseNestKind.Merged, SetReleaseNestUndo.Restored, "Merged (revision 3 → 4); undo restored revision 3")] + [InlineData(SetReleaseNestKind.Merged, SetReleaseNestUndo.Skipped, "Merged (revision 3 → 4); undo left it as it was")] + public void Change_SaysWhatTheReleaseAndItsUndoDid(SetReleaseNestKind kind, SetReleaseNestUndo? undo, string expected) + { + var nest = new SetReleaseNest + { + Kind = kind, + RevisionBefore = kind == SetReleaseNestKind.Merged ? 3 : null, + RevisionAfter = kind == SetReleaseNestKind.Merged ? 4 : 1, + Undo = undo, + }; + + Assert.Equal(expected, SetReleaseText.Change(nest)); + } + [Fact] public void UndoRefusal_NamesEachChangedNest_OrSaysItWasUndoneBefore() { diff --git a/OpenNest.WinForms.Tests/Forms/SetReleaseFormsTests.cs b/OpenNest.WinForms.Tests/Forms/SetReleaseFormsTests.cs index 1c4e4650..bab6d707 100644 --- a/OpenNest.WinForms.Tests/Forms/SetReleaseFormsTests.cs +++ b/OpenNest.WinForms.Tests/Forms/SetReleaseFormsTests.cs @@ -43,13 +43,13 @@ public class SetReleaseFormsTests Assert.Equal(2, grid.Rows.Count); Assert.True(skipped.Visible); Assert.Contains("'SYN-OLD'", skipped.Text); - Field(form, "multiplierBox").Value = 3; + Field(form, "setGrid").Rows[0].Cells["kitsColumn"].Value = "3"; Assert.Equal(new object[] { 12, 9 }, grid.Rows.Cast().Select(r => r.Cells["partsColumn"].Value)); Field(form, "notesBox").Text = "Synthetic run"; Run(form.ReleaseAsync()); - Assert.Contains("Create 2 Draft nests from set 'Synthetic kit' ×3", Assert.Single(questions)); + Assert.Contains("Release set 'Synthetic kit' ×3 into 2 Draft nests", Assert.Single(questions)); Assert.Equal(2, nests.Uploaded.Count); Assert.Equal(2, opened.Count); Assert.All(opened, o => Assert.Equal(NestStatus.Draft, o.Nest.Status)); @@ -64,7 +64,8 @@ public class SetReleaseFormsTests Assert.StartsWith("Released: 2 nests", Field