namespace IRCSharp.Tests.State; public class Channel { private readonly Server _server = new("test"); public Channel() { _server.Parse(new Line("001 nickname")); _server.Parse(new Line(":nickname JOIN #chan")); } [Test] public async Task JoinSelf() { await Assert.That(_server.Channels).ContainsKey("#chan"); await Assert.That(_server.Users).ContainsKey("nickname"); await Assert.That(_server.Channels).HasCount(1); await Assert.That(_server.Users).HasCount(1); var user = _server.Users["nickname"]; var chan = _server.Channels["#chan"]; await Assert.That(chan.Users).ContainsKey(user.NickNameLower).And.HasCount(1); await Assert.That(user.Channels).Contains(chan.NameLower).And.HasCount(1); } [Test] public async Task JoinOther() { _server.Parse(new Line(":other JOIN #chan")); await Assert.That(_server.Users).HasCount(2); await Assert.That(_server.Users).ContainsKey("other"); var channel = _server.Channels["#chan"]; await Assert.That(channel.Users).HasCount(2); var user = _server.Users["other"]; await Assert.That(user.Channels).Contains(channel.NameLower).And.HasCount(1); } [Test] public async Task PartSelf() { _server.Parse(new Line(":nickname PART #chan")); await Assert.That(_server.Users).IsEmpty(); await Assert.That(_server.Channels).IsEmpty(); } [Test] public async Task PartOther() { _server.Parse(new Line(":other JOIN #chan")); _server.Parse(new Line(":other PART #chan")); var user = _server.Users["nickname"]; var channel = _server.Channels["#chan"]; var chanUser = channel.Users[user.NickNameLower]; await Assert.That(user.Channels).Contains(channel.NameLower).And.HasCount(1); await Assert.That(_server.Users).IsEquivalentTo(new Dictionary {{"nickname", user}}); await Assert.That(_server.Channels).IsEquivalentTo(new Dictionary {{"#chan", channel}}); await Assert.That(channel.Users).IsEquivalentTo(new Dictionary {{"nickname", chanUser}}); } [Test] public async Task KickSelf() { _server.Parse(new Line(":nickname KICK #chan nickname")); await Assert.That(_server.Users).IsEmpty(); await Assert.That(_server.Channels).IsEmpty(); } [Test] public async Task KickOther() { _server.Parse(new Line(":other JOIN #chan")); _server.Parse(new Line(":nickname KICK #chan other")); var user = _server.Users["nickname"]; var channel = _server.Channels["#chan"]; var chanUser = channel.Users[user.NickNameLower]; await Assert.That(_server.Users).HasCount(1); await Assert.That(_server.Channels).HasCount(1); await Assert.That(user.Channels).Contains(channel.NameLower).And.HasCount(1); await Assert.That(channel.Users) .IsEquivalentTo(new Dictionary { { user.NickNameLower, chanUser } }); } [Test] public async Task QuitSelf() { _server.Parse(new Line("QUIT :i'm outta here")); await Assert.That(_server.Users).IsEmpty(); await Assert.That(_server.Channels).IsEmpty(); } [Test] public async Task QuitSelfWithSource() { _server.Parse(new Line(":nickname QUIT :i'm outta here")); await Assert.That(_server.Users).IsEmpty(); await Assert.That(_server.Channels).IsEmpty(); } [Test] public async Task QuitOther() { _server.Parse(new Line(":other JOIN #chan")); _server.Parse(new Line(":other QUIT :see ya")); await Assert.That(_server.Users).DoesNotContainKey("other"); } [Test] public async Task TopicText() { _server.Parse(new Line("332 * #chan :test")); await Assert.That(_server.Channels["#chan"].Topic).IsEqualTo("test"); } [Test] public async Task TopicSetByAt() { var dt = DateTimeOffset.FromUnixTimeSeconds(1584023277).DateTime; _server.Parse(new Line("333 * #chan other 1584023277")); var channel = _server.Channels["#chan"]; await Assert.That(channel.TopicSetter).IsEqualTo("other"); await Assert.That(channel.TopicTime).IsEqualTo(dt); } [Test] public async Task TopicCommand() { _server.Parse(new Line("TOPIC #chan :hello there")); await Assert.That(_server.Channels["#chan"].Topic).IsEqualTo("hello there"); } [Test] public async Task CreationDate() { var dt = DateTimeOffset.FromUnixTimeSeconds(1584041889).DateTime; _server.Parse(new Line("329 * #chan 1584041889")); await Assert.That(_server.Channels["#chan"].Created).IsEqualTo(dt); } [Test] public async Task NamesCommand() { _server.Parse(new Line("353 * * #chan :nickname @+other")); await Assert.That(_server.Users).ContainsKey("nickname"); await Assert.That(_server.Users).ContainsKey("other"); var user = _server.Users["other"]; var channel = _server.Channels["#chan"]; var chanUser1 = channel.Users[user.NickNameLower]; var chanUser2 = channel.Users[_server.NickNameLower]; await Assert.That(channel.Users).HasCount(2); await Assert.That(channel.Users[user.NickNameLower].Modes).IsEqualTo(chanUser1.Modes); await Assert.That(channel.Users[_server.NickNameLower].Modes).IsEqualTo(chanUser2.Modes); await Assert.That(chanUser1.Modes).IsEquivalentTo(["o", "v"]); await Assert.That(user.Channels).Contains(channel.NameLower).And.HasCount(1); } [Test] public async Task UserhostInNames() { _server.Parse(new Line("353 * * #chan :nickname!user@host other!user2@host2")); await Assert.That(_server.UserName).IsEqualTo("user"); await Assert.That(_server.HostName).IsEqualTo("host"); var user = _server.Users["other"]; await Assert.That(user.UserName).IsEqualTo("user2"); await Assert.That(user.HostName).IsEqualTo("host2"); } [Test] public async Task NickAfterJoin() { var user = _server.Users["nickname"]; var channel = _server.Channels["#chan"]; var chanUser = channel.Users[user.NickNameLower]; _server.Parse(new Line(":nickname NICK nickname2")); await Assert.That(channel.Users) .IsEquivalentTo(new Dictionary { { user.NickNameLower, chanUser } }); } }