v4/interactions/utils_test.go

99 lines
2.4 KiB
Go

package interactions_test
import (
"bytes"
"crypto"
"crypto/ed25519"
"encoding/hex"
"encoding/json"
"net/http"
"testing"
"time"
"git.sapphic.engineer/roleypoly/v4/discord"
"git.sapphic.engineer/roleypoly/v4/discord/clientmock"
"git.sapphic.engineer/roleypoly/v4/interactions"
"git.sapphic.engineer/roleypoly/v4/types/fixtures"
"github.com/gofiber/fiber/v3"
"github.com/stretchr/testify/assert"
)
func makeInteractions(t *testing.T) (*interactions.Interactions, *clientmock.DiscordClientMock, ed25519.PrivateKey) {
pub, priv, err := ed25519.GenerateKey(nil)
if err != nil {
t.Errorf("makeInteractions: failed to generate key: %v", err)
}
dcm := clientmock.NewDiscordClientMock()
gs := discord.NewGuildService(dcm)
i := &interactions.Interactions{
PublicKey: pub,
PublicBaseURL: "http://roleypoly.local",
Guilds: gs,
Router: interactions.NewInteractionRouter(),
OK: true,
}
return i, dcm, priv
}
func cmdHelloWorld(ix interactions.Interaction) (interactions.InteractionResponse, error) {
return interactions.String("Hello world!", true)
}
func sign(t *testing.T, key ed25519.PrivateKey, body []byte) (string, string) {
timestamp := time.Now().UTC().Format(time.RFC3339)
payloadBuf := bytes.Buffer{}
payloadBuf.WriteString(timestamp)
payloadBuf.Write(body)
signature, err := key.Sign(nil, payloadBuf.Bytes(), crypto.Hash(0))
if err != nil {
t.Errorf("signing failed: %v", err)
}
sigHex := hex.EncodeToString(signature)
return sigHex, timestamp
}
func sendInteraction(t *testing.T, i *interactions.Interactions, key ed25519.PrivateKey, ix interactions.Interaction) (ir interactions.InteractionResponse) {
app := fiber.New()
i.Routes(app)
body, err := json.Marshal(ix)
if err != nil {
t.Error(err)
return
}
sig, ts := sign(t, key, body)
req, _ := http.NewRequest("POST", "/", bytes.NewBuffer(body))
req.Header.Add("X-Signature-Ed25519", sig)
req.Header.Add("X-Signature-Timestamp", ts)
resp, err := app.Test(req)
assert.Nil(t, err)
assert.Equal(t, http.StatusOK, resp.StatusCode)
err = json.NewDecoder(resp.Body).Decode(&ir)
if err != nil {
t.Error(err)
}
return
}
func mkInteraction(name string) interactions.Interaction {
return interactions.Interaction{
GuildID: "guild-id",
Type: interactions.TypeApplicationCommand,
Member: fixtures.Member,
Data: interactions.InteractionData{
Name: name,
},
}
}