1 | package soju
|
---|
2 |
|
---|
3 | import (
|
---|
4 | "net"
|
---|
5 | "testing"
|
---|
6 |
|
---|
7 | "golang.org/x/crypto/bcrypt"
|
---|
8 | "gopkg.in/irc.v3"
|
---|
9 | )
|
---|
10 |
|
---|
11 | const (
|
---|
12 | testUsername = "soju-test-user"
|
---|
13 | testPassword = testUsername
|
---|
14 | )
|
---|
15 |
|
---|
16 | func ircPipe() (ircConn, ircConn) {
|
---|
17 | c1, c2 := net.Pipe()
|
---|
18 | return newNetIRCConn(c1), newNetIRCConn(c2)
|
---|
19 | }
|
---|
20 |
|
---|
21 | func createTempDB(t *testing.T) Database {
|
---|
22 | db, err := OpenSqliteDB("sqlite3", ":memory:")
|
---|
23 | if err != nil {
|
---|
24 | t.Fatalf("failed to create temporary SQLite database: %v", err)
|
---|
25 | }
|
---|
26 | // :memory: will open a separate database for each new connection. Make
|
---|
27 | // sure the sql package only uses a single connection. An alternative
|
---|
28 | // solution is to use "file::memory:?cache=shared".
|
---|
29 | db.(*SqliteDB).db.SetMaxOpenConns(1)
|
---|
30 | return db
|
---|
31 | }
|
---|
32 |
|
---|
33 | func createTestUser(t *testing.T) *Server {
|
---|
34 | db := createTempDB(t)
|
---|
35 |
|
---|
36 | hashed, err := bcrypt.GenerateFromPassword([]byte(testPassword), bcrypt.DefaultCost)
|
---|
37 | if err != nil {
|
---|
38 | t.Fatalf("failed to generate bcrypt hash: %v", err)
|
---|
39 | }
|
---|
40 |
|
---|
41 | record := &User{Username: testUsername, Password: string(hashed)}
|
---|
42 | if err := db.StoreUser(record); err != nil {
|
---|
43 | t.Fatalf("failed to store test user: %v", err)
|
---|
44 | }
|
---|
45 |
|
---|
46 | return NewServer(db)
|
---|
47 | }
|
---|
48 |
|
---|
49 | func expectMessage(t *testing.T, c ircConn, cmd string) *irc.Message {
|
---|
50 | msg, err := c.ReadMessage()
|
---|
51 | if err != nil {
|
---|
52 | t.Fatalf("failed to read IRC message (want %q): %v", cmd, err)
|
---|
53 | }
|
---|
54 | if msg.Command != cmd {
|
---|
55 | t.Fatalf("invalid message received: want %q, got: %v", cmd, msg)
|
---|
56 | }
|
---|
57 | return msg
|
---|
58 | }
|
---|
59 |
|
---|
60 | func authTestUser(t *testing.T, c ircConn) {
|
---|
61 | c.WriteMessage(&irc.Message{
|
---|
62 | Command: "PASS",
|
---|
63 | Params: []string{testPassword},
|
---|
64 | })
|
---|
65 | c.WriteMessage(&irc.Message{
|
---|
66 | Command: "NICK",
|
---|
67 | Params: []string{testUsername},
|
---|
68 | })
|
---|
69 | c.WriteMessage(&irc.Message{
|
---|
70 | Command: "USER",
|
---|
71 | Params: []string{testUsername, "0", "*", testUsername},
|
---|
72 | })
|
---|
73 |
|
---|
74 | expectMessage(t, c, irc.RPL_WELCOME)
|
---|
75 | }
|
---|
76 |
|
---|
77 | func TestServer(t *testing.T) {
|
---|
78 | srv := createTestUser(t)
|
---|
79 | if err := srv.Start(); err != nil {
|
---|
80 | t.Fatalf("failed to start server: %v", err)
|
---|
81 | }
|
---|
82 | defer srv.Shutdown()
|
---|
83 |
|
---|
84 | c, srvConn := ircPipe()
|
---|
85 | defer c.Close()
|
---|
86 | go srv.handle(srvConn)
|
---|
87 |
|
---|
88 | authTestUser(t, c)
|
---|
89 | }
|
---|