// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Testing; using osu.Framework.Utils; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.Mods; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Mods; using osuTK.Input; namespace osu.Game.Tests.Visual.UserInterface { [TestFixture] public class TestSceneModSelectScreen : OsuManualInputManagerTestScene { [Resolved] private RulesetStore rulesetStore { get; set; } private UserModSelectScreen modSelectScreen; [SetUpSteps] public void SetUpSteps() { AddStep("clear contents", Clear); AddStep("reset ruleset", () => Ruleset.Value = rulesetStore.GetRuleset(0)); AddStep("reset mods", () => SelectedMods.SetDefault()); } private void createScreen() { AddStep("create screen", () => Child = modSelectScreen = new UserModSelectScreen { RelativeSizeAxes = Axes.Both, State = { Value = Visibility.Visible }, SelectedMods = { BindTarget = SelectedMods } }); waitForColumnLoad(); } [Test] public void TestStateChange() { createScreen(); AddStep("toggle state", () => modSelectScreen.ToggleVisibility()); } [Test] public void TestPreexistingSelection() { AddStep("set mods", () => SelectedMods.Value = new Mod[] { new OsuModAlternate(), new OsuModDaycore() }); createScreen(); AddUntilStep("two panels active", () => modSelectScreen.ChildrenOfType().Count(panel => panel.Active.Value) == 2); AddAssert("mod multiplier correct", () => { double multiplier = SelectedMods.Value.Aggregate(1d, (m, mod) => m * mod.ScoreMultiplier); return Precision.AlmostEquals(multiplier, modSelectScreen.ChildrenOfType().Single().Current.Value); }); assertCustomisationToggleState(disabled: false, active: false); } [Test] public void TestExternalSelection() { createScreen(); AddStep("set mods", () => SelectedMods.Value = new Mod[] { new OsuModAlternate(), new OsuModDaycore() }); AddUntilStep("two panels active", () => modSelectScreen.ChildrenOfType().Count(panel => panel.Active.Value) == 2); AddAssert("mod multiplier correct", () => { double multiplier = SelectedMods.Value.Aggregate(1d, (m, mod) => m * mod.ScoreMultiplier); return Precision.AlmostEquals(multiplier, modSelectScreen.ChildrenOfType().Single().Current.Value); }); assertCustomisationToggleState(disabled: false, active: false); } [Test] public void TestRulesetChange() { createScreen(); changeRuleset(0); changeRuleset(1); changeRuleset(2); changeRuleset(3); } [Test] public void TestCustomisationToggleState() { createScreen(); assertCustomisationToggleState(disabled: true, active: false); AddStep("select customisable mod", () => SelectedMods.Value = new[] { new OsuModDoubleTime() }); assertCustomisationToggleState(disabled: false, active: false); AddStep("select mod requiring configuration", () => SelectedMods.Value = new[] { new OsuModDifficultyAdjust() }); assertCustomisationToggleState(disabled: false, active: true); AddStep("dismiss mod customisation", () => { InputManager.MoveMouseTo(modSelectScreen.ChildrenOfType().Single()); InputManager.Click(MouseButton.Left); }); AddStep("append another mod not requiring config", () => SelectedMods.Value = SelectedMods.Value.Append(new OsuModFlashlight()).ToArray()); assertCustomisationToggleState(disabled: false, active: false); AddStep("select mod without configuration", () => SelectedMods.Value = new[] { new OsuModAutoplay() }); assertCustomisationToggleState(disabled: true, active: false); AddStep("select mod requiring configuration", () => SelectedMods.Value = new[] { new OsuModDifficultyAdjust() }); assertCustomisationToggleState(disabled: false, active: true); AddStep("select mod without configuration", () => SelectedMods.Value = new[] { new OsuModAutoplay() }); assertCustomisationToggleState(disabled: true, active: false); // config was dismissed without explicit user action. } private void waitForColumnLoad() => AddUntilStep("all column content loaded", () => modSelectScreen.ChildrenOfType().Any() && modSelectScreen.ChildrenOfType().All(column => column.IsLoaded && column.ItemsLoaded)); private void changeRuleset(int id) { AddStep($"set ruleset to {id}", () => Ruleset.Value = rulesetStore.GetRuleset(id)); waitForColumnLoad(); } private void assertCustomisationToggleState(bool disabled, bool active) { ShearedToggleButton getToggle() => modSelectScreen.ChildrenOfType().Single(); AddAssert($"customisation toggle is {(disabled ? "" : "not ")}disabled", () => getToggle().Active.Disabled == disabled); AddAssert($"customisation toggle is {(active ? "" : "not ")}active", () => getToggle().Active.Value == active); } } }