10 "github.com/shazow/ssh-chat/chat/message"
14 type MockScreen struct {
18 func (s *MockScreen) Write(data []byte) (n int, err error) {
19 s.buffer = append(s.buffer, data...)
23 func (s *MockScreen) Read(p *[]byte) (n int, err error) {
29 func (s *MockScreen) Close() error {
33 func TestRoomServe(t *testing.T) {
35 ch.Send(message.NewAnnounceMsg("hello"))
37 received := <-ch.broadcast
38 actual := received.String()
39 expected := " * hello"
41 if actual != expected {
42 t.Errorf("Got: %q; Expected: %q", actual, expected)
46 type ScreenedUser struct {
51 func TestIgnore(t *testing.T) {
58 // Create 3 users, join the room and clear their screen buffers
59 users := make([]ScreenedUser, 3)
60 for i := 0; i < 3; i++ {
61 screen := &MockScreen{}
62 user := message.NewUserScreen(message.SimpleID(fmt.Sprintf("user%d", i)), screen)
63 users[i] = ScreenedUser{
68 _, err := ch.Join(user)
74 for _, u := range users {
75 for i := 0; i < 3; i++ {
76 u.user.HandleMsg(u.user.ConsumeOne())
77 u.screen.Read(&buffer)
81 // Use some handy variable names for distinguish between roles
86 // test ignoring unexisting user
87 if err := sendCommand("/ignore test", ignorer, ch, &buffer); err != nil {
90 expectOutput(t, buffer, "-> Err: user not found: test"+message.Newline)
92 // test ignoring existing user
93 if err := sendCommand("/ignore "+ignored.user.Name(), ignorer, ch, &buffer); err != nil {
96 expectOutput(t, buffer, "-> Ignoring: "+ignored.user.Name()+message.Newline)
98 // ignoring the same user twice returns an error message and doesn't add the user twice
99 if err := sendCommand("/ignore "+ignored.user.Name(), ignorer, ch, &buffer); err != nil {
102 expectOutput(t, buffer, "-> Err: user already ignored: user1"+message.Newline)
103 if ignoredList := ignorer.user.Ignored.ListPrefix(""); len(ignoredList) != 1 {
104 t.Fatalf("should have %d ignored users, has %d", 1, len(ignoredList))
107 // when a message is sent from the ignored user, it is delivered to non-ignoring users
108 ch.Send(message.NewPublicMsg("hello", ignored.user))
109 other.user.HandleMsg(other.user.ConsumeOne())
110 other.screen.Read(&buffer)
111 expectOutput(t, buffer, ignored.user.Name()+": hello"+message.Newline)
113 // ensure ignorer doesn't have received any message
114 if ignorer.user.HasMessages() {
115 t.Fatal("should not have messages")
118 // `/ignore` returns a list of ignored users
119 if err := sendCommand("/ignore", ignorer, ch, &buffer); err != nil {
122 expectOutput(t, buffer, "-> 1 ignored: "+ignored.user.Name()+message.Newline)
124 // `/unignore [USER]` removes the user from ignored ones
125 if err := sendCommand("/unignore "+ignored.user.Name(), users[0], ch, &buffer); err != nil {
128 expectOutput(t, buffer, "-> No longer ignoring: user1"+message.Newline)
130 if err := sendCommand("/ignore", users[0], ch, &buffer); err != nil {
133 expectOutput(t, buffer, "-> 0 users ignored."+message.Newline)
135 if ignoredList := ignorer.user.Ignored.ListPrefix(""); len(ignoredList) != 0 {
136 t.Fatalf("should have %d ignored users, has %d", 0, len(ignoredList))
139 // after unignoring a user, its messages can be received again
140 ch.Send(message.NewPublicMsg("hello again!", ignored.user))
142 // give some time for the channel to get the message
145 // ensure ignorer has received the message
146 if !ignorer.user.HasMessages() {
147 // FIXME: This is flaky :/
148 t.Fatal("should have messages")
150 ignorer.user.HandleMsg(ignorer.user.ConsumeOne())
151 ignorer.screen.Read(&buffer)
152 expectOutput(t, buffer, ignored.user.Name()+": hello again!"+message.Newline)
155 func expectOutput(t *testing.T, buffer []byte, expected string) {
156 bytes := []byte(expected)
157 if !reflect.DeepEqual(buffer, bytes) {
158 t.Errorf("Got: %q; Expected: %q", buffer, expected)
162 func sendCommand(cmd string, mock ScreenedUser, room *Room, buffer *[]byte) error {
163 msg, ok := message.NewPublicMsg(cmd, mock.user).ParseCommand()
165 return errors.New("cannot parse command message")
169 mock.user.HandleMsg(mock.user.ConsumeOne())
170 mock.screen.Read(buffer)
175 func TestRoomJoin(t *testing.T) {
176 var expected, actual []byte
179 u := message.NewUserScreen(message.SimpleID("foo"), s)
190 u.HandleMsg(u.ConsumeOne())
191 expected = []byte(" * foo joined. (Connected: 1)" + message.Newline)
193 if !reflect.DeepEqual(actual, expected) {
194 t.Errorf("Got: %q; Expected: %q", actual, expected)
197 ch.Send(message.NewSystemMsg("hello", u))
198 u.HandleMsg(u.ConsumeOne())
199 expected = []byte("-> hello" + message.Newline)
201 if !reflect.DeepEqual(actual, expected) {
202 t.Errorf("Got: %q; Expected: %q", actual, expected)
205 ch.Send(message.ParseInput("/me says hello.", u))
206 u.HandleMsg(u.ConsumeOne())
207 expected = []byte("** foo says hello." + message.Newline)
209 if !reflect.DeepEqual(actual, expected) {
210 t.Errorf("Got: %q; Expected: %q", actual, expected)
214 func TestRoomDoesntBroadcastAnnounceMessagesWhenQuiet(t *testing.T) {
215 u := message.NewUser(message.SimpleID("foo"))
216 u.SetConfig(message.UserConfig{
228 // Drain the initial Join message
234 msg := u.ConsumeChan()
235 if _, ok := msg.(*message.AnnounceMsg); ok {
236 t.Errorf("Got unexpected `%T`", msg)
243 // Call with an AnnounceMsg and all the other types
244 // and assert we received only non-announce messages
245 ch.HandleMsg(message.NewAnnounceMsg("Ignored"))
246 // Assert we still get all other types of messages
247 ch.HandleMsg(message.NewEmoteMsg("hello", u))
248 ch.HandleMsg(message.NewSystemMsg("hello", u))
249 ch.HandleMsg(message.NewPrivateMsg("hello", u, u))
250 ch.HandleMsg(message.NewPublicMsg("hello", u))
253 func TestRoomQuietToggleBroadcasts(t *testing.T) {
254 u := message.NewUser(message.SimpleID("foo"))
255 u.SetConfig(message.UserConfig{
267 // Drain the initial Join message
270 u.SetConfig(message.UserConfig{
274 expectedMsg := message.NewAnnounceMsg("Ignored")
275 ch.HandleMsg(expectedMsg)
276 msg := u.ConsumeOne()
277 if _, ok := msg.(*message.AnnounceMsg); !ok {
278 t.Errorf("Got: `%T`; Expected: `%T`", msg, expectedMsg)
281 u.SetConfig(message.UserConfig{
285 ch.HandleMsg(message.NewAnnounceMsg("Ignored"))
286 ch.HandleMsg(message.NewSystemMsg("hello", u))
288 if _, ok := msg.(*message.AnnounceMsg); ok {
289 t.Errorf("Got unexpected `%T`", msg)
293 func TestQuietToggleDisplayState(t *testing.T) {
294 var expected, actual []byte
297 u := message.NewUserScreen(message.SimpleID("foo"), s)
308 u.HandleMsg(u.ConsumeOne())
309 expected = []byte(" * foo joined. (Connected: 1)" + message.Newline)
311 if !reflect.DeepEqual(actual, expected) {
312 t.Errorf("Got: %q; Expected: %q", actual, expected)
315 ch.Send(message.ParseInput("/quiet", u))
317 u.HandleMsg(u.ConsumeOne())
318 expected = []byte("-> Quiet mode is toggled ON" + message.Newline)
320 if !reflect.DeepEqual(actual, expected) {
321 t.Errorf("Got: %q; Expected: %q", actual, expected)
324 ch.Send(message.ParseInput("/quiet", u))
326 u.HandleMsg(u.ConsumeOne())
327 expected = []byte("-> Quiet mode is toggled OFF" + message.Newline)
329 if !reflect.DeepEqual(actual, expected) {
330 t.Errorf("Got: %q; Expected: %q", actual, expected)
334 func TestRoomNames(t *testing.T) {
335 var expected, actual []byte
338 u := message.NewUserScreen(message.SimpleID("foo"), s)
349 u.HandleMsg(u.ConsumeOne())
350 expected = []byte(" * foo joined. (Connected: 1)" + message.Newline)
352 if !reflect.DeepEqual(actual, expected) {
353 t.Errorf("Got: %q; Expected: %q", actual, expected)
356 ch.Send(message.ParseInput("/names", u))
358 u.HandleMsg(u.ConsumeOne())
359 expected = []byte("-> 1 connected: foo" + message.Newline)
361 if !reflect.DeepEqual(actual, expected) {
362 t.Errorf("Got: %q; Expected: %q", actual, expected)