<commit_before>package chat

import (
	"errors"
	"fmt"
	"reflect"
	"testing"
	"time"

	"github.com/shazow/ssh-chat/chat/message"
	"github.com/shazow/ssh-chat/set"
)

// Used for testing
type MockScreen struct {
	buffer []byte
}

func (s *MockScreen) Write(data []byte) (n int, err error) {
	s.buffer = append(s.buffer, data...)
	return len(data), nil
}

func (s *MockScreen) Read(p *[]byte) (n int, err error) {
	*p = s.buffer
	s.buffer = []byte{}
	return len(*p), nil
}

func (s *MockScreen) Close() error {
	return nil
}

func TestRoomServe(t *testing.T) {
	ch := NewRoom()
	ch.Send(message.NewAnnounceMsg("hello"))

	received := <-ch.broadcast
	actual := received.String()
	expected := " * hello"

	if actual != expected {
		t.Errorf("Got: %q; Expected: %q", actual, expected)
	}
}

type ScreenedUser struct {
	user   *message.User
	screen *MockScreen
}

func TestIgnore(t *testing.T) {
	var buffer []byte

	ch := NewRoom()
	go ch.Serve()
	defer ch.Close()

	// Create 3 users, join the room and clear their screen buffers
	users := make([]ScreenedUser, 3)
	for i := 0; i < 3; i++ {
		screen := &MockScreen{}
		user := message.NewUserScreen(message.SimpleID(fmt.Sprintf("user%d", i)), screen)
		users[i] = ScreenedUser{
			user:   user,
			screen: screen,
		}

		_, err := ch.Join(user)
		if err != nil {
			t.Fatal(err)
		}
	}

	for _, u := range users {
		for i := 0; i < 3; i++ {
			u.user.HandleMsg(u.user.ConsumeOne())
			u.screen.Read(&buffer)
		}
	}

	// Use some handy variable names for distinguish between roles
	ignorer := users[0]
	ignored := users[1]
	other := users[2]

	// test ignoring unexisting user
	if err := sendCommand("/ignore test", ignorer, ch, &buffer); err != nil {
		t.Fatal(err)
	}
	expectOutput(t, buffer, "-> Err: user not found: test"+message.Newline)

	// test ignoring existing user
	if err := sendCommand("/ignore "+ignored.user.Name(), ignorer, ch, &buffer); err != nil {
		t.Fatal(err)
	}
	expectOutput(t, buffer, "-> Ignoring: "+ignored.user.Name()+message.Newline)

	// ignoring the same user twice returns an error message and doesn't add the user twice
	if err := sendCommand("/ignore "+ignored.user.Name(), ignorer, ch, &buffer); err != nil {
		t.Fatal(err)
	}
	expectOutput(t, buffer, "-> Err: user already ignored: user1"+message.Newline)
	if ignoredList := ignorer.user.Ignored.ListPrefix(""); len(ignoredList) != 1 {
		t.Fatalf("should have %d ignored users, has %d", 1, len(ignoredList))
	}

	// ignoring the same user twice returns an error message and doesn't add the user twice
	ch.Send(message.NewEmoteMsg("crying", ignored.user))
	if ignorer.user.HasMessages() {
		t.Fatal("should not have emote messages")
	}

	// when a message is sent from the ignored user, it is delivered to non-ignoring users
	ch.Send(message.NewPublicMsg("hello", ignored.user))
	other.user.HandleMsg(other.user.ConsumeOne())
	other.screen.Read(&buffer)
	expectOutput(t, buffer, ignored.user.Name()+": hello"+message.Newline)

	// ensure ignorer doesn't have received any message
	if ignorer.user.HasMessages() {
		t.Fatal("should not have messages")
	}

	// `/ignore` returns a list of ignored users<commit_msg>Fix test comment<commit_after>package chat

import (
	"errors"
	"fmt"
	"reflect"
	"testing"
	"time"

	"github.com/shazow/ssh-chat/chat/message"
	"github.com/shazow/ssh-chat/set"
)

// Used for testing
type MockScreen struct {
	buffer []byte
}

func (s *MockScreen) Write(data []byte) (n int, err error) {
	s.buffer = append(s.buffer, data...)
	return len(data), nil
}

func (s *MockScreen) Read(p *[]byte) (n int, err error) {
	*p = s.buffer
	s.buffer = []byte{}
	return len(*p), nil
}

func (s *MockScreen) Close() error {
	return nil
}

func TestRoomServe(t *testing.T) {
	ch := NewRoom()
	ch.Send(message.NewAnnounceMsg("hello"))

	received := <-ch.broadcast
	actual := received.String()
	expected := " * hello"

	if actual != expected {
		t.Errorf("Got: %q; Expected: %q", actual, expected)
	}
}

type ScreenedUser struct {
	user   *message.User
	screen *MockScreen
}

func TestIgnore(t *testing.T) {
	var buffer []byte

	ch := NewRoom()
	go ch.Serve()
	defer ch.Close()

	// Create 3 users, join the room and clear their screen buffers
	users := make([]ScreenedUser, 3)
	for i := 0; i < 3; i++ {
		screen := &MockScreen{}
		user := message.NewUserScreen(message.SimpleID(fmt.Sprintf("user%d", i)), screen)
		users[i] = ScreenedUser{
			user:   user,
			screen: screen,
		}

		_, err := ch.Join(user)
		if err != nil {
			t.Fatal(err)
		}
	}

	for _, u := range users {
		for i := 0; i < 3; i++ {
			u.user.HandleMsg(u.user.ConsumeOne())
			u.screen.Read(&buffer)
		}
	}

	// Use some handy variable names for distinguish between roles
	ignorer := users[0]
	ignored := users[1]
	other := users[2]

	// test ignoring unexisting user
	if err := sendCommand("/ignore test", ignorer, ch, &buffer); err != nil {
		t.Fatal(err)
	}
	expectOutput(t, buffer, "-> Err: user not found: test"+message.Newline)

	// test ignoring existing user
	if err := sendCommand("/ignore "+ignored.user.Name(), ignorer, ch, &buffer); err != nil {
		t.Fatal(err)
	}
	expectOutput(t, buffer, "-> Ignoring: "+ignored.user.Name()+message.Newline)

	// ignoring the same user twice returns an error message and doesn't add the user twice
	if err := sendCommand("/ignore "+ignored.user.Name(), ignorer, ch, &buffer); err != nil {
		t.Fatal(err)
	}
	expectOutput(t, buffer, "-> Err: user already ignored: user1"+message.Newline)
	if ignoredList := ignorer.user.Ignored.ListPrefix(""); len(ignoredList) != 1 {
		t.Fatalf("should have %d ignored users, has %d", 1, len(ignoredList))
	}

	// when an emote is sent by an ignored user, it should not be displayed
	ch.Send(message.NewEmoteMsg("crying", ignored.user))
	if ignorer.user.HasMessages() {
		t.Fatal("should not have emote messages")
	}

	// when a message is sent from the ignored user, it is delivered to non-ignoring users
	ch.Send(message.NewPublicMsg("hello", ignored.user))
	other.user.HandleMsg(other.user.ConsumeOne())
	other.screen.Read(&buffer)
	expectOutput(t, buffer, ignored.user.Name()+": hello"+message.Newline)

	// ensure ignorer doesn't have received any message
	if ignorer.user.HasMessages() {
		t.Fatal("should not have messages")
	}

	// `/ignore` returns a list of ignored users
{'fraction_non_alphanumeric': 0.15728186313606635, 'fraction_numerical': 0.003828361780188228, 'mean_word_length': 3.883177570093458, 'pattern_counts': {'":': 2, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4286863', 'n_tokens_mistral': 2316, 'n_tokens_neox': 2186, 'n_words': 626}