1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-16 02:11:05 +08:00
osu-lazer/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs
Bartłomiej Dach 8b04455c29
Fix chat overlay tests
Not entirely sure why they were failing previously, but the most likely
explanation is that by freak accident some mock requests would
previously execute immediately rather than be scheduled on the API
thread, which would change execution ordering and ensure that
`ChannelManager.CurrentChannel` would become the joined channel, rather
than remaining at the channel listing.
2024-08-30 14:57:15 +02:00

774 lines
33 KiB
C#

// 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.
#nullable disable
using System;
using System.Linq;
using System.Collections.Generic;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input;
using osu.Framework.Logging;
using osu.Framework.Testing;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Chat;
using osu.Game.Overlays;
using osu.Game.Overlays.Chat;
using osu.Game.Overlays.Chat.Listing;
using osu.Game.Overlays.Chat.ChannelList;
using osuTK;
using osuTK.Input;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Tests.Resources;
namespace osu.Game.Tests.Visual.Online
{
[TestFixture]
public partial class TestSceneChatOverlay : OsuManualInputManagerTestScene
{
private TestChatOverlay chatOverlay;
private ChannelManager channelManager;
private readonly APIUser testUser = new APIUser { Username = "test user", Id = 5071479 };
private readonly APIUser testUser1 = new APIUser { Username = "test user", Id = 5071480 };
private Channel[] testChannels;
private Message[] initialMessages;
private Channel testChannel1 => testChannels[0];
private Channel testChannel2 => testChannels[1];
[Resolved]
private OsuConfigManager config { get; set; } = null!;
private int currentMessageId;
private DummyAPIAccess dummyAPI => (DummyAPIAccess)API;
private readonly ManualResetEventSlim requestLock = new ManualResetEventSlim();
[SetUp]
public void SetUp() => Schedule(() =>
{
currentMessageId = 0;
testChannels = Enumerable.Range(1, 10).Select(createPublicChannel).ToArray();
initialMessages = testChannels.SelectMany(createChannelMessages).ToArray();
Child = new DependencyProvidingContainer
{
RelativeSizeAxes = Axes.Both,
CachedDependencies = new (Type, object)[]
{
(typeof(ChannelManager), channelManager = new ChannelManager(API)),
},
Children = new Drawable[]
{
channelManager,
chatOverlay = new TestChatOverlay(),
},
};
});
[SetUpSteps]
public void SetUpSteps()
{
AddStep("Setup request handler", () =>
{
((DummyAPIAccess)API).HandleRequest = req =>
{
switch (req)
{
case CreateChannelRequest createRequest:
createRequest.TriggerSuccess(new APIChatChannel
{
ChannelID = ((int)createRequest.Channel.Id),
RecentMessages = new List<Message>()
});
return true;
case GetUpdatesRequest getUpdates:
getUpdates.TriggerFailure(new WebException());
return true;
case JoinChannelRequest joinChannel:
joinChannel.TriggerSuccess();
return true;
case LeaveChannelRequest leaveChannel:
leaveChannel.TriggerSuccess();
return true;
case GetMessagesRequest getMessages:
getMessages.TriggerSuccess(initialMessages.ToList());
return true;
case GetUserRequest getUser:
if (getUser.Lookup == testUser.Username)
getUser.TriggerSuccess(testUser);
else
getUser.TriggerFailure(new WebException());
return true;
case PostMessageRequest postMessage:
postMessage.TriggerSuccess(new Message(TestResources.GetNextTestID())
{
Content = postMessage.Message.Content,
ChannelId = postMessage.Message.ChannelId,
Sender = postMessage.Message.Sender,
Timestamp = new DateTimeOffset(DateTime.Now),
});
return true;
default:
Logger.Log($"Unhandled Request Type: {req.GetType()}");
return false;
}
};
});
AddStep("Add test channels", () =>
{
(channelManager.AvailableChannels as BindableList<Channel>)?.AddRange(testChannels);
});
}
[Test]
public void TestBasic()
{
AddStep("Show overlay with channel", () =>
{
chatOverlay.Show();
Channel joinedChannel = channelManager.JoinChannel(testChannel1);
channelManager.CurrentChannel.Value = joinedChannel;
});
AddAssert("Overlay is visible", () => chatOverlay.State.Value == Visibility.Visible);
waitForChannel1Visible();
}
[Test]
public void TestShowHide()
{
AddStep("Show overlay", () => chatOverlay.Show());
AddAssert("Overlay is visible", () => chatOverlay.State.Value == Visibility.Visible);
AddStep("Hide overlay", () => chatOverlay.Hide());
AddAssert("Overlay is hidden", () => chatOverlay.State.Value == Visibility.Hidden);
}
[Test]
public void TestChatHeight()
{
BindableFloat configChatHeight = new BindableFloat();
float newHeight = 0;
AddStep("Reset config chat height", () =>
{
config.BindWith(OsuSetting.ChatDisplayHeight, configChatHeight);
configChatHeight.SetDefault();
});
AddStep("Show overlay", () => chatOverlay.Show());
AddAssert("Overlay uses config height", () => chatOverlay.Height == configChatHeight.Default);
AddStep("Move mouse to drag bar", () => InputManager.MoveMouseTo(chatOverlayTopBar.DragBar));
AddStep("Click drag bar", () => InputManager.PressButton(MouseButton.Left));
AddStep("Drag overlay to new height", () => InputManager.MoveMouseTo(chatOverlayTopBar, new Vector2(0, -300)));
AddStep("Stop dragging", () => InputManager.ReleaseButton(MouseButton.Left));
AddStep("Store new height", () => newHeight = chatOverlay.Height);
AddAssert("Config height changed", () => !configChatHeight.IsDefault && configChatHeight.Value == newHeight);
AddStep("Hide overlay", () => chatOverlay.Hide());
AddStep("Show overlay", () => chatOverlay.Show());
AddAssert("Overlay uses new height", () => chatOverlay.Height == newHeight);
}
[Test]
public void TestChannelSelection()
{
AddStep("Show overlay", () => chatOverlay.Show());
AddAssert("Listing is visible", () => listingIsVisible);
joinTestChannel(0);
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
waitForChannel1Visible();
}
[Test]
public void TestSearchInListing()
{
AddStep("Show overlay", () => chatOverlay.Show());
AddAssert("Listing is visible", () => listingIsVisible);
AddStep("Search for 'number 2'", () => chatOverlayTextBox.Text = "number 2");
AddUntilStep("Only channel 2 visible", () =>
{
IEnumerable<ChannelListingItem> listingItems = chatOverlay.ChildrenOfType<ChannelListingItem>()
.Where(item => item.IsPresent);
return listingItems.Count() == 1 && listingItems.Single().Channel == testChannel2;
});
}
[Test]
public void TestChannelCloseButton()
{
var testPMChannel = new Channel(testUser);
AddStep("Show overlay", () => chatOverlay.Show());
joinTestChannel(0);
joinChannel(testPMChannel);
AddStep("Select PM channel", () => clickDrawable(getChannelListItem(testPMChannel)));
AddStep("Click close button", () =>
{
ChannelListItemCloseButton closeButton = getChannelListItem(testPMChannel).ChildrenOfType<ChannelListItemCloseButton>().Single();
clickDrawable(closeButton);
});
AddAssert("PM channel closed", () => !channelManager.JoinedChannels.Contains(testPMChannel));
AddStep("Select normal channel", () => clickDrawable(getChannelListItem(testChannel1)));
AddStep("Click close button", () =>
{
ChannelListItemCloseButton closeButton = getChannelListItem(testChannel1).ChildrenOfType<ChannelListItemCloseButton>().Single();
clickDrawable(closeButton);
});
AddAssert("Normal channel closed", () => !channelManager.JoinedChannels.Contains(testChannel1));
}
[Test]
public void TestChatCommand()
{
AddStep("Show overlay", () => chatOverlay.Show());
joinTestChannel(0);
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
AddStep("Open chat with user", () => channelManager.PostCommand($"chat {testUser.Username}"));
AddAssert("PM channel is selected", () =>
channelManager.CurrentChannel.Value.Type == ChannelType.PM && channelManager.CurrentChannel.Value.Users.Single() == testUser);
AddStep("Open chat with non-existent user", () => channelManager.PostCommand("chat user_doesnt_exist"));
AddAssert("Last message is error", () => channelManager.CurrentChannel.Value.Messages.Last() is ErrorMessage);
// Make sure no unnecessary requests are made when the PM channel is already open.
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
AddStep("Unregister request handling", () => ((DummyAPIAccess)API).HandleRequest = null);
AddStep("Open chat with user", () => channelManager.PostCommand($"chat {testUser.Username}"));
AddAssert("PM channel is selected", () =>
channelManager.CurrentChannel.Value.Type == ChannelType.PM && channelManager.CurrentChannel.Value.Users.Single() == testUser);
}
[Test]
public void TestMultiplayerChannelIsNotShown()
{
Channel multiplayerChannel;
AddStep("Show overlay", () => chatOverlay.Show());
joinChannel(multiplayerChannel = new Channel(new APIUser())
{
Name = "#mp_1",
Type = ChannelType.Multiplayer,
});
AddAssert("Channel is joined", () => channelManager.JoinedChannels.Contains(multiplayerChannel));
AddUntilStep("Channel not present in listing", () => !chatOverlay.ChildrenOfType<ChannelListingItem>()
.Where(item => item.IsPresent)
.Select(item => item.Channel)
.Contains(multiplayerChannel));
}
[Test]
public void TestHighlightOnCurrentChannel()
{
Message message = null;
AddStep("Show overlay", () => chatOverlay.Show());
joinTestChannel(0);
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
AddStep("Send message in channel 1", () =>
{
testChannel1.AddNewMessages(message = new Message
{
ChannelId = testChannel1.Id,
Content = "Message to highlight!",
Timestamp = DateTimeOffset.Now,
Sender = testUser,
});
});
AddStep("Highlight message", () => chatOverlay.HighlightMessage(message, testChannel1));
waitForChannel1Visible();
}
[Test]
public void TestHighlightOnAnotherChannel()
{
Message message = null;
AddStep("Show overlay", () => chatOverlay.Show());
joinTestChannel(0);
joinTestChannel(1);
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
AddStep("Send message in channel 2", () =>
{
testChannel2.AddNewMessages(message = new Message
{
ChannelId = testChannel2.Id,
Content = "Message to highlight!",
Timestamp = DateTimeOffset.Now,
Sender = testUser,
});
});
AddStep("Highlight message", () => chatOverlay.HighlightMessage(message, testChannel2));
waitForChannel2Visible();
}
[Test]
public void TestHighlightOnLeftChannel()
{
Message message = null;
AddStep("Show overlay", () => chatOverlay.Show());
joinTestChannel(0);
joinTestChannel(1);
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
AddStep("Send message in channel 2", () =>
{
testChannel2.AddNewMessages(message = new Message
{
ChannelId = testChannel2.Id,
Content = "Message to highlight!",
Timestamp = DateTimeOffset.Now,
Sender = testUser,
});
});
AddStep("Leave channel 2", () => channelManager.LeaveChannel(testChannel2));
AddStep("Highlight message", () => chatOverlay.HighlightMessage(message, testChannel2));
waitForChannel2Visible();
}
[Test]
public void TestHighlightWhileChatNeverOpen()
{
Message message = null;
joinTestChannel(0);
AddStep("Send message in channel 1", () =>
{
testChannel1.AddNewMessages(message = new Message
{
ChannelId = testChannel1.Id,
Content = "Message to highlight!",
Timestamp = DateTimeOffset.Now,
Sender = testUser,
});
});
AddStep("Highlight message", () => chatOverlay.HighlightMessage(message, testChannel1));
waitForChannel1Visible();
}
[Test]
public void TestHighlightWithNullChannel()
{
Message message = null;
joinTestChannel(0);
AddStep("Send message in channel 1", () =>
{
testChannel1.AddNewMessages(message = new Message
{
ChannelId = testChannel1.Id,
Content = "Message to highlight!",
Timestamp = DateTimeOffset.Now,
Sender = testUser,
});
});
AddStep("Set null channel", () => channelManager.CurrentChannel.Value = null);
AddStep("Highlight message", () => chatOverlay.HighlightMessage(message, testChannel1));
waitForChannel1Visible();
}
[Test]
public void TestTextBoxRetainsFocus()
{
AddStep("Show overlay", () => chatOverlay.Show());
AddAssert("TextBox is focused", () => InputManager.FocusedDrawable == chatOverlayTextBox);
joinTestChannel(0);
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
waitForChannel1Visible();
AddAssert("TextBox is focused", () => InputManager.FocusedDrawable == chatOverlayTextBox);
AddStep("Click drawable channel", () => clickDrawable(currentDrawableChannel));
AddAssert("TextBox is focused", () => InputManager.FocusedDrawable == chatOverlayTextBox);
AddStep("Click selector", () => clickDrawable(channelSelectorButton));
AddAssert("TextBox is focused", () => InputManager.FocusedDrawable == chatOverlayTextBox);
AddStep("Click listing", () => clickDrawable(chatOverlay.ChildrenOfType<ChannelListing>().Single()));
AddAssert("TextBox is focused", () => InputManager.FocusedDrawable == chatOverlayTextBox);
AddStep("Click channel list", () => clickDrawable(chatOverlay.ChildrenOfType<ChannelList>().Single()));
AddAssert("TextBox is focused", () => InputManager.FocusedDrawable == chatOverlayTextBox);
AddStep("Click top bar", () => clickDrawable(chatOverlay.ChildrenOfType<ChatOverlayTopBar>().Single()));
AddAssert("TextBox is focused", () => InputManager.FocusedDrawable == chatOverlayTextBox);
AddStep("Hide overlay", () => chatOverlay.Hide());
AddAssert("TextBox is not focused", () => InputManager.FocusedDrawable == null);
}
[Test]
public void TestSlowLoadingChannel()
{
AddStep("Show overlay (slow-loading)", () =>
{
chatOverlay.Show();
chatOverlay.SlowLoading = true;
});
joinTestChannel(0);
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
AddUntilStep("Channel 1 loading", () => !channelIsVisible && chatOverlay.GetSlowLoadingChannel(testChannel1).LoadState == LoadState.Loading);
joinTestChannel(1);
AddStep("Select channel 2", () => clickDrawable(getChannelListItem(testChannel2)));
AddUntilStep("Channel 2 loading", () => !channelIsVisible && chatOverlay.GetSlowLoadingChannel(testChannel2).LoadState == LoadState.Loading);
AddStep("Finish channel 1 load", () => chatOverlay.GetSlowLoadingChannel(testChannel1).LoadEvent.Set());
AddUntilStep("Channel 1 ready", () => chatOverlay.GetSlowLoadingChannel(testChannel1).LoadState == LoadState.Ready);
AddAssert("Channel 1 not displayed", () => !channelIsVisible);
AddStep("Finish channel 2 load", () => chatOverlay.GetSlowLoadingChannel(testChannel2).LoadEvent.Set());
AddUntilStep("Channel 2 loaded", () => chatOverlay.GetSlowLoadingChannel(testChannel2).IsLoaded);
waitForChannel2Visible();
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
AddUntilStep("Channel 1 loaded", () => chatOverlay.GetSlowLoadingChannel(testChannel1).IsLoaded);
waitForChannel1Visible();
}
[Test]
public void TestKeyboardCloseAndRestoreChannel()
{
AddStep("Show overlay with channel 1", () =>
{
channelManager.CurrentChannel.Value = channelManager.JoinChannel(testChannel1);
chatOverlay.Show();
});
waitForChannel1Visible();
AddStep("Press document close keys", () => InputManager.Keys(PlatformAction.DocumentClose));
AddAssert("Listing is visible", () => listingIsVisible);
AddStep("Press tab restore keys", () => InputManager.Keys(PlatformAction.TabRestore));
waitForChannel1Visible();
}
[Test]
public void TestKeyboardNewChannel()
{
AddStep("Show overlay with channel 1", () =>
{
channelManager.CurrentChannel.Value = channelManager.JoinChannel(testChannel1);
chatOverlay.Show();
});
waitForChannel1Visible();
AddStep("Press tab new keys", () => InputManager.Keys(PlatformAction.TabNew));
AddAssert("Listing is visible", () => listingIsVisible);
}
[Test]
public void TestKeyboardNextChannel()
{
Channel announceChannel = createAnnounceChannel();
Channel pmChannel1 = createPrivateChannel();
Channel pmChannel2 = createPrivateChannel();
joinTestChannel(0);
joinTestChannel(1);
joinChannel(pmChannel1);
joinChannel(pmChannel2);
joinChannel(announceChannel);
AddStep("Show overlay", () => chatOverlay.Show());
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
waitForChannel1Visible();
AddStep("Press document next keys", () => InputManager.Keys(PlatformAction.DocumentNext));
waitForChannel2Visible();
AddStep("Press document next keys", () => InputManager.Keys(PlatformAction.DocumentNext));
AddUntilStep("PM Channel 1 displayed", () => channelIsVisible && currentDrawableChannel?.Channel == pmChannel1);
AddStep("Press document next keys", () => InputManager.Keys(PlatformAction.DocumentNext));
AddUntilStep("PM Channel 2 displayed", () => channelIsVisible && currentDrawableChannel?.Channel == pmChannel2);
AddStep("Press document next keys", () => InputManager.Keys(PlatformAction.DocumentNext));
AddUntilStep("Announce channel displayed", () => channelIsVisible && currentDrawableChannel?.Channel == announceChannel);
AddStep("Press document next keys", () => InputManager.Keys(PlatformAction.DocumentNext));
waitForChannel1Visible();
}
[Test]
public void TestRemoveMessages()
{
AddStep("Show overlay with channel", () =>
{
chatOverlay.Show();
channelManager.CurrentChannel.Value = channelManager.JoinChannel(testChannel1);
});
AddAssert("Overlay is visible", () => chatOverlay.State.Value == Visibility.Visible);
waitForChannel1Visible();
AddStep("Send message from another user", () =>
{
testChannel1.AddNewMessages(new Message
{
ChannelId = testChannel1.Id,
Content = "Message from another user",
Timestamp = DateTimeOffset.Now,
Sender = testUser1,
});
});
AddStep("Remove messages from other user", () =>
{
testChannel1.RemoveMessagesFromUser(testUser.Id);
});
}
[Test]
public void TestTextBoxSavePerChannel()
{
var testPMChannel = new Channel(testUser);
AddStep("show overlay", () => chatOverlay.Show());
joinTestChannel(0);
joinChannel(testPMChannel);
AddAssert("listing is visible", () => listingIsVisible);
AddStep("search for 'number 2'", () => chatOverlayTextBox.Text = "number 2");
AddAssert("'number 2' saved to selector", () => channelManager.CurrentChannel.Value.TextBoxMessage.Value == "number 2");
AddStep("select normal channel", () => clickDrawable(getChannelListItem(testChannel1)));
AddAssert("text box cleared on normal channel", () => chatOverlayTextBox.Text == string.Empty);
AddAssert("nothing saved on normal channel", () => channelManager.CurrentChannel.Value.TextBoxMessage.Value == string.Empty);
AddStep("type '727'", () => chatOverlayTextBox.Text = "727");
AddAssert("'727' saved to normal channel", () => channelManager.CurrentChannel.Value.TextBoxMessage.Value == "727");
AddStep("select PM channel", () => clickDrawable(getChannelListItem(testPMChannel)));
AddAssert("text box cleared on PM channel", () => chatOverlayTextBox.Text == string.Empty);
AddAssert("nothing saved on PM channel", () => channelManager.CurrentChannel.Value.TextBoxMessage.Value == string.Empty);
AddStep("type 'hello'", () => chatOverlayTextBox.Text = "hello");
AddAssert("'hello' saved to PM channel", () => channelManager.CurrentChannel.Value.TextBoxMessage.Value == "hello");
AddStep("select normal channel", () => clickDrawable(getChannelListItem(testChannel1)));
AddAssert("text box contains '727'", () => chatOverlayTextBox.Text == "727");
AddStep("select PM channel", () => clickDrawable(getChannelListItem(testPMChannel)));
AddAssert("text box contains 'hello'", () => chatOverlayTextBox.Text == "hello");
AddStep("click close button", () =>
{
ChannelListItemCloseButton closeButton = getChannelListItem(testPMChannel).ChildrenOfType<ChannelListItemCloseButton>().Single();
clickDrawable(closeButton);
});
AddAssert("listing is visible", () => listingIsVisible);
AddAssert("text box contains 'channel 2'", () => chatOverlayTextBox.Text == "number 2");
AddUntilStep("only channel 2 visible", () =>
{
IEnumerable<ChannelListingItem> listingItems = chatOverlay.ChildrenOfType<ChannelListingItem>()
.Where(item => item.IsPresent);
return listingItems.Count() == 1 && listingItems.Single().Channel == testChannel2;
});
}
[Test]
public void TestChatReport()
{
ChatReportRequest request = null;
AddStep("Show overlay with channel", () =>
{
chatOverlay.Show();
channelManager.CurrentChannel.Value = channelManager.JoinChannel(testChannel1);
});
AddAssert("Overlay is visible", () => chatOverlay.State.Value == Visibility.Visible);
waitForChannel1Visible();
AddStep("Setup request handling", () =>
{
requestLock.Reset();
dummyAPI.HandleRequest = r =>
{
if (!(r is ChatReportRequest req))
return false;
Task.Run(() =>
{
request = req;
requestLock.Wait(10000);
req.TriggerSuccess();
});
return true;
};
});
AddStep("Show report popover", () => this.ChildrenOfType<ChatLine>().First().ShowPopover());
AddStep("Set report reason to other", () =>
{
var reason = this.ChildrenOfType<OsuEnumDropdown<ChatReportReason>>().Single();
reason.Current.Value = ChatReportReason.Other;
});
AddStep("Try to report", () =>
{
var btn = this.ChildrenOfType<ReportChatPopover>().Single().ChildrenOfType<RoundedButton>().Single();
InputManager.MoveMouseTo(btn);
InputManager.Click(MouseButton.Left);
});
AddAssert("Nothing happened", () => this.ChildrenOfType<ReportChatPopover>().Any());
AddStep("Set report data", () =>
{
var field = this.ChildrenOfType<ReportChatPopover>().Single().ChildrenOfType<OsuTextBox>().First();
field.Current.Value = "test other";
});
AddStep("Try to report", () =>
{
var btn = this.ChildrenOfType<ReportChatPopover>().Single().ChildrenOfType<RoundedButton>().Single();
InputManager.MoveMouseTo(btn);
InputManager.Click(MouseButton.Left);
});
AddUntilStep("Overlay closed", () => !this.ChildrenOfType<ReportChatPopover>().Any());
AddStep("Complete request", () => requestLock.Set());
AddUntilStep("Request sent", () => request != null);
AddUntilStep("Info message displayed", () => channelManager.CurrentChannel.Value.Messages.Last(), () => Is.InstanceOf(typeof(InfoMessage)));
}
private void joinTestChannel(int i)
{
AddStep($"Join test channel {i}", () => channelManager.JoinChannel(testChannels[i]));
AddUntilStep("wait for join completed", () => testChannels[i].Joined.Value);
}
private void joinChannel(Channel channel)
{
AddStep($"Join channel {channel}", () => channelManager.JoinChannel(channel));
AddUntilStep("wait for join completed", () => channel.Joined.Value);
}
private void waitForChannel1Visible() =>
AddUntilStep("Channel 1 is visible", () => channelIsVisible && currentDrawableChannel?.Channel == testChannel1);
private void waitForChannel2Visible() =>
AddUntilStep("Channel 2 is visible", () => channelIsVisible && currentDrawableChannel?.Channel == testChannel2);
private bool listingIsVisible =>
chatOverlay.ChildrenOfType<ChannelListing>().Single().State.Value == Visibility.Visible;
private bool loadingIsVisible =>
chatOverlay.ChildrenOfType<LoadingLayer>().Single().State.Value == Visibility.Visible;
private bool channelIsVisible =>
!listingIsVisible && !loadingIsVisible;
[CanBeNull]
private DrawableChannel currentDrawableChannel =>
chatOverlay.ChildrenOfType<DrawableChannel>().SingleOrDefault();
private ChannelListItem getChannelListItem(Channel channel) =>
chatOverlay.ChildrenOfType<ChannelListItem>().Single(item => item.Channel == channel);
private ChatTextBox chatOverlayTextBox =>
chatOverlay.ChildrenOfType<ChatTextBox>().Single();
private ChatOverlayTopBar chatOverlayTopBar =>
chatOverlay.ChildrenOfType<ChatOverlayTopBar>().Single();
private ChannelListItem channelSelectorButton =>
chatOverlay.ChildrenOfType<ChannelListItem>().Single(item => item.Channel is ChannelListing.ChannelListingChannel);
private void clickDrawable(Drawable d)
{
InputManager.MoveMouseTo(d);
InputManager.Click(MouseButton.Left);
}
private List<Message> createChannelMessages(Channel channel)
{
var message = new Message(currentMessageId++)
{
ChannelId = channel.Id,
Content = $"Hello, this is a message in {channel.Name}",
Sender = testUser,
Timestamp = new DateTimeOffset(DateTime.Now),
};
return new List<Message> { message };
}
private Channel createPublicChannel(int id) => new Channel
{
Id = id,
Name = $"#channel-{id}",
Topic = $"We talk about the number {id} here",
Type = ChannelType.Public,
};
private Channel createPrivateChannel()
{
int id = TestResources.GetNextTestID();
return new Channel(new APIUser
{
Id = id,
Username = $"test user {id}",
});
}
private Channel createAnnounceChannel()
{
const int announce_channel_id = 133337;
return new Channel
{
Name = $"Announce {announce_channel_id}",
Type = ChannelType.Announce,
Id = announce_channel_id,
};
}
private partial class TestChatOverlay : ChatOverlay
{
public bool SlowLoading { get; set; }
public SlowLoadingDrawableChannel GetSlowLoadingChannel(Channel channel) => DrawableChannels.OfType<SlowLoadingDrawableChannel>().Single(c => c.Channel == channel);
protected override DrawableChannel CreateDrawableChannel(Channel newChannel)
{
return SlowLoading
? new SlowLoadingDrawableChannel(newChannel)
: new DrawableChannel(newChannel);
}
}
private partial class SlowLoadingDrawableChannel : DrawableChannel
{
public readonly ManualResetEventSlim LoadEvent = new ManualResetEventSlim();
public SlowLoadingDrawableChannel([NotNull] Channel channel)
: base(channel)
{
}
[BackgroundDependencyLoader]
private void load()
{
LoadEvent.Wait(10000);
}
}
}
}