github.com/diamondburned/arikawa@v1.3.14/gateway/integration_test.go (about) 1 // +build integration 2 3 package gateway 4 5 import ( 6 "context" 7 "log" 8 "os" 9 "strings" 10 "testing" 11 "time" 12 13 "github.com/diamondburned/arikawa/internal/heart" 14 "github.com/diamondburned/arikawa/utils/wsutil" 15 ) 16 17 func init() { 18 wsutil.WSDebug = func(v ...interface{}) { 19 log.Println(append([]interface{}{"Debug:"}, v...)...) 20 } 21 heart.Debug = func(v ...interface{}) { 22 log.Println(append([]interface{}{"Heart:"}, v...)...) 23 } 24 } 25 26 func TestInvalidToken(t *testing.T) { 27 g, err := NewGateway("bad token") 28 if err != nil { 29 t.Fatal("Failed to make a Gateway:", err) 30 } 31 32 err = g.Open() 33 if err == nil { 34 t.Fatal("Unexpected success while opening with a bad token.") 35 } 36 37 // 4004 Authentication Failed. 38 if strings.Contains(err.Error(), "4004") { 39 return 40 } 41 42 t.Fatal("Unexpected error:", err) 43 } 44 45 func TestIntegration(t *testing.T) { 46 var token = os.Getenv("BOT_TOKEN") 47 if token == "" { 48 t.Fatal("Missing $BOT_TOKEN") 49 } 50 51 wsutil.WSError = func(err error) { 52 t.Error(err) 53 } 54 55 var gateway *Gateway 56 57 // NewGateway should call Start for us. 58 g, err := NewGateway("Bot " + token) 59 if err != nil { 60 t.Fatal("Failed to make a Gateway:", err) 61 } 62 g.AfterClose = func(err error) { 63 log.Println("Closed.") 64 } 65 gateway = g 66 67 if err := g.Open(); err != nil { 68 t.Fatal("Failed to authenticate with Discord:", err) 69 } 70 71 ev := wait(t, gateway.Events) 72 ready, ok := ev.(*ReadyEvent) 73 if !ok { 74 t.Fatal("Event received is not of type Ready:", ev) 75 } 76 77 if gateway.SessionID == "" { 78 t.Fatal("Session ID is empty") 79 } 80 81 log.Println("Bot's username is", ready.User.Username) 82 83 // Sleep past the rate limiter before reconnecting: 84 time.Sleep(5 * time.Second) 85 86 gotimeout(t, func() { 87 // Try and reconnect for 20 seconds maximum. 88 ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) 89 defer cancel() 90 91 if err := gateway.ReconnectCtx(ctx); err != nil { 92 t.Fatal("Unexpected error while reconnecting:", err) 93 } 94 }) 95 96 // Wait for the desired event: 97 gotimeout(t, func() { 98 for ev := range gateway.Events { 99 switch ev.(type) { 100 // Accept only a Resumed event. 101 case *ResumedEvent: 102 return // exit 103 case *ReadyEvent: 104 t.Fatal("Ready event received instead of Resumed.") 105 } 106 } 107 }) 108 109 if err := g.Close(); err != nil { 110 t.Fatal("Failed to close Gateway:", err) 111 } 112 } 113 114 func wait(t *testing.T, evCh chan interface{}) interface{} { 115 select { 116 case ev := <-evCh: 117 return ev 118 case <-time.After(20 * time.Second): 119 t.Fatal("Timed out waiting for event") 120 return nil 121 } 122 } 123 124 func gotimeout(t *testing.T, fn func()) { 125 t.Helper() 126 127 var done = make(chan struct{}) 128 go func() { 129 fn() 130 done <- struct{}{} 131 }() 132 133 select { 134 case <-time.After(20 * time.Second): 135 t.Fatal("Timed out waiting for function.") 136 case <-done: 137 return 138 } 139 }