diff --git a/osu.Game.Tests/Visual/Online/TestSceneCurrentlyPlayingDisplay.cs b/osu.Game.Tests/Visual/Online/TestSceneCurrentlyOnlineDisplay.cs similarity index 60% rename from osu.Game.Tests/Visual/Online/TestSceneCurrentlyPlayingDisplay.cs rename to osu.Game.Tests/Visual/Online/TestSceneCurrentlyOnlineDisplay.cs index 5237238f63..7687cd195d 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCurrentlyPlayingDisplay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCurrentlyOnlineDisplay.cs @@ -10,43 +10,50 @@ using osu.Framework.Graphics; using osu.Framework.Testing; using osu.Game.Database; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.Metadata; using osu.Game.Online.Spectator; using osu.Game.Overlays; using osu.Game.Overlays.Dashboard; +using osu.Game.Screens.OnlinePlay.Match.Components; +using osu.Game.Tests.Visual.Metadata; using osu.Game.Tests.Visual.Spectator; using osu.Game.Users; namespace osu.Game.Tests.Visual.Online { - public partial class TestSceneCurrentlyPlayingDisplay : OsuTestScene + public partial class TestSceneCurrentlyOnlineDisplay : OsuTestScene { private readonly APIUser streamingUser = new APIUser { Id = 2, Username = "Test user" }; private TestSpectatorClient spectatorClient = null!; - private CurrentlyPlayingDisplay currentlyPlaying = null!; + private TestMetadataClient metadataClient = null!; + private CurrentlyOnlineDisplay currentlyOnline = null!; [SetUpSteps] public void SetUpSteps() { - AddStep("add streaming client", () => + AddStep("set up components", () => { spectatorClient = new TestSpectatorClient(); + metadataClient = new TestMetadataClient(); var lookupCache = new TestUserLookupCache(); Children = new Drawable[] { lookupCache, spectatorClient, + metadataClient, new DependencyProvidingContainer { RelativeSizeAxes = Axes.Both, CachedDependencies = new (Type, object)[] { (typeof(SpectatorClient), spectatorClient), + (typeof(MetadataClient), metadataClient), (typeof(UserLookupCache), lookupCache), (typeof(OverlayColourProvider), new OverlayColourProvider(OverlayColourScheme.Purple)), }, - Child = currentlyPlaying = new CurrentlyPlayingDisplay + Child = currentlyOnline = new CurrentlyOnlineDisplay { RelativeSizeAxes = Axes.Both, } @@ -58,10 +65,20 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestBasicDisplay() { - AddStep("Add playing user", () => spectatorClient.SendStartPlay(streamingUser.Id, 0)); - AddUntilStep("Panel loaded", () => currentlyPlaying.ChildrenOfType().FirstOrDefault()?.User.Id == 2); - AddStep("Remove playing user", () => spectatorClient.SendEndPlay(streamingUser.Id)); - AddUntilStep("Panel no longer present", () => !currentlyPlaying.ChildrenOfType().Any()); + AddStep("Begin watching user presence", () => metadataClient.BeginWatchingUserPresence()); + AddStep("Add online user", () => metadataClient.UserPresenceUpdated(streamingUser.Id, new UserPresence { Status = UserStatus.Online, Activity = new UserActivity.ChoosingBeatmap() })); + AddUntilStep("Panel loaded", () => currentlyOnline.ChildrenOfType().FirstOrDefault()?.User.Id == 2); + AddAssert("Spectate button disabled", () => currentlyOnline.ChildrenOfType().First().Enabled.Value, () => Is.False); + + AddStep("User began playing", () => spectatorClient.SendStartPlay(streamingUser.Id, 0)); + AddAssert("Spectate button enabled", () => currentlyOnline.ChildrenOfType().First().Enabled.Value, () => Is.True); + + AddStep("User finished playing", () => spectatorClient.SendEndPlay(streamingUser.Id)); + AddAssert("Spectate button disabled", () => currentlyOnline.ChildrenOfType().First().Enabled.Value, () => Is.False); + + AddStep("Remove playing user", () => metadataClient.UserPresenceUpdated(streamingUser.Id, null)); + AddUntilStep("Panel no longer present", () => !currentlyOnline.ChildrenOfType().Any()); + AddStep("End watching user presence", () => metadataClient.EndWatchingUserPresence()); } internal partial class TestUserLookupCache : UserLookupCache diff --git a/osu.Game/Tests/Visual/Metadata/TestMetadataClient.cs b/osu.Game/Tests/Visual/Metadata/TestMetadataClient.cs new file mode 100644 index 0000000000..16cbf879df --- /dev/null +++ b/osu.Game/Tests/Visual/Metadata/TestMetadataClient.cs @@ -0,0 +1,81 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Threading.Tasks; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Game.Online.API; +using osu.Game.Online.Metadata; +using osu.Game.Users; + +namespace osu.Game.Tests.Visual.Metadata +{ + public partial class TestMetadataClient : MetadataClient + { + public override IBindable IsConnected => new BindableBool(true); + + public override IBindable IsWatchingUserPresence => isWatchingUserPresence; + private readonly BindableBool isWatchingUserPresence = new BindableBool(); + + public override IBindableDictionary UserStates => userStates; + private readonly BindableDictionary userStates = new BindableDictionary(); + + [Resolved] + private IAPIProvider api { get; set; } = null!; + + public override Task BeginWatchingUserPresence() + { + isWatchingUserPresence.Value = true; + return Task.CompletedTask; + } + + public override Task EndWatchingUserPresence() + { + isWatchingUserPresence.Value = false; + return Task.CompletedTask; + } + + public override Task UpdateActivity(UserActivity? activity) + { + if (isWatchingUserPresence.Value) + { + userStates.TryGetValue(api.LocalUser.Value.Id, out var localUserPresence); + localUserPresence = localUserPresence with { Activity = activity }; + userStates[api.LocalUser.Value.Id] = localUserPresence; + } + + return Task.CompletedTask; + } + + public override Task UpdateStatus(UserStatus? status) + { + if (isWatchingUserPresence.Value) + { + userStates.TryGetValue(api.LocalUser.Value.Id, out var localUserPresence); + localUserPresence = localUserPresence with { Status = status }; + userStates[api.LocalUser.Value.Id] = localUserPresence; + } + + return Task.CompletedTask; + } + + public override Task UserPresenceUpdated(int userId, UserPresence? presence) + { + if (isWatchingUserPresence.Value) + { + if (presence.HasValue) + userStates[userId] = presence.Value; + else + userStates.Remove(userId); + } + + return Task.CompletedTask; + } + + public override Task GetChangesSince(int queueId) + => Task.FromResult(new BeatmapUpdates(Array.Empty(), queueId)); + + public override Task BeatmapSetsUpdated(BeatmapUpdates updates) => Task.CompletedTask; + } +}