diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorBeatmapCreation.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorBeatmapCreation.cs index 5aa2dd2ebf..37cb43a43a 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorBeatmapCreation.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorBeatmapCreation.cs @@ -18,6 +18,7 @@ using osu.Game.Database; using osu.Game.Overlays.Dialog; using osu.Game.Rulesets; using osu.Game.Rulesets.Catch; +using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.UI; @@ -453,6 +454,51 @@ namespace osu.Game.Tests.Visual.Editing }); } + [Test] + public void TestExitBlockedWhenSavingBeatmapWithSameNamedDifficulties() + { + Guid setId = Guid.Empty; + const string duplicate_difficulty_name = "duplicate"; + + AddStep("retrieve set ID", () => setId = EditorBeatmap.BeatmapInfo.BeatmapSet!.ID); + AddStep("set difficulty name", () => EditorBeatmap.BeatmapInfo.DifficultyName = duplicate_difficulty_name); + AddStep("save beatmap", () => Editor.Save()); + AddAssert("new beatmap persisted", () => + { + var set = beatmapManager.QueryBeatmapSet(s => s.ID == setId); + return set != null && set.PerformRead(s => s.Beatmaps.Count == 1 && s.Files.Count == 1); + }); + + AddStep("create new difficulty", () => Editor.CreateNewDifficulty(new CatchRuleset().RulesetInfo)); + + AddUntilStep("wait for created", () => + { + string? difficultyName = Editor.ChildrenOfType().SingleOrDefault()?.BeatmapInfo.DifficultyName; + return difficultyName != null && difficultyName != duplicate_difficulty_name; + }); + AddUntilStep("wait for editor load", () => Editor.IsLoaded && DialogOverlay.IsLoaded); + + AddStep("add hitobjects", () => EditorBeatmap.AddRange(new[] + { + new Fruit + { + StartTime = 0 + }, + new Fruit + { + StartTime = 1000 + } + })); + + AddStep("set difficulty name", () => EditorBeatmap.BeatmapInfo.DifficultyName = duplicate_difficulty_name); + AddUntilStep("wait for has unsaved changes", () => Editor.HasUnsavedChanges); + + AddStep("exit", () => Editor.Exit()); + AddUntilStep("wait for dialog", () => DialogOverlay.CurrentDialog is PromptForSaveDialog); + AddStep("attempt to save", () => DialogOverlay.CurrentDialog.PerformOkAction()); + AddAssert("editor is still current", () => Editor.IsCurrentScreen()); + } + [Test] public void TestCreateNewDifficultyForInconvertibleRuleset() { diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index b885eee46f..35d8bb4ab7 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -425,7 +425,8 @@ namespace osu.Game.Screens.Edit { dialogOverlay.Push(new SaveBeforeGameplayTestDialog(() => { - Save(); + if (!Save()) return; + pushEditorPlayer(); })); } @@ -764,7 +765,7 @@ namespace osu.Game.Screens.Edit private void confirmExitWithSave() { - Save(); + if (!Save()) return; ExitConfirmed = true; this.Exit(); @@ -1021,13 +1022,15 @@ namespace osu.Game.Screens.Edit private void exportBeatmap() { - Save(); + if (!Save()) return; + beatmapManager.Export(Beatmap.Value.BeatmapSetInfo); } private void exportLegacyBeatmap() { - Save(); + if (!Save()) return; + beatmapManager.ExportLegacy(Beatmap.Value.BeatmapSetInfo); }