diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs index 78bc51e47b..519d76fc93 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs @@ -1,9 +1,24 @@ // 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.Audio; +using osu.Framework.Platform; +using osu.Framework.Screens; +using osu.Framework.Testing; +using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; +using osu.Game.Online.Rooms; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Osu; using osu.Game.Screens.OnlinePlay.Components; +using osu.Game.Screens.OnlinePlay.Multiplayer.Match; +using osu.Game.Tests.Beatmaps; +using osu.Game.Tests.Resources; +using osu.Game.Users; +using osuTK.Input; namespace osu.Game.Tests.Visual.Multiplayer { @@ -11,7 +26,85 @@ public class TestSceneMultiplayer : ScreenTestScene { private TestMultiplayer multiplayerScreen; + private BeatmapManager beatmaps; + private RulesetStore rulesets; + private BeatmapSetInfo importedSet; + + private TestMultiplayerClient client => multiplayerScreen.Client; + private Room room => client.APIRoom; + public TestSceneMultiplayer() + { + loadMultiplayer(); + } + + [BackgroundDependencyLoader] + private void load(GameHost host, AudioManager audio) + { + Dependencies.Cache(rulesets = new RulesetStore(ContextFactory)); + Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, host, Beatmap.Default)); + beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait(); + + importedSet = beatmaps.GetAllUsableBeatmapSetsEnumerable(IncludedDetails.All).First(); + } + + [Test] + public void TestMatchStartWhileSpectatingWithNoBeatmap() + { + loadMultiplayer(); + + AddStep("open room", () => + { + multiplayerScreen.OpenNewRoom(new Room + { + Name = { Value = "Test Room" }, + Playlist = + { + new PlaylistItem + { + Beatmap = { Value = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo }, + Ruleset = { Value = new OsuRuleset().RulesetInfo }, + } + } + }); + }); + + AddStep("create room", () => + { + InputManager.MoveMouseTo(this.ChildrenOfType().Single()); + InputManager.Click(MouseButton.Left); + }); + + AddUntilStep("wait for join", () => client.Room != null); + + AddStep("join other user (ready, host)", () => + { + client.AddUser(new User { Id = MultiplayerTestScene.PLAYER_1_ID, Username = "Other" }); + client.TransferHost(MultiplayerTestScene.PLAYER_1_ID); + client.ChangeUserState(MultiplayerTestScene.PLAYER_1_ID, MultiplayerUserState.Ready); + }); + + AddStep("change playlist", () => + { + room.Playlist.Add(new PlaylistItem + { + Beatmap = { Value = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo }, + Ruleset = { Value = new OsuRuleset().RulesetInfo }, + }); + }); + + AddStep("click spectate button", () => + { + InputManager.MoveMouseTo(this.ChildrenOfType().Single()); + InputManager.Click(MouseButton.Left); + }); + + AddStep("start match externally", () => client.StartMatch()); + + AddAssert("screen not changed", () => multiplayerScreen.IsCurrentScreen()); + } + + private void loadMultiplayer() { AddStep("show", () => { diff --git a/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs b/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs index de77a15da0..167cf705a7 100644 --- a/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs +++ b/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs @@ -25,6 +25,8 @@ public class TestMultiplayerClient : StatefulMultiplayerClient public override IBindable IsConnected => isConnected; private readonly Bindable isConnected = new Bindable(true); + public Room? APIRoom { get; private set; } + public Action? RoomSetupAction; [Resolved] @@ -138,10 +140,16 @@ protected override Task JoinRoom(long roomId) RoomSetupAction?.Invoke(room); RoomSetupAction = null; + APIRoom = apiRoom; + return Task.FromResult(room); } - protected override Task LeaveRoomInternal() => Task.CompletedTask; + protected override Task LeaveRoomInternal() + { + APIRoom = null; + return Task.CompletedTask; + } public override Task TransferHost(int userId) => ((IMultiplayerClient)this).HostChanged(userId);