1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 09:27:29 +08:00

Merge pull request #27996 from bdach/delete-dirty-difficulty-droken

Fix deleting modified difficulty via editor leaving user in broken state
This commit is contained in:
Dean Herbert 2024-04-25 21:20:09 +08:00 committed by GitHub
commit 6a8a6fa79d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 51 additions and 0 deletions

View File

@ -12,6 +12,7 @@ using osu.Game.Beatmaps;
using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Osu;
using osu.Game.Screens.Edit;
using osu.Game.Storyboards;
using osu.Game.Tests.Beatmaps.IO;
using osuTK.Input;
@ -83,6 +84,49 @@ namespace osu.Game.Tests.Visual.Editing
}
}
[Test]
public void TestDeleteDifficultyWithPendingChanges()
{
Guid deletedDifficultyID = Guid.Empty;
int countBeforeDeletion = 0;
string beatmapSetHashBefore = string.Empty;
AddUntilStep("wait for editor to load", () => Editor?.ReadyForUse == true);
AddStep("store selected difficulty", () =>
{
deletedDifficultyID = EditorBeatmap.BeatmapInfo.ID;
countBeforeDeletion = Beatmap.Value.BeatmapSetInfo.Beatmaps.Count;
beatmapSetHashBefore = Beatmap.Value.BeatmapSetInfo.Hash;
});
AddStep("make change to difficulty", () =>
{
EditorBeatmap.BeginChange();
EditorBeatmap.BeatmapInfo.DifficultyName = "changin' things";
EditorBeatmap.EndChange();
});
AddStep("click File", () => this.ChildrenOfType<DrawableOsuMenuItem>().First().TriggerClick());
AddStep("click delete", () => getDeleteMenuItem().TriggerClick());
AddUntilStep("wait for dialog", () => DialogOverlay.CurrentDialog != null);
AddAssert("dialog is deletion confirmation dialog", () => DialogOverlay.CurrentDialog, Is.InstanceOf<DeleteDifficultyConfirmationDialog>);
AddStep("confirm", () => InputManager.Key(Key.Number1));
AddUntilStep("no next dialog", () => DialogOverlay.CurrentDialog == null);
AddUntilStep("switched to different difficulty",
() => this.ChildrenOfType<EditorBeatmap>().SingleOrDefault() != null && EditorBeatmap.BeatmapInfo.ID != deletedDifficultyID);
AddAssert("difficulty is unattached from set",
() => Beatmap.Value.BeatmapSetInfo.Beatmaps.Select(b => b.ID), () => Does.Not.Contain(deletedDifficultyID));
AddAssert("beatmap set difficulty count decreased by one",
() => Beatmap.Value.BeatmapSetInfo.Beatmaps.Count, () => Is.EqualTo(countBeforeDeletion - 1));
AddAssert("set hash changed", () => Beatmap.Value.BeatmapSetInfo.Hash, () => Is.Not.EqualTo(beatmapSetHashBefore));
AddAssert("difficulty is deleted from realm",
() => Realm.Run(r => r.Find<BeatmapInfo>(deletedDifficultyID)), () => Is.Null);
}
private DrawableOsuMenuItem getDeleteMenuItem() => this.ChildrenOfType<DrawableOsuMenuItem>()
.Single(item => item.ChildrenOfType<SpriteText>().Any(text => text.Text.ToString().StartsWith("Delete", StringComparison.Ordinal)));
}

View File

@ -1088,6 +1088,13 @@ namespace osu.Game.Screens.Edit
var difficultiesBeforeDeletion = groupedOrderedBeatmaps.SelectMany(g => g).ToList();
// if the difficulty being currently deleted has unsaved changes,
// the editor exit flow would prompt for save *after* this method has done its thing.
// this is generally undesirable and also ends up leaving the user in a broken state.
// therefore, just update the last saved hash to make the exit flow think the deleted beatmap is not dirty,
// so that it will not show the save dialog on exit.
updateLastSavedHash();
beatmapManager.DeleteDifficultyImmediately(difficultyToDelete);
int deletedIndex = difficultiesBeforeDeletion.IndexOf(difficultyToDelete);