IRC parsing, tokenization, and state handling in C#
1namespace IRCSharp.Tests.State;
2
3[TestClass]
4public class Channel
5{
6 private Server _server;
7
8 [TestInitialize]
9 public void TestInitialize()
10 {
11 _server = new("test");
12 _server.Parse(new("001 nickname"));
13 _server.Parse(new(":nickname JOIN #chan"));
14 }
15
16 [TestMethod]
17 public void JoinSelf()
18 {
19 Assert.IsTrue(_server.Channels.ContainsKey("#chan"));
20 Assert.IsTrue(_server.Users.ContainsKey("nickname"));
21 Assert.AreEqual(1, _server.Channels.Count);
22 Assert.AreEqual(1, _server.Users.Count);
23
24 var user = _server.Users["nickname"];
25 var chan = _server.Channels["#chan"];
26 Assert.IsTrue(chan.Users.ContainsKey(user.NickNameLower));
27 CollectionAssert.AreEqual(new List<string> {chan.NameLower}, user.Channels.ToList());
28 }
29
30 [TestMethod]
31 public void JoinOther()
32 {
33 _server.Parse(new(":other JOIN #chan"));
34
35 Assert.AreEqual(2, _server.Users.Count);
36 Assert.IsTrue(_server.Users.ContainsKey("other"));
37
38 var channel = _server.Channels["#chan"];
39 Assert.AreEqual(2, channel.Users.Count);
40
41 var user = _server.Users["other"];
42 CollectionAssert.AreEqual(new List<string> {channel.NameLower}, user.Channels.ToList());
43 }
44
45 [TestMethod]
46 public void PartSelf()
47 {
48 _server.Parse(new(":nickname PART #chan"));
49
50 Assert.AreEqual(0, _server.Users.Count);
51 Assert.AreEqual(0, _server.Channels.Count);
52 }
53
54 [TestMethod]
55 public void PartOther()
56 {
57 _server.Parse(new(":other JOIN #chan"));
58 _server.Parse(new(":other PART #chan"));
59
60 var user = _server.Users["nickname"];
61 var channel = _server.Channels["#chan"];
62 var chanUser = channel.Users[user.NickNameLower];
63
64 Assert.AreEqual(channel.NameLower, user.Channels.Single());
65 CollectionAssert.AreEqual(new Dictionary<string, IRCStates.User> {{"nickname", user}}, _server.Users);
66 CollectionAssert.AreEqual(new Dictionary<string, IRCStates.Channel> {{"#chan", channel}}, _server.Channels);
67 CollectionAssert.AreEqual(new Dictionary<string, ChannelUser> {{"nickname", chanUser}}, channel.Users);
68 }
69
70 [TestMethod]
71 public void KickSelf()
72 {
73 _server.Parse(new(":nickname KICK #chan nickname"));
74
75 Assert.AreEqual(0, _server.Users.Count);
76 Assert.AreEqual(0, _server.Channels.Count);
77 }
78
79 [TestMethod]
80 public void KickOther()
81 {
82 _server.Parse(new(":other JOIN #chan"));
83 _server.Parse(new(":nickname KICK #chan other"));
84
85 var user = _server.Users["nickname"];
86 var channel = _server.Channels["#chan"];
87 var chanUser = channel.Users[user.NickNameLower];
88
89 Assert.AreEqual(1, _server.Users.Count);
90 Assert.AreEqual(1, _server.Channels.Count);
91 Assert.AreEqual(channel.NameLower, user.Channels.Single());
92 CollectionAssert.AreEqual(new Dictionary<string, ChannelUser> {{user.NickNameLower, chanUser}},
93 channel.Users);
94 }
95
96 [TestMethod]
97 public void QuitSelf()
98 {
99 _server.Parse(new("QUIT :i'm outta here"));
100 Assert.AreEqual(0, _server.Users.Count);
101 Assert.AreEqual(0, _server.Channels.Count);
102 }
103
104 [TestMethod]
105 public void QuitSelfWithSource()
106 {
107 _server.Parse(new(":nickname QUIT :i'm outta here"));
108 Assert.AreEqual(0, _server.Users.Count);
109 Assert.AreEqual(0, _server.Channels.Count);
110 }
111
112 [TestMethod]
113 public void QuitOther()
114 {
115 _server.Parse(new(":other JOIN #chan"));
116 _server.Parse(new(":other QUIT :see ya"));
117 Assert.IsFalse(_server.Users.ContainsKey("other"));
118 }
119
120 [TestMethod]
121 public void TopicText()
122 {
123 _server.Parse(new("332 * #chan :test"));
124 Assert.AreEqual("test", _server.Channels["#chan"].Topic);
125 }
126
127 [TestMethod]
128 public void TopicSetByAt()
129 {
130 var dt = DateTimeOffset.FromUnixTimeSeconds(1584023277).DateTime;
131 _server.Parse(new("333 * #chan other 1584023277"));
132
133 var channel = _server.Channels["#chan"];
134
135 Assert.AreEqual("other", channel.TopicSetter);
136 Assert.AreEqual(dt, channel.TopicTime);
137 }
138
139 [TestMethod]
140 public void TopicCommand()
141 {
142 _server.Parse(new("TOPIC #chan :hello there"));
143 Assert.AreEqual("hello there", _server.Channels["#chan"].Topic);
144 }
145
146 [TestMethod]
147 public void CreationDate()
148 {
149 _server.Parse(new("329 * #chan 1584041889"));
150 Assert.AreEqual(DateTimeOffset.FromUnixTimeSeconds(1584041889).DateTime, _server.Channels["#chan"].Created);
151 }
152
153 [TestMethod]
154 public void NamesCommand()
155 {
156 _server.Parse(new("353 * * #chan :nickname @+other"));
157 Assert.IsTrue(_server.Users.ContainsKey("nickname"));
158 Assert.IsTrue(_server.Users.ContainsKey("other"));
159
160 var user = _server.Users["other"];
161 var channel = _server.Channels["#chan"];
162 var chanUser1 = channel.Users[user.NickNameLower];
163 var chanUser2 = channel.Users[_server.NickNameLower];
164
165 Assert.AreEqual(2, channel.Users.Count);
166 CollectionAssert.AreEqual(chanUser1.Modes, channel.Users[user.NickNameLower].Modes);
167 CollectionAssert.AreEqual(chanUser2.Modes, channel.Users[_server.NickNameLower].Modes);
168 CollectionAssert.AreEqual(new List<string> {"o", "v"}, chanUser1.Modes);
169 Assert.AreEqual(channel.NameLower, user.Channels.Single());
170 }
171
172 [TestMethod]
173 public void UserhostInNames()
174 {
175 _server.Parse(new("353 * * #chan :nickname!user@host other!user2@host2"));
176 Assert.AreEqual("user", _server.UserName);
177 Assert.AreEqual("host", _server.HostName);
178
179 var user = _server.Users["other"];
180 Assert.AreEqual("user2", user.UserName);
181 Assert.AreEqual("host2", user.HostName);
182 }
183
184 [TestMethod]
185 public void NickAfterJoin()
186 {
187 var user = _server.Users["nickname"];
188 var channel = _server.Channels["#chan"];
189 var chanUser = channel.Users[user.NickNameLower];
190 _server.Parse(new(":nickname NICK nickname2"));
191 CollectionAssert.AreEqual(new Dictionary<string, ChannelUser> {{user.NickNameLower, chanUser}},
192 channel.Users);
193 }
194}