diff --git a/discord/api.go b/discord/api.go index 29d6895..1352350 100644 --- a/discord/api.go +++ b/discord/api.go @@ -1,8 +1,57 @@ package discord +import ( + "fmt" + "net/http" + "net/url" + "time" +) + +const DiscordBaseUrl = "https://discord.com/api/v10" + type IDiscordClient interface { + Do(req *http.Request) (*http.Response, error) } -func Get(url string) { +type DiscordClient struct { + Client *http.Client + BotToken string + ClientID string + ClientSecret string +} + +func NewDiscordClient(clientID, clientSecret, botToken string) DiscordClient { + return DiscordClient{ + ClientID: clientID, + ClientSecret: clientSecret, + BotToken: botToken, + Client: &http.Client{ + Timeout: time.Second * 10, + }, + } +} + +func (d *DiscordClient) Do(req *http.Request) (*http.Response, error) { + return d.Client.Do(req) +} + +func NewRequest(method string, path string, botToken string) *http.Request { + url, err := url.Parse(fmt.Sprintf("%s%s", DiscordBaseUrl, path)) + if err != nil { + panic("discord/api: wtf couldnt join a string??") + } + + req := &http.Request{ + Method: method, + URL: url, + } + + req.Header.Set("User-Agent", "Roleypoly (https://roleypoly.com, v4)") + + if botToken != "" { + req.Header.Set("Authorization", fmt.Sprintf("Bot %s", botToken)) + } + + return req } diff --git a/discord/api_mock.go b/discord/api_mock.go new file mode 100644 index 0000000..2f90c47 --- /dev/null +++ b/discord/api_mock.go @@ -0,0 +1,30 @@ +package discord + +import ( + "bytes" + "encoding/json" + "io" + "net/http" + + "github.com/stretchr/testify/mock" +) + +type DiscordClientMock struct { + mock.Mock +} + +func (c *DiscordClientMock) Do(req *http.Request) (*http.Response, error) { + args := c.Called(req) + + return args.Get(0).(*http.Response), args.Error(1) +} + +func (c *DiscordClientMock) MockResponse(statusCode int, data any) *http.Response { + body := bytes.Buffer{} + json.NewEncoder(&body).Encode(data) + + return &http.Response{ + StatusCode: statusCode, + Body: io.NopCloser(&body), + } +} diff --git a/discord/guild.go b/discord/guild.go index 205a4d2..7897cdb 100644 --- a/discord/guild.go +++ b/discord/guild.go @@ -1,11 +1,12 @@ package discord -import "context" +import "git.sapphic.engineer/roleypoly/v4/types" type IGuild interface { - GetMember(ctx context.Context, memberID string) (IMember, error) + GetMember(memberID string) (IMember, error) } type Guild struct { - ID string + Client IDiscordClient + types.DiscordGuild } diff --git a/discord/guild_mock.go b/discord/guild_mock.go index 4a9fb9a..e9e0635 100644 --- a/discord/guild_mock.go +++ b/discord/guild_mock.go @@ -1,8 +1,6 @@ package discord import ( - "context" - "github.com/stretchr/testify/mock" ) @@ -10,8 +8,8 @@ type GuildMock struct { mock.Mock } -func (g *GuildMock) GetMember(ctx context.Context, memberID string) (IMember, error) { - args := g.Called(ctx, memberID) +func (g *GuildMock) GetMember(memberID string) (IMember, error) { + args := g.Called(memberID) if args.Get(0) == nil { return nil, args.Error(1) diff --git a/discord/guildservice.go b/discord/guildservice.go index 3067d7b..c22c13f 100644 --- a/discord/guildservice.go +++ b/discord/guildservice.go @@ -1,14 +1,18 @@ package discord -import "context" - type IGuildService interface { - GetGuild(ctx context.Context, guildID string) (IGuild, error) + Client() IDiscordClient + GetGuild(guildID string) (IGuild, error) } type GuildService struct { + client IDiscordClient } -func (gs *GuildService) GetGuild(ctx context.Context, guildID string) (IGuild, error) { - return nil, nil +func (gs *GuildService) Client() IDiscordClient { + return gs.client +} + +func (gs *GuildService) GetGuild(guildID string) (IGuild, error) { + // gs.client } diff --git a/discord/guildservice_mock.go b/discord/guildservice_mock.go index 36c67b0..eb2857a 100644 --- a/discord/guildservice_mock.go +++ b/discord/guildservice_mock.go @@ -1,8 +1,6 @@ package discord import ( - "context" - "github.com/stretchr/testify/mock" ) @@ -10,8 +8,8 @@ type GuildServiceMock struct { mock.Mock } -func (gs *GuildServiceMock) GetGuild(ctx context.Context, guildID string) (IGuild, error) { - args := gs.Called(ctx, guildID) +func (gs *GuildServiceMock) GetGuild(guildID string) (IGuild, error) { + args := gs.Called(guildID) if args.Get(0) == nil { return nil, args.Error(1) diff --git a/interactions/interactions.go b/interactions/interactions.go index 7ec7dbb..20fd7d2 100644 --- a/interactions/interactions.go +++ b/interactions/interactions.go @@ -72,3 +72,8 @@ func (i *Interactions) PostHandler(c fiber.Ctx) error { return types.NewAPIError(http.StatusNotImplemented, "not implemented").Send(c) } + +func (i *Interactions) Respond(ix Interaction, ir InteractionResponse) error { + // TODO: make request to /webhooks/appid/{ix.Token} + return nil +} diff --git a/interactions/types.go b/interactions/types.go index 092c489..aa57c9e 100644 --- a/interactions/types.go +++ b/interactions/types.go @@ -9,6 +9,7 @@ type Interaction struct { GuildID string `json:"guild_id"` AppPermissions uint64 `json:"app_permissions"` Type uint64 `json:"type"` + Token string `json:"token"` } const ( diff --git a/testing/testing.go b/testing/testing.go index 1df8b49..88c8897 100644 --- a/testing/testing.go +++ b/testing/testing.go @@ -1,14 +1,43 @@ package testing -import "github.com/gofiber/fiber/v3" +import ( + "log" -type TestingController struct{} + "github.com/gofiber/fiber/v3" + + "git.sapphic.engineer/roleypoly/v4/discord" + "git.sapphic.engineer/roleypoly/v4/types" +) + +type TestingController struct { + Guilds discord.IGuildService +} func (t *TestingController) Routes(r fiber.Router) { r.Get("/picker/:version?", t.Picker) + r.Get("/m/:server/:user", t.GetMember) } func (t *TestingController) Picker(c fiber.Ctx) error { version := c.Params("version", "main") return c.Render("picker/"+version, fiber.Map{}) } + +func (t *TestingController) GetMember(c fiber.Ctx) error { + serverID := c.Params("server") + userID := c.Params("user") + + g, err := t.Guilds.GetGuild(serverID) + if err != nil { + log.Println("testing/get guild: ", err) + types.NewAPIError(500, err.Error()).Send(c) + } + + m, err := g.GetMember(userID) + if err != nil { + log.Println("testing/get member: ", err) + types.NewAPIError(500, err.Error()).Send(c) + } + + return c.JSON(m) +} diff --git a/types/guild.go b/types/guild.go new file mode 100644 index 0000000..ea6c5e3 --- /dev/null +++ b/types/guild.go @@ -0,0 +1,3 @@ +package types + +type DiscordGuild struct{} diff --git a/utils/strings.go b/utils/strings.go index 748b280..5a24214 100644 --- a/utils/strings.go +++ b/utils/strings.go @@ -1,7 +1,14 @@ package utils -import "fmt" +import ( + "fmt" + "strings" +) func HeadTitle(text string) string { return fmt.Sprintf("%s | Roleypoly", text) } + +func J(parts ...string) string { + return "/" + strings.Join(parts, "/") +} diff --git a/utils/strings_test.go b/utils/strings_test.go index 82ac3fc..552a520 100644 --- a/utils/strings_test.go +++ b/utils/strings_test.go @@ -11,3 +11,7 @@ import ( func TestHeadTitle(t *testing.T) { assert.Equal(t, utils.HeadTitle("Hello World"), "Hello World | Roleypoly") } + +func TestJ(t *testing.T) { + assert.Equal(t, "a/b/c", utils.J("a", "b", "c")) +}