discord_test.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. package discordgo
  2. import (
  3. "os"
  4. "runtime"
  5. "testing"
  6. "time"
  7. )
  8. //////////////////////////////////////////////////////////////////////////////
  9. ////////////////////////////////////////////////////// VARS NEEDED FOR TESTING
  10. var (
  11. dg *Session // Stores global discordgo session
  12. envToken = os.Getenv("DG_TOKEN") // Token to use when authenticating
  13. envEmail = os.Getenv("DG_EMAIL") // Email to use when authenticating
  14. envPassword = os.Getenv("DG_PASSWORD") // Password to use when authenticating
  15. envGuild = os.Getenv("DG_GUILD") // Guild ID to use for tests
  16. envChannel = os.Getenv("DG_CHANNEL") // Channel ID to use for tests
  17. // envUser = os.Getenv("DG_USER") // User ID to use for tests
  18. envAdmin = os.Getenv("DG_ADMIN") // User ID of admin user to use for tests
  19. )
  20. func init() {
  21. if envEmail == "" || envPassword == "" || envToken == "" {
  22. return
  23. }
  24. if d, err := New(envEmail, envPassword, envToken); err == nil {
  25. dg = d
  26. }
  27. }
  28. //////////////////////////////////////////////////////////////////////////////
  29. //////////////////////////////////////////// HELPER FUNCTIONS USED FOR TESTING
  30. // This waits x time for the check bool to be the want bool
  31. func waitBoolEqual(timeout time.Duration, check *bool, want bool) bool {
  32. start := time.Now()
  33. for {
  34. if *check == want {
  35. return true
  36. }
  37. if time.Since(start) > timeout {
  38. return false
  39. }
  40. runtime.Gosched()
  41. }
  42. }
  43. // Checks if we're connected to Discord
  44. func isConnected() bool {
  45. if dg == nil {
  46. return false
  47. }
  48. if dg.Token == "" {
  49. return false
  50. }
  51. // Need a way to see if the ws connection is nil
  52. if !waitBoolEqual(10*time.Second, &dg.DataReady, true) {
  53. return false
  54. }
  55. return true
  56. }
  57. //////////////////////////////////////////////////////////////////////////////
  58. /////////////////////////////////////////////////////////////// START OF TESTS
  59. // TestNew tests the New() function without any arguments. This should return
  60. // a valid Session{} struct and no errors.
  61. func TestNew(t *testing.T) {
  62. _, err := New()
  63. if err != nil {
  64. t.Errorf("New() returned error: %+v", err)
  65. }
  66. }
  67. // TestInvalidToken tests the New() function with an invalid token
  68. func TestInvalidToken(t *testing.T) {
  69. d, err := New("asjkldhflkjasdh")
  70. if err != nil {
  71. t.Fatalf("New(InvalidToken) returned error: %+v", err)
  72. }
  73. // New with just a token does not do any communication, so attempt an api call.
  74. _, err = d.UserSettings()
  75. if err == nil {
  76. t.Errorf("New(InvalidToken), d.UserSettings returned nil error.")
  77. }
  78. }
  79. // TestInvalidUserPass tests the New() function with an invalid Email and Pass
  80. func TestInvalidEmailPass(t *testing.T) {
  81. _, err := New("invalidemail", "invalidpassword")
  82. if err == nil {
  83. t.Errorf("New(InvalidEmail, InvalidPass) returned nil error.")
  84. }
  85. }
  86. // TestInvalidPass tests the New() function with an invalid Password
  87. func TestInvalidPass(t *testing.T) {
  88. if envEmail == "" {
  89. t.Skip("Skipping New(username,InvalidPass), DG_EMAIL not set")
  90. return
  91. }
  92. _, err := New(envEmail, "invalidpassword")
  93. if err == nil {
  94. t.Errorf("New(Email, InvalidPass) returned nil error.")
  95. }
  96. }
  97. // TestNewUserPass tests the New() function with a username and password.
  98. // This should return a valid Session{}, a valid Session.Token.
  99. func TestNewUserPass(t *testing.T) {
  100. if envEmail == "" || envPassword == "" {
  101. t.Skip("Skipping New(username,password), DG_EMAIL or DG_PASSWORD not set")
  102. return
  103. }
  104. d, err := New(envEmail, envPassword)
  105. if err != nil {
  106. t.Fatalf("New(user,pass) returned error: %+v", err)
  107. }
  108. if d == nil {
  109. t.Fatal("New(user,pass), d is nil, should be Session{}")
  110. }
  111. if d.Token == "" {
  112. t.Fatal("New(user,pass), d.Token is empty, should be a valid Token.")
  113. }
  114. }
  115. // TestNewToken tests the New() function with a Token. This should return
  116. // the same as the TestNewUserPass function.
  117. func TestNewToken(t *testing.T) {
  118. if envToken == "" {
  119. t.Skip("Skipping New(token), DG_TOKEN not set")
  120. }
  121. d, err := New(envToken)
  122. if err != nil {
  123. t.Fatalf("New(envToken) returned error: %+v", err)
  124. }
  125. if d == nil {
  126. t.Fatal("New(envToken), d is nil, should be Session{}")
  127. }
  128. if d.Token == "" {
  129. t.Fatal("New(envToken), d.Token is empty, should be a valid Token.")
  130. }
  131. }
  132. // TestNewUserPassToken tests the New() function with a username, password and token.
  133. // This should return the same as the TestNewUserPass function.
  134. func TestNewUserPassToken(t *testing.T) {
  135. if envEmail == "" || envPassword == "" || envToken == "" {
  136. t.Skip("Skipping New(username,password,token), DG_EMAIL, DG_PASSWORD or DG_TOKEN not set")
  137. return
  138. }
  139. d, err := New(envEmail, envPassword, envToken)
  140. if err != nil {
  141. t.Fatalf("New(user,pass,token) returned error: %+v", err)
  142. }
  143. if d == nil {
  144. t.Fatal("New(user,pass,token), d is nil, should be Session{}")
  145. }
  146. if d.Token == "" {
  147. t.Fatal("New(user,pass,token), d.Token is empty, should be a valid Token.")
  148. }
  149. }
  150. func TestOpenClose(t *testing.T) {
  151. if envToken == "" {
  152. t.Skip("Skipping TestClose, DG_TOKEN not set")
  153. }
  154. d, err := New(envToken)
  155. if err != nil {
  156. t.Fatalf("TestClose, New(envToken) returned error: %+v", err)
  157. }
  158. if err = d.Open(); err != nil {
  159. t.Fatalf("TestClose, d.Open failed: %+v", err)
  160. }
  161. if !waitBoolEqual(10*time.Second, &d.DataReady, true) {
  162. t.Fatal("DataReady never became true.")
  163. }
  164. // TODO find a better way
  165. // Add a small sleep here to make sure heartbeat and other events
  166. // have enough time to get fired. Need a way to actually check
  167. // those events.
  168. time.Sleep(2 * time.Second)
  169. // UpdateStatus - maybe we move this into wsapi_test.go but the websocket
  170. // created here is needed. This helps tests that the websocket was setup
  171. // and it is working.
  172. if err = d.UpdateStatus(0, time.Now().String()); err != nil {
  173. t.Errorf("UpdateStatus error: %+v", err)
  174. }
  175. if err = d.Close(); err != nil {
  176. t.Fatalf("TestClose, d.Close failed: %+v", err)
  177. }
  178. }
  179. func TestAddHandler(t *testing.T) {
  180. testHandlerCalled := 0
  181. testHandler := func(s *Session, m *MessageCreate) {
  182. testHandlerCalled++
  183. }
  184. interfaceHandlerCalled := 0
  185. interfaceHandler := func(s *Session, i interface{}) {
  186. interfaceHandlerCalled++
  187. }
  188. bogusHandlerCalled := false
  189. bogusHandler := func(s *Session, se *Session) {
  190. bogusHandlerCalled = true
  191. }
  192. d := Session{}
  193. d.AddHandler(testHandler)
  194. d.AddHandler(testHandler)
  195. d.AddHandler(interfaceHandler)
  196. d.AddHandler(bogusHandler)
  197. d.handle(&MessageCreate{})
  198. d.handle(&MessageDelete{})
  199. // testHandler will be called twice because it was added twice.
  200. if testHandlerCalled != 2 {
  201. t.Fatalf("testHandler was not called twice.")
  202. }
  203. // interfaceHandler will be called twice, once for each event.
  204. if interfaceHandlerCalled != 2 {
  205. t.Fatalf("interfaceHandler was not called twice.")
  206. }
  207. if bogusHandlerCalled {
  208. t.Fatalf("bogusHandler was called.")
  209. }
  210. }
  211. func TestRemoveHandler(t *testing.T) {
  212. testHandlerCalled := 0
  213. testHandler := func(s *Session, m *MessageCreate) {
  214. testHandlerCalled++
  215. }
  216. d := Session{}
  217. r := d.AddHandler(testHandler)
  218. d.handle(&MessageCreate{})
  219. r()
  220. d.handle(&MessageCreate{})
  221. // testHandler will be called once, as it was removed in between calls.
  222. if testHandlerCalled != 1 {
  223. t.Fatalf("testHandler was not called once.")
  224. }
  225. }