redo discord mocks
This commit is contained in:
parent
f4718f979a
commit
dfbb9e2bca
19 changed files with 223 additions and 105 deletions
|
@ -1,30 +0,0 @@
|
|||
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),
|
||||
}
|
||||
}
|
42
discord/clientmock/discord_client_mock.go
Normal file
42
discord/clientmock/discord_client_mock.go
Normal file
|
@ -0,0 +1,42 @@
|
|||
package clientmock
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"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) BotAuth(req *http.Request) {
|
||||
c.Called(req)
|
||||
}
|
||||
|
||||
func (c *DiscordClientMock) MockResponse(method, path string, statusCode int, data any) {
|
||||
body := bytes.Buffer{}
|
||||
json.NewEncoder(&body).Encode(data)
|
||||
|
||||
r := &http.Response{
|
||||
StatusCode: statusCode,
|
||||
Body: io.NopCloser(&body),
|
||||
}
|
||||
|
||||
pathMatcher := regexp.MustCompile(strings.ReplaceAll(path, "*", "[a-z0-9_-]+"))
|
||||
|
||||
c.On("Do", mock.MatchedBy(func(req *http.Request) bool {
|
||||
return req.Method == method && pathMatcher.MatchString(req.URL.Path)
|
||||
})).Return(r, nil)
|
||||
}
|
|
@ -5,12 +5,15 @@ import (
|
|||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
)
|
||||
|
||||
const DiscordBaseUrl = "https://discord.com/api/v10"
|
||||
|
||||
type IDiscordClient interface {
|
||||
Do(req *http.Request) (*http.Response, error)
|
||||
BotAuth(req *http.Request)
|
||||
}
|
||||
|
||||
type DiscordClient struct {
|
||||
|
@ -36,7 +39,11 @@ 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 {
|
||||
func (d *DiscordClient) BotAuth(req *http.Request) {
|
||||
req.Header.Set("Authorization", fmt.Sprintf("Bot %s", d.BotToken))
|
||||
}
|
||||
|
||||
func NewRequest(method string, path string) *http.Request {
|
||||
url, err := url.Parse(fmt.Sprintf("%s%s", DiscordBaseUrl, path))
|
||||
if err != nil {
|
||||
panic("discord/api: wtf couldnt join a string??")
|
||||
|
@ -45,13 +52,15 @@ func NewRequest(method string, path string, botToken string) *http.Request {
|
|||
req := &http.Request{
|
||||
Method: method,
|
||||
URL: url,
|
||||
Header: http.Header{},
|
||||
}
|
||||
|
||||
req.Header.Set("User-Agent", "Roleypoly (https://roleypoly.com, v4)")
|
||||
|
||||
if botToken != "" {
|
||||
req.Header.Set("Authorization", fmt.Sprintf("Bot %s", botToken))
|
||||
}
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
func OutputResponse(resp *http.Response, dst any) error {
|
||||
// TODO: more checks?
|
||||
return json.NewDecoder(resp.Body).Decode(dst)
|
||||
}
|
|
@ -1,12 +1,39 @@
|
|||
package discord
|
||||
|
||||
import "git.sapphic.engineer/roleypoly/v4/types"
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.sapphic.engineer/roleypoly/v4/types"
|
||||
"git.sapphic.engineer/roleypoly/v4/utils"
|
||||
)
|
||||
|
||||
type IGuild interface {
|
||||
GetMember(memberID string) (IMember, error)
|
||||
}
|
||||
|
||||
type Guild struct {
|
||||
Client IDiscordClient
|
||||
types.DiscordGuild
|
||||
|
||||
Client IDiscordClient `json:"-"`
|
||||
}
|
||||
|
||||
func (g *Guild) GetMember(memberID string) (*Member, error) {
|
||||
guildID := g.ID
|
||||
req := NewRequest("GET", utils.J("guilds", guildID, "members", memberID))
|
||||
g.Client.BotAuth(req)
|
||||
|
||||
resp, err := g.Client.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Guild.GetMember: request failed: %w", err)
|
||||
}
|
||||
|
||||
member := &Member{
|
||||
Client: g.Client,
|
||||
}
|
||||
err = OutputResponse(resp, member)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Guild.GetMember: response decode failed: %w", err)
|
||||
}
|
||||
|
||||
return member, nil
|
||||
}
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
package discord
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
type GuildMock struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
func (g *GuildMock) GetMember(memberID string) (IMember, error) {
|
||||
args := g.Called(memberID)
|
||||
|
||||
if args.Get(0) == nil {
|
||||
return nil, args.Error(1)
|
||||
}
|
||||
|
||||
return args.Get(0).(IMember), args.Error(1)
|
||||
}
|
31
discord/guild_test.go
Normal file
31
discord/guild_test.go
Normal file
|
@ -0,0 +1,31 @@
|
|||
package discord_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"git.sapphic.engineer/roleypoly/v4/discord"
|
||||
"git.sapphic.engineer/roleypoly/v4/types/fixtures"
|
||||
"git.sapphic.engineer/roleypoly/v4/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
fixtureMember = &discord.Member{
|
||||
DiscordMember: fixtures.Member,
|
||||
}
|
||||
)
|
||||
|
||||
func TestGetMember(t *testing.T) {
|
||||
dc := defaultMocks(t)
|
||||
g := discord.Guild{
|
||||
Client: dc,
|
||||
DiscordGuild: fixtures.Guild,
|
||||
}
|
||||
|
||||
dc.MockResponse("GET", utils.J("guilds", fixtures.Guild.ID, "members", fixtureMember.User.ID), 200, fixtureMember)
|
||||
|
||||
m, err := g.GetMember("41666")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "Doll", m.Nick)
|
||||
}
|
|
@ -1,5 +1,11 @@
|
|||
package discord
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.sapphic.engineer/roleypoly/v4/utils"
|
||||
)
|
||||
|
||||
type IGuildService interface {
|
||||
Client() IDiscordClient
|
||||
GetGuild(guildID string) (IGuild, error)
|
||||
|
@ -19,7 +25,23 @@ func (gs *GuildService) Client() IDiscordClient {
|
|||
return gs.client
|
||||
}
|
||||
|
||||
func (gs *GuildService) GetGuild(guildID string) (IGuild, error) {
|
||||
// gs.client
|
||||
return nil, nil
|
||||
func (gs *GuildService) GetGuild(guildID string) (*Guild, error) {
|
||||
|
||||
req := NewRequest("GET", utils.J("guilds", guildID))
|
||||
gs.client.BotAuth(req)
|
||||
|
||||
resp, err := gs.client.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GuildService.GetGuild: request failed: %w", err)
|
||||
}
|
||||
|
||||
guild := &Guild{
|
||||
Client: gs.client,
|
||||
}
|
||||
err = OutputResponse(resp, guild)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GuildService.GetGuild: response decode failed: %w", err)
|
||||
}
|
||||
|
||||
return guild, nil
|
||||
}
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
package discord
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
type GuildServiceMock struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
func (gs *GuildServiceMock) GetGuild(guildID string) (IGuild, error) {
|
||||
args := gs.Called(guildID)
|
||||
|
||||
if args.Get(0) == nil {
|
||||
return nil, args.Error(1)
|
||||
}
|
||||
|
||||
return args.Get(0).(IGuild), args.Error(1)
|
||||
}
|
||||
|
||||
func (gs *GuildServiceMock) Client() IDiscordClient {
|
||||
args := gs.Called()
|
||||
return args.Get(0).(IDiscordClient)
|
||||
}
|
27
discord/guildservice_test.go
Normal file
27
discord/guildservice_test.go
Normal file
|
@ -0,0 +1,27 @@
|
|||
package discord_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.sapphic.engineer/roleypoly/v4/discord"
|
||||
"git.sapphic.engineer/roleypoly/v4/types/fixtures"
|
||||
"git.sapphic.engineer/roleypoly/v4/utils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var (
|
||||
fixtureGuild = &discord.Guild{
|
||||
DiscordGuild: fixtures.Guild,
|
||||
}
|
||||
)
|
||||
|
||||
func TestGetGuild(t *testing.T) {
|
||||
dc := defaultMocks(t)
|
||||
gs := discord.NewGuildService(dc)
|
||||
|
||||
dc.MockResponse("GET", utils.J("guilds", fixtures.Guild.ID), 200, fixtureGuild)
|
||||
|
||||
g, err := gs.GetGuild("1312")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "1312", g.ID)
|
||||
}
|
|
@ -8,6 +8,7 @@ type IMember interface {
|
|||
}
|
||||
|
||||
type Member struct {
|
||||
Client IDiscordClient
|
||||
types.DiscordMember
|
||||
}
|
||||
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
package discord
|
||||
|
||||
import "github.com/stretchr/testify/mock"
|
||||
|
||||
type MemberMock struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
func (m *MemberMock) GetRoles() error {
|
||||
args := m.Called()
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (m *MemberMock) PatchRoles() error {
|
||||
args := m.Called()
|
||||
return args.Error(0)
|
||||
}
|
1
discord/member_test.go
Normal file
1
discord/member_test.go
Normal file
|
@ -0,0 +1 @@
|
|||
package discord_test
|
16
discord/utils_test.go
Normal file
16
discord/utils_test.go
Normal file
|
@ -0,0 +1,16 @@
|
|||
package discord_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.sapphic.engineer/roleypoly/v4/discord/clientmock"
|
||||
"github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
func defaultMocks(t *testing.T) *clientmock.DiscordClientMock {
|
||||
dc := &clientmock.DiscordClientMock{}
|
||||
|
||||
dc.On("BotAuth", mock.AnythingOfType("*http.Request"))
|
||||
|
||||
return dc
|
||||
}
|
|
@ -56,9 +56,8 @@ func TestPostHandlerSigFail(t *testing.T) {
|
|||
app := roleypoly.CreateFiberApp()
|
||||
i.Routes(app)
|
||||
|
||||
// TODO: make real interaction
|
||||
body, err := json.Marshal(map[string]string{
|
||||
"temp": "temp",
|
||||
body, err := json.Marshal(map[string]any{
|
||||
"type": 1,
|
||||
})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
)
|
||||
|
||||
type TestingController struct {
|
||||
Guilds discord.IGuildService
|
||||
Guilds *discord.GuildService
|
||||
}
|
||||
|
||||
func (t *TestingController) Routes(r fiber.Router) {
|
||||
|
|
9
types/fixtures/guild.go
Normal file
9
types/fixtures/guild.go
Normal file
|
@ -0,0 +1,9 @@
|
|||
package fixtures
|
||||
|
||||
import "git.sapphic.engineer/roleypoly/v4/types"
|
||||
|
||||
var (
|
||||
Guild = types.DiscordGuild{
|
||||
ID: "1312",
|
||||
}
|
||||
)
|
12
types/fixtures/member.go
Normal file
12
types/fixtures/member.go
Normal file
|
@ -0,0 +1,12 @@
|
|||
package fixtures
|
||||
|
||||
import "git.sapphic.engineer/roleypoly/v4/types"
|
||||
|
||||
var (
|
||||
Member = types.DiscordMember{
|
||||
User: User,
|
||||
Nick: "Doll",
|
||||
Permissions: 0,
|
||||
Roles: []string{"role1", "role2"},
|
||||
}
|
||||
)
|
10
types/fixtures/user.go
Normal file
10
types/fixtures/user.go
Normal file
|
@ -0,0 +1,10 @@
|
|||
package fixtures
|
||||
|
||||
import "git.sapphic.engineer/roleypoly/v4/types"
|
||||
|
||||
var (
|
||||
User = types.DiscordUser{
|
||||
Username: "41666",
|
||||
ID: "41666",
|
||||
}
|
||||
)
|
|
@ -1,3 +1,5 @@
|
|||
package types
|
||||
|
||||
type DiscordGuild struct{}
|
||||
type DiscordGuild struct {
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue