123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- package discordgo
- import (
- "fmt"
- "os"
- "runtime"
- "sync/atomic"
- "testing"
- "time"
- )
- //////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////// VARS NEEDED FOR TESTING
- var (
- dg *Session // Stores a global discordgo user session
- dgBot *Session // Stores a global discordgo bot session
- envOAuth2Token = os.Getenv("DG_OAUTH2_TOKEN") // Token to use when authenticating using OAuth2 token
- envBotToken = os.Getenv("DGB_TOKEN") // Token to use when authenticating the bot account
- envGuild = os.Getenv("DG_GUILD") // Guild ID to use for tests
- envChannel = os.Getenv("DG_CHANNEL") // Channel ID to use for tests
- envVoiceChannel = os.Getenv("DG_VOICE_CHANNEL") // Channel ID to use for tests
- envAdmin = os.Getenv("DG_ADMIN") // User ID of admin user to use for tests
- )
- func TestMain(m *testing.M) {
- fmt.Println("Init is being called.")
- if envBotToken != "" {
- if d, err := New(envBotToken); err == nil {
- dgBot = d
- }
- }
- if envOAuth2Token == "" {
- envOAuth2Token = os.Getenv("DGU_TOKEN")
- }
- if envOAuth2Token != "" {
- if d, err := New(envOAuth2Token); err == nil {
- dg = d
- }
- }
- os.Exit(m.Run())
- }
- //////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////// START OF TESTS
- // TestNewToken tests the New() function with a Token.
- func TestNewToken(t *testing.T) {
- if envOAuth2Token == "" {
- t.Skip("Skipping New(token), DGU_TOKEN not set")
- }
- d, err := New(envOAuth2Token)
- if err != nil {
- t.Fatalf("New(envToken) returned error: %+v", err)
- }
- if d == nil {
- t.Fatal("New(envToken), d is nil, should be Session{}")
- }
- if d.Token == "" {
- t.Fatal("New(envToken), d.Token is empty, should be a valid Token.")
- }
- }
- func TestOpenClose(t *testing.T) {
- if envOAuth2Token == "" {
- t.Skip("Skipping TestClose, DGU_TOKEN not set")
- }
- d, err := New(envOAuth2Token)
- if err != nil {
- t.Fatalf("TestClose, New(envToken) returned error: %+v", err)
- }
- if err = d.Open(); err != nil {
- t.Fatalf("TestClose, d.Open failed: %+v", err)
- }
- // We need a better way to know the session is ready for use,
- // this is totally gross.
- start := time.Now()
- for {
- d.RLock()
- if d.DataReady {
- d.RUnlock()
- break
- }
- d.RUnlock()
- if time.Since(start) > 10*time.Second {
- t.Fatal("DataReady never became true.yy")
- }
- runtime.Gosched()
- }
- // TODO find a better way
- // Add a small sleep here to make sure heartbeat and other events
- // have enough time to get fired. Need a way to actually check
- // those events.
- time.Sleep(2 * time.Second)
- // UpdateStatus - maybe we move this into wsapi_test.go but the websocket
- // created here is needed. This helps tests that the websocket was setup
- // and it is working.
- if err = d.UpdateGameStatus(0, time.Now().String()); err != nil {
- t.Errorf("UpdateStatus error: %+v", err)
- }
- if err = d.Close(); err != nil {
- t.Fatalf("TestClose, d.Close failed: %+v", err)
- }
- }
- func TestAddHandler(t *testing.T) {
- testHandlerCalled := int32(0)
- testHandler := func(s *Session, m *MessageCreate) {
- atomic.AddInt32(&testHandlerCalled, 1)
- }
- interfaceHandlerCalled := int32(0)
- interfaceHandler := func(s *Session, i interface{}) {
- atomic.AddInt32(&interfaceHandlerCalled, 1)
- }
- bogusHandlerCalled := int32(0)
- bogusHandler := func(s *Session, se *Session) {
- atomic.AddInt32(&bogusHandlerCalled, 1)
- }
- d := Session{}
- d.AddHandler(testHandler)
- d.AddHandler(testHandler)
- d.AddHandler(interfaceHandler)
- d.AddHandler(bogusHandler)
- d.handleEvent(messageCreateEventType, &MessageCreate{})
- d.handleEvent(messageDeleteEventType, &MessageDelete{})
- <-time.After(500 * time.Millisecond)
- // testHandler will be called twice because it was added twice.
- if atomic.LoadInt32(&testHandlerCalled) != 2 {
- t.Fatalf("testHandler was not called twice.")
- }
- // interfaceHandler will be called twice, once for each event.
- if atomic.LoadInt32(&interfaceHandlerCalled) != 2 {
- t.Fatalf("interfaceHandler was not called twice.")
- }
- if atomic.LoadInt32(&bogusHandlerCalled) != 0 {
- t.Fatalf("bogusHandler was called.")
- }
- }
- func TestRemoveHandler(t *testing.T) {
- testHandlerCalled := int32(0)
- testHandler := func(s *Session, m *MessageCreate) {
- atomic.AddInt32(&testHandlerCalled, 1)
- }
- d := Session{}
- r := d.AddHandler(testHandler)
- d.handleEvent(messageCreateEventType, &MessageCreate{})
- r()
- d.handleEvent(messageCreateEventType, &MessageCreate{})
- <-time.After(500 * time.Millisecond)
- // testHandler will be called once, as it was removed in between calls.
- if atomic.LoadInt32(&testHandlerCalled) != 1 {
- t.Fatalf("testHandler was not called once.")
- }
- }
- func TestScheduledEvents(t *testing.T) {
- if dgBot == nil {
- t.Skip("Skipping, dgBot not set.")
- }
- beginAt := time.Now().Add(1 * time.Hour)
- endAt := time.Now().Add(2 * time.Hour)
- event, err := dgBot.GuildScheduledEventCreate(envGuild, &GuildScheduledEventParams{
- Name: "Test Event",
- PrivacyLevel: GuildScheduledEventPrivacyLevelGuildOnly,
- ScheduledStartTime: &beginAt,
- ScheduledEndTime: &endAt,
- Description: "Awesome Test Event created on livestream",
- EntityType: GuildScheduledEventEntityTypeExternal,
- EntityMetadata: &GuildScheduledEventEntityMetadata{
- Location: "https://discord.com",
- },
- })
- defer dgBot.GuildScheduledEventDelete(envGuild, event.ID)
- if err != nil || event.Name != "Test Event" {
- t.Fatal(err)
- }
- events, err := dgBot.GuildScheduledEvents(envGuild, true)
- if err != nil {
- t.Fatal(err)
- }
- var foundEvent *GuildScheduledEvent
- for _, e := range events {
- if e.ID == event.ID {
- foundEvent = e
- break
- }
- }
- if foundEvent.Name != event.Name {
- t.Fatal("err on GuildScheduledEvents endpoint. Missing Scheduled Event")
- }
- getEvent, err := dgBot.GuildScheduledEvent(envGuild, event.ID, true)
- if err != nil {
- t.Fatal(err)
- }
- if getEvent.Name != event.Name {
- t.Fatal("err on GuildScheduledEvent endpoint. Mismatched Scheduled Event")
- }
- eventUpdated, err := dgBot.GuildScheduledEventEdit(envGuild, event.ID, &GuildScheduledEventParams{Name: "Test Event Updated"})
- if err != nil {
- t.Fatal(err)
- }
- if eventUpdated.Name != "Test Event Updated" {
- t.Fatal("err on GuildScheduledEventUpdate endpoint. Scheduled Event Name mismatch")
- }
- // Usage of 1 and 1 is just the pseudo data with the purpose to run all branches in the function without crashes.
- // see https://github.com/bwmarrin/discordgo/pull/1032#discussion_r815438303 for more details.
- users, err := dgBot.GuildScheduledEventUsers(envGuild, event.ID, 1, true, "1", "1")
- if err != nil {
- t.Fatal(err)
- }
- if len(users) != 0 {
- t.Fatal("err on GuildScheduledEventUsers. Mismatch of event maybe occured")
- }
- err = dgBot.GuildScheduledEventDelete(envGuild, event.ID)
- if err != nil {
- t.Fatal(err)
- }
- }
- func TestComplexScheduledEvents(t *testing.T) {
- if dgBot == nil {
- t.Skip("Skipping, dgBot not set.")
- }
- beginAt := time.Now().Add(1 * time.Hour)
- endAt := time.Now().Add(2 * time.Hour)
- event, err := dgBot.GuildScheduledEventCreate(envGuild, &GuildScheduledEventParams{
- Name: "Test Voice Event",
- PrivacyLevel: GuildScheduledEventPrivacyLevelGuildOnly,
- ScheduledStartTime: &beginAt,
- ScheduledEndTime: &endAt,
- Description: "Test event on voice channel",
- EntityType: GuildScheduledEventEntityTypeVoice,
- ChannelID: envVoiceChannel,
- })
- if err != nil || event.Name != "Test Voice Event" {
- t.Fatal(err)
- }
- defer dgBot.GuildScheduledEventDelete(envGuild, event.ID)
- _, err = dgBot.GuildScheduledEventEdit(envGuild, event.ID, &GuildScheduledEventParams{
- EntityType: GuildScheduledEventEntityTypeExternal,
- EntityMetadata: &GuildScheduledEventEntityMetadata{
- Location: "https://discord.com",
- },
- })
- if err != nil {
- t.Fatal("err on GuildScheduledEventEdit. Change of entity type to external failed")
- }
- _, err = dgBot.GuildScheduledEventEdit(envGuild, event.ID, &GuildScheduledEventParams{
- ChannelID: envVoiceChannel,
- EntityType: GuildScheduledEventEntityTypeVoice,
- EntityMetadata: nil,
- })
- if err != nil {
- t.Fatal("err on GuildScheduledEventEdit. Change of entity type to voice failed")
- }
- }
|