arikawa/voice/integration_test.go

145 lines
2.7 KiB
Go

// +build integration
package voice
import (
"encoding/binary"
"io"
"log"
"os"
"testing"
"github.com/diamondburned/arikawa/discord"
"github.com/diamondburned/arikawa/state"
)
type testConfig struct {
BotToken string
VoiceChID discord.Snowflake
}
func mustConfig(t *testing.T) testConfig {
var token = os.Getenv("BOT_TOKEN")
if token == "" {
t.Fatal("Missing $BOT_TOKEN")
}
var sid = os.Getenv("VOICE_ID")
if sid == "" {
t.Fatal("Missing $VOICE_ID")
}
id, err := discord.ParseSnowflake(sid)
if err != nil {
t.Fatal("Invalid $VOICE_ID:", err)
}
return testConfig{
BotToken: token,
VoiceChID: id,
}
}
// file is only a few bytes lolmao
func nicoReader(t *testing.T) (read func() []byte) {
f, err := os.Open("testdata/nico.dca")
if err != nil {
t.Fatal("Failed to open nico.dca:", err)
}
t.Cleanup(func() {
f.Close()
})
var lenbuf [4]byte
return func() []byte {
if _, err := io.ReadFull(f, lenbuf[:]); !catchRead(t, err) {
return nil
}
// Read the integer
framelen := int(binary.LittleEndian.Uint32(lenbuf[:]))
// Read exactly frame
frame := make([]byte, framelen)
if _, err := io.ReadFull(f, frame); !catchRead(t, err) {
return nil
}
return frame
}
}
func catchRead(t *testing.T, err error) bool {
t.Helper()
if err == io.EOF {
return false
}
if err != nil {
t.Fatal("Failed to read:", err)
}
return true
}
func TestIntegration(t *testing.T) {
config := mustConfig(t)
WSDebug = func(v ...interface{}) {
log.Println(v...)
}
// heart.Debug = func(v ...interface{}) {
// log.Println(append([]interface{}{"Pacemaker:"}, v...)...)
// }
s, err := state.New("Bot " + config.BotToken)
if err != nil {
t.Fatal("Failed to create a new session:", err)
}
v := NewVoice(s)
if err := s.Open(); err != nil {
t.Fatal("Failed to connect:", err)
}
// Validate the given voice channel.
c, err := s.Channel(config.VoiceChID)
if err != nil {
t.Fatal("Failed to get channel:", err)
}
if c.Type != discord.GuildVoice {
t.Fatal("Channel isn't a guild voice channel.")
}
conn, err := v.JoinChannel(c.GuildID, c.ID, false, false)
if err != nil {
t.Fatal("Failed to join channel:", err)
}
// Grab the file in the local test data.
read := nicoReader(t)
// Trigger speaking.
if err := conn.Speaking(Microphone); err != nil {
t.Fatal("Failed to start speaking:", err)
}
// Copy the audio?
for bytes := read(); bytes != nil; bytes = read() {
conn.OpusSend <- bytes
// conn.Write(bytes)
}
// Finish speaking.
if err := conn.StopSpeaking(); err != nil {
t.Fatal("Failed to stop speaking:", err)
}
if err := conn.Disconnect(s.Gateway); err != nil {
t.Fatal("Failed to disconnect:", err)
}
}