2022-04-04 01:53:05 +08:00
|
|
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
|
|
|
// See the LICENCE file in the repository root for full licence text.
|
|
|
|
|
2022-06-17 15:37:17 +08:00
|
|
|
#nullable disable
|
|
|
|
|
2024-07-11 20:31:23 +08:00
|
|
|
using System;
|
2022-05-06 22:43:24 +08:00
|
|
|
using System.Collections.Generic;
|
2022-04-17 22:54:30 +08:00
|
|
|
using System.Linq;
|
2022-04-04 01:53:05 +08:00
|
|
|
using NUnit.Framework;
|
2022-05-06 22:43:24 +08:00
|
|
|
using osu.Framework.Allocation;
|
|
|
|
using osu.Framework.Bindables;
|
2023-06-06 21:12:31 +08:00
|
|
|
using osu.Framework.Graphics;
|
2022-04-04 01:53:05 +08:00
|
|
|
using osu.Framework.Graphics.Containers;
|
2024-01-13 14:41:53 +08:00
|
|
|
using osu.Framework.Graphics.Sprites;
|
2022-05-15 02:18:44 +08:00
|
|
|
using osu.Framework.Input;
|
2022-04-17 22:54:30 +08:00
|
|
|
using osu.Framework.Testing;
|
|
|
|
using osu.Game.Overlays.Mods;
|
2022-05-07 03:35:22 +08:00
|
|
|
using osu.Game.Rulesets.Osu.Mods;
|
2022-05-06 22:43:24 +08:00
|
|
|
using osu.Game.Rulesets.Mods;
|
2024-07-11 20:31:23 +08:00
|
|
|
using osu.Game.Screens.Footer;
|
2022-04-04 01:53:05 +08:00
|
|
|
using osu.Game.Screens.OnlinePlay;
|
2024-01-13 14:41:53 +08:00
|
|
|
using osu.Game.Utils;
|
2022-05-06 22:43:24 +08:00
|
|
|
using osuTK.Input;
|
2022-04-04 01:53:05 +08:00
|
|
|
|
|
|
|
namespace osu.Game.Tests.Visual.Multiplayer
|
|
|
|
{
|
2022-11-24 13:32:20 +08:00
|
|
|
public partial class TestSceneFreeModSelectOverlay : MultiplayerTestScene
|
2022-04-04 01:53:05 +08:00
|
|
|
{
|
2022-05-11 04:29:57 +08:00
|
|
|
private FreeModSelectOverlay freeModSelectOverlay;
|
2024-01-13 14:41:53 +08:00
|
|
|
private FooterButtonFreeMods footerButtonFreeMods;
|
2024-07-11 20:31:23 +08:00
|
|
|
private ScreenFooter footer;
|
2022-05-06 22:43:24 +08:00
|
|
|
private readonly Bindable<Dictionary<ModType, IReadOnlyList<Mod>>> availableMods = new Bindable<Dictionary<ModType, IReadOnlyList<Mod>>>();
|
|
|
|
|
|
|
|
[BackgroundDependencyLoader]
|
|
|
|
private void load(OsuGameBase osuGameBase)
|
|
|
|
{
|
|
|
|
availableMods.BindTo(osuGameBase.AvailableMods);
|
|
|
|
}
|
2022-05-07 03:35:22 +08:00
|
|
|
|
2022-04-04 01:53:05 +08:00
|
|
|
[Test]
|
|
|
|
public void TestFreeModSelect()
|
|
|
|
{
|
2022-05-07 03:35:22 +08:00
|
|
|
createFreeModSelect();
|
2022-04-17 22:54:30 +08:00
|
|
|
|
2022-04-22 06:07:00 +08:00
|
|
|
AddUntilStep("all visible mods are playable",
|
2022-04-17 22:54:30 +08:00
|
|
|
() => this.ChildrenOfType<ModPanel>()
|
|
|
|
.Where(panel => panel.IsPresent)
|
|
|
|
.All(panel => panel.Mod.HasImplementation && panel.Mod.UserPlayable));
|
|
|
|
|
2022-04-04 01:53:05 +08:00
|
|
|
AddToggleStep("toggle visibility", visible =>
|
|
|
|
{
|
2022-05-11 04:29:57 +08:00
|
|
|
if (freeModSelectOverlay != null)
|
|
|
|
freeModSelectOverlay.State.Value = visible ? Visibility.Visible : Visibility.Hidden;
|
2022-04-04 01:53:05 +08:00
|
|
|
});
|
|
|
|
}
|
2022-05-07 03:35:22 +08:00
|
|
|
|
|
|
|
[Test]
|
|
|
|
public void TestCustomisationNotAvailable()
|
|
|
|
{
|
|
|
|
createFreeModSelect();
|
|
|
|
|
2022-05-11 04:29:57 +08:00
|
|
|
AddStep("select difficulty adjust", () => freeModSelectOverlay.SelectedMods.Value = new[] { new OsuModDifficultyAdjust() });
|
2022-05-07 03:35:22 +08:00
|
|
|
AddWaitStep("wait some", 3);
|
2024-06-23 13:22:54 +08:00
|
|
|
AddAssert("customisation area not expanded", () => !this.ChildrenOfType<ModCustomisationPanel>().Single().Expanded.Value);
|
2022-05-07 03:35:22 +08:00
|
|
|
}
|
|
|
|
|
2023-06-06 21:12:31 +08:00
|
|
|
[Test]
|
|
|
|
public void TestSelectAllButtonUpdatesStateWhenSearchTermChanged()
|
|
|
|
{
|
|
|
|
createFreeModSelect();
|
|
|
|
|
|
|
|
AddStep("apply search term", () => freeModSelectOverlay.SearchTerm = "ea");
|
|
|
|
|
|
|
|
AddAssert("select all button enabled", () => this.ChildrenOfType<SelectAllModsButton>().Single().Enabled.Value);
|
|
|
|
|
|
|
|
AddStep("click select all button", navigateAndClick<SelectAllModsButton>);
|
|
|
|
AddAssert("select all button disabled", () => !this.ChildrenOfType<SelectAllModsButton>().Single().Enabled.Value);
|
|
|
|
|
|
|
|
AddStep("change search term", () => freeModSelectOverlay.SearchTerm = "e");
|
|
|
|
|
|
|
|
AddAssert("select all button enabled", () => this.ChildrenOfType<SelectAllModsButton>().Single().Enabled.Value);
|
|
|
|
|
|
|
|
void navigateAndClick<T>() where T : Drawable
|
|
|
|
{
|
|
|
|
InputManager.MoveMouseTo(this.ChildrenOfType<T>().Single());
|
|
|
|
InputManager.Click(MouseButton.Left);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-15 02:18:44 +08:00
|
|
|
[Test]
|
|
|
|
public void TestSelectDeselectAllViaKeyboard()
|
|
|
|
{
|
|
|
|
createFreeModSelect();
|
|
|
|
|
2023-06-04 22:11:04 +08:00
|
|
|
AddStep("kill search bar focus", () => freeModSelectOverlay.SearchTextBox.KillFocus());
|
|
|
|
|
2022-05-15 02:18:44 +08:00
|
|
|
AddStep("press ctrl+a", () => InputManager.Keys(PlatformAction.SelectAll));
|
|
|
|
AddUntilStep("all mods selected", assertAllAvailableModsSelected);
|
|
|
|
|
|
|
|
AddStep("press backspace", () => InputManager.Key(Key.BackSpace));
|
|
|
|
AddUntilStep("all mods deselected", () => !freeModSelectOverlay.SelectedMods.Value.Any());
|
|
|
|
}
|
|
|
|
|
2022-05-06 22:43:24 +08:00
|
|
|
[Test]
|
|
|
|
public void TestSelectDeselectAll()
|
|
|
|
{
|
|
|
|
createFreeModSelect();
|
|
|
|
|
2022-05-26 04:27:54 +08:00
|
|
|
AddAssert("select all button enabled", () => this.ChildrenOfType<SelectAllModsButton>().Single().Enabled.Value);
|
2022-05-26 03:49:31 +08:00
|
|
|
|
2022-05-06 22:43:24 +08:00
|
|
|
AddStep("click select all button", () =>
|
|
|
|
{
|
2022-05-26 04:27:54 +08:00
|
|
|
InputManager.MoveMouseTo(this.ChildrenOfType<SelectAllModsButton>().Single());
|
2022-05-06 22:43:24 +08:00
|
|
|
InputManager.Click(MouseButton.Left);
|
|
|
|
});
|
|
|
|
AddUntilStep("all mods selected", assertAllAvailableModsSelected);
|
2022-05-26 04:27:54 +08:00
|
|
|
AddAssert("select all button disabled", () => !this.ChildrenOfType<SelectAllModsButton>().Single().Enabled.Value);
|
2022-05-06 22:43:24 +08:00
|
|
|
|
|
|
|
AddStep("click deselect all button", () =>
|
|
|
|
{
|
2022-05-26 04:27:54 +08:00
|
|
|
InputManager.MoveMouseTo(this.ChildrenOfType<DeselectAllModsButton>().Single());
|
2022-05-06 22:43:24 +08:00
|
|
|
InputManager.Click(MouseButton.Left);
|
|
|
|
});
|
2022-05-11 04:29:57 +08:00
|
|
|
AddUntilStep("all mods deselected", () => !freeModSelectOverlay.SelectedMods.Value.Any());
|
2022-05-26 04:27:54 +08:00
|
|
|
AddAssert("select all button enabled", () => this.ChildrenOfType<SelectAllModsButton>().Single().Enabled.Value);
|
2022-05-06 22:43:24 +08:00
|
|
|
}
|
|
|
|
|
2024-01-13 14:41:53 +08:00
|
|
|
[Test]
|
|
|
|
public void TestSelectAllViaFooterButtonThenDeselectFromOverlay()
|
|
|
|
{
|
|
|
|
createFreeModSelect();
|
|
|
|
|
2024-07-11 20:31:23 +08:00
|
|
|
AddAssert("overlay select all button enabled", () => this.ChildrenOfType<SelectAllModsButton>().Single().Enabled.Value);
|
2024-01-13 14:41:53 +08:00
|
|
|
AddAssert("footer button displays off", () => footerButtonFreeMods.ChildrenOfType<IHasText>().Any(t => t.Text == "off"));
|
|
|
|
|
|
|
|
AddStep("click footer select all button", () =>
|
|
|
|
{
|
|
|
|
InputManager.MoveMouseTo(footerButtonFreeMods);
|
|
|
|
InputManager.Click(MouseButton.Left);
|
|
|
|
});
|
|
|
|
|
|
|
|
AddUntilStep("all mods selected", assertAllAvailableModsSelected);
|
|
|
|
AddAssert("footer button displays all", () => footerButtonFreeMods.ChildrenOfType<IHasText>().Any(t => t.Text == "all"));
|
|
|
|
|
|
|
|
AddStep("click deselect all button", () =>
|
|
|
|
{
|
|
|
|
InputManager.MoveMouseTo(this.ChildrenOfType<DeselectAllModsButton>().Single());
|
|
|
|
InputManager.Click(MouseButton.Left);
|
|
|
|
});
|
|
|
|
AddUntilStep("all mods deselected", () => !freeModSelectOverlay.SelectedMods.Value.Any());
|
|
|
|
AddAssert("footer button displays off", () => footerButtonFreeMods.ChildrenOfType<IHasText>().Any(t => t.Text == "off"));
|
|
|
|
}
|
|
|
|
|
2022-05-07 03:35:22 +08:00
|
|
|
private void createFreeModSelect()
|
|
|
|
{
|
2024-07-11 20:31:23 +08:00
|
|
|
AddStep("create free mod select screen", () => Child = new DependencyProvidingContainer
|
2022-05-07 03:35:22 +08:00
|
|
|
{
|
2024-07-11 20:31:23 +08:00
|
|
|
RelativeSizeAxes = Axes.Both,
|
|
|
|
Children = new Drawable[]
|
2024-01-13 14:41:53 +08:00
|
|
|
{
|
2024-07-11 20:31:23 +08:00
|
|
|
freeModSelectOverlay = new FreeModSelectOverlay
|
|
|
|
{
|
|
|
|
State = { Value = Visibility.Visible }
|
|
|
|
},
|
|
|
|
footerButtonFreeMods = new FooterButtonFreeMods(freeModSelectOverlay)
|
|
|
|
{
|
|
|
|
Anchor = Anchor.BottomRight,
|
|
|
|
Origin = Anchor.BottomRight,
|
|
|
|
Y = -ScreenFooter.HEIGHT,
|
|
|
|
Current = { BindTarget = freeModSelectOverlay.SelectedMods },
|
|
|
|
},
|
|
|
|
footer = new ScreenFooter(),
|
2024-01-13 14:41:53 +08:00
|
|
|
},
|
2024-07-11 20:31:23 +08:00
|
|
|
CachedDependencies = new (Type, object)[] { (typeof(ScreenFooter), footer) },
|
2022-05-07 03:35:22 +08:00
|
|
|
});
|
2024-07-11 20:31:23 +08:00
|
|
|
|
2022-05-07 03:35:22 +08:00
|
|
|
AddUntilStep("all column content loaded",
|
2022-05-11 04:29:57 +08:00
|
|
|
() => freeModSelectOverlay.ChildrenOfType<ModColumn>().Any()
|
|
|
|
&& freeModSelectOverlay.ChildrenOfType<ModColumn>().All(column => column.IsLoaded && column.ItemsLoaded));
|
2022-05-07 03:35:22 +08:00
|
|
|
}
|
2022-05-06 22:43:24 +08:00
|
|
|
|
|
|
|
private bool assertAllAvailableModsSelected()
|
|
|
|
{
|
|
|
|
var allAvailableMods = availableMods.Value
|
2023-10-30 22:48:00 +08:00
|
|
|
.Where(pair => pair.Key != ModType.System)
|
2024-01-13 14:41:53 +08:00
|
|
|
.SelectMany(pair => ModUtils.FlattenMods(pair.Value))
|
2022-05-06 22:43:24 +08:00
|
|
|
.Where(mod => mod.UserPlayable && mod.HasImplementation)
|
|
|
|
.ToList();
|
|
|
|
|
2024-01-13 14:41:53 +08:00
|
|
|
if (freeModSelectOverlay.SelectedMods.Value.Count != allAvailableMods.Count)
|
|
|
|
return false;
|
|
|
|
|
2022-05-06 22:43:24 +08:00
|
|
|
foreach (var availableMod in allAvailableMods)
|
|
|
|
{
|
2022-05-11 04:29:57 +08:00
|
|
|
if (freeModSelectOverlay.SelectedMods.Value.All(selectedMod => selectedMod.GetType() != availableMod.GetType()))
|
2022-05-06 22:43:24 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2022-04-04 01:53:05 +08:00
|
|
|
}
|
|
|
|
}
|