mirror of
https://github.com/elyby/chrly.git
synced 2025-05-31 14:11:51 +05:30
#1: Fix Mojang's API HTTPClient default configuration, make mojang.ResponseError interface not applicable to any type, add handling of some possible network errors
This commit is contained in:
@@ -5,9 +5,12 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var HttpClient = &http.Client{}
|
var HttpClient = &http.Client{
|
||||||
|
Timeout: 3 * time.Second,
|
||||||
|
}
|
||||||
|
|
||||||
type SignedTexturesResponse struct {
|
type SignedTexturesResponse struct {
|
||||||
Id string `json:"id"`
|
Id string `json:"id"`
|
||||||
@@ -32,10 +35,7 @@ type ProfileInfo struct {
|
|||||||
// See https://wiki.vg/Mojang_API#Playernames_-.3E_UUIDs
|
// See https://wiki.vg/Mojang_API#Playernames_-.3E_UUIDs
|
||||||
func UsernamesToUuids(usernames []string) ([]*ProfileInfo, error) {
|
func UsernamesToUuids(usernames []string) ([]*ProfileInfo, error) {
|
||||||
requestBody, _ := json.Marshal(usernames)
|
requestBody, _ := json.Marshal(usernames)
|
||||||
request, err := http.NewRequest("POST", "https://api.mojang.com/profiles/minecraft", bytes.NewBuffer(requestBody))
|
request, _ := http.NewRequest("POST", "https://api.mojang.com/profiles/minecraft", bytes.NewBuffer(requestBody))
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
request.Header.Set("Content-Type", "application/json")
|
request.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
@@ -65,10 +65,7 @@ func UuidToTextures(uuid string, signed bool) (*SignedTexturesResponse, error) {
|
|||||||
url += "?unsigned=false"
|
url += "?unsigned=false"
|
||||||
}
|
}
|
||||||
|
|
||||||
request, err := http.NewRequest("GET", url, nil)
|
request, _ := http.NewRequest("GET", url, nil)
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
response, err := HttpClient.Do(request)
|
response, err := HttpClient.Do(request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -92,15 +89,30 @@ func validateResponse(response *http.Response) error {
|
|||||||
switch {
|
switch {
|
||||||
case response.StatusCode == 204:
|
case response.StatusCode == 204:
|
||||||
return &EmptyResponse{}
|
return &EmptyResponse{}
|
||||||
|
case response.StatusCode == 400:
|
||||||
|
type errorResponse struct {
|
||||||
|
Error string `json:"error"`
|
||||||
|
Message string `json:"errorMessage"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var decodedError *errorResponse
|
||||||
|
body, _ := ioutil.ReadAll(response.Body)
|
||||||
|
_ = json.Unmarshal(body, &decodedError)
|
||||||
|
|
||||||
|
return &BadRequestError{ErrorType: decodedError.Error, Message: decodedError.Message}
|
||||||
case response.StatusCode == 429:
|
case response.StatusCode == 429:
|
||||||
return &TooManyRequestsError{}
|
return &TooManyRequestsError{}
|
||||||
case response.StatusCode >= 500:
|
case response.StatusCode >= 500:
|
||||||
return &ServerError{response.StatusCode}
|
return &ServerError{Status: response.StatusCode}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ResponseError interface {
|
||||||
|
IsMojangError() bool
|
||||||
|
}
|
||||||
|
|
||||||
// Mojang API doesn't return a 404 Not Found error for non-existent data identifiers
|
// Mojang API doesn't return a 404 Not Found error for non-existent data identifiers
|
||||||
// Instead, they return 204 with an empty body
|
// Instead, they return 204 with an empty body
|
||||||
type EmptyResponse struct {
|
type EmptyResponse struct {
|
||||||
@@ -110,19 +122,48 @@ func (*EmptyResponse) Error() string {
|
|||||||
return "Empty Response"
|
return "Empty Response"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*EmptyResponse) IsMojangError() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// When passed request params are invalid, Mojang returns 400 Bad Request error
|
||||||
|
type BadRequestError struct {
|
||||||
|
ResponseError
|
||||||
|
ErrorType string
|
||||||
|
Message string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *BadRequestError) Error() string {
|
||||||
|
return e.Message
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*BadRequestError) IsMojangError() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// When you exceed the set limit of requests, this error will be returned
|
// When you exceed the set limit of requests, this error will be returned
|
||||||
type TooManyRequestsError struct {
|
type TooManyRequestsError struct {
|
||||||
|
ResponseError
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*TooManyRequestsError) Error() string {
|
func (*TooManyRequestsError) Error() string {
|
||||||
return "Too Many Requests"
|
return "Too Many Requests"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*TooManyRequestsError) IsMojangError() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// ServerError happens when Mojang's API returns any response with 50* status
|
// ServerError happens when Mojang's API returns any response with 50* status
|
||||||
type ServerError struct {
|
type ServerError struct {
|
||||||
|
ResponseError
|
||||||
Status int
|
Status int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ServerError) Error() string {
|
func (e *ServerError) Error() string {
|
||||||
return "Server error"
|
return "Server error"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*ServerError) IsMojangError() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
@@ -51,6 +51,30 @@ func TestUsernamesToUuids(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("handle bad request response", func(t *testing.T) {
|
||||||
|
assert := testify.New(t)
|
||||||
|
|
||||||
|
defer gock.Off()
|
||||||
|
gock.New("https://api.mojang.com").
|
||||||
|
Post("/profiles/minecraft").
|
||||||
|
Reply(400).
|
||||||
|
JSON(map[string]interface{}{
|
||||||
|
"error": "IllegalArgumentException",
|
||||||
|
"errorMessage": "profileName can not be null or empty.",
|
||||||
|
})
|
||||||
|
|
||||||
|
client := &http.Client{}
|
||||||
|
gock.InterceptClient(client)
|
||||||
|
|
||||||
|
HttpClient = client
|
||||||
|
|
||||||
|
result, err := UsernamesToUuids([]string{""})
|
||||||
|
assert.Nil(result)
|
||||||
|
assert.IsType(&BadRequestError{}, err)
|
||||||
|
assert.EqualError(err, "profileName can not be null or empty.")
|
||||||
|
assert.Implements((*ResponseError)(nil), err)
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("handle too many requests response", func(t *testing.T) {
|
t.Run("handle too many requests response", func(t *testing.T) {
|
||||||
assert := testify.New(t)
|
assert := testify.New(t)
|
||||||
|
|
||||||
@@ -72,6 +96,7 @@ func TestUsernamesToUuids(t *testing.T) {
|
|||||||
assert.Nil(result)
|
assert.Nil(result)
|
||||||
assert.IsType(&TooManyRequestsError{}, err)
|
assert.IsType(&TooManyRequestsError{}, err)
|
||||||
assert.EqualError(err, "Too Many Requests")
|
assert.EqualError(err, "Too Many Requests")
|
||||||
|
assert.Implements((*ResponseError)(nil), err)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("handle server error", func(t *testing.T) {
|
t.Run("handle server error", func(t *testing.T) {
|
||||||
@@ -93,6 +118,7 @@ func TestUsernamesToUuids(t *testing.T) {
|
|||||||
assert.IsType(&ServerError{}, err)
|
assert.IsType(&ServerError{}, err)
|
||||||
assert.EqualError(err, "Server error")
|
assert.EqualError(err, "Server error")
|
||||||
assert.Equal(500, err.(*ServerError).Status)
|
assert.Equal(500, err.(*ServerError).Status)
|
||||||
|
assert.Implements((*ResponseError)(nil), err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,6 +211,7 @@ func TestUuidToTextures(t *testing.T) {
|
|||||||
assert.Nil(result)
|
assert.Nil(result)
|
||||||
assert.IsType(&EmptyResponse{}, err)
|
assert.IsType(&EmptyResponse{}, err)
|
||||||
assert.EqualError(err, "Empty Response")
|
assert.EqualError(err, "Empty Response")
|
||||||
|
assert.Implements((*ResponseError)(nil), err)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("handle too many requests response", func(t *testing.T) {
|
t.Run("handle too many requests response", func(t *testing.T) {
|
||||||
@@ -208,6 +235,7 @@ func TestUuidToTextures(t *testing.T) {
|
|||||||
assert.Nil(result)
|
assert.Nil(result)
|
||||||
assert.IsType(&TooManyRequestsError{}, err)
|
assert.IsType(&TooManyRequestsError{}, err)
|
||||||
assert.EqualError(err, "Too Many Requests")
|
assert.EqualError(err, "Too Many Requests")
|
||||||
|
assert.Implements((*ResponseError)(nil), err)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("handle server error", func(t *testing.T) {
|
t.Run("handle server error", func(t *testing.T) {
|
||||||
@@ -229,5 +257,6 @@ func TestUuidToTextures(t *testing.T) {
|
|||||||
assert.IsType(&ServerError{}, err)
|
assert.IsType(&ServerError{}, err)
|
||||||
assert.EqualError(err, "Server error")
|
assert.EqualError(err, "Server error")
|
||||||
assert.Equal(500, err.(*ServerError).Status)
|
assert.Equal(500, err.(*ServerError).Status)
|
||||||
|
assert.Implements((*ResponseError)(nil), err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,11 @@
|
|||||||
package queue
|
package queue
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/elyby/chrly/api/mojang"
|
"github.com/elyby/chrly/api/mojang"
|
||||||
@@ -100,15 +102,15 @@ func (ctx *JobsQueue) queueRound() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
profiles, err := usernamesToUuids(usernames)
|
profiles, err := usernamesToUuids(usernames)
|
||||||
switch err.(type) {
|
if err != nil {
|
||||||
case *mojang.TooManyRequestsError, *mojang.ServerError:
|
defer func() {
|
||||||
for _, job := range jobs {
|
for _, job := range jobs {
|
||||||
job.RespondTo <- nil
|
job.RespondTo <- nil
|
||||||
}
|
}
|
||||||
|
}()
|
||||||
|
maybeShouldPanic(err)
|
||||||
|
|
||||||
return
|
return
|
||||||
case error:
|
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
@@ -146,11 +148,9 @@ func (ctx *JobsQueue) getTextures(uuid string) *mojang.SignedTexturesResponse {
|
|||||||
|
|
||||||
shouldCache := true
|
shouldCache := true
|
||||||
result, err := uuidToTextures(uuid, true)
|
result, err := uuidToTextures(uuid, true)
|
||||||
switch err.(type) {
|
if err != nil {
|
||||||
case *mojang.EmptyResponse, *mojang.TooManyRequestsError, *mojang.ServerError:
|
maybeShouldPanic(err)
|
||||||
shouldCache = false
|
shouldCache = false
|
||||||
case error:
|
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if shouldCache && result != nil {
|
if shouldCache && result != nil {
|
||||||
@@ -159,3 +159,25 @@ func (ctx *JobsQueue) getTextures(uuid string) *mojang.SignedTexturesResponse {
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Starts to panic if there's an unexpected error
|
||||||
|
func maybeShouldPanic(err error) {
|
||||||
|
switch err.(type) {
|
||||||
|
case mojang.ResponseError:
|
||||||
|
return
|
||||||
|
case net.Error:
|
||||||
|
if err.(net.Error).Timeout() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if opErr, ok := err.(*net.OpError); ok && (opErr.Op == "dial" || opErr.Op == "read") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err == syscall.ECONNREFUSED {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
@@ -6,16 +6,18 @@ import (
|
|||||||
"github.com/elyby/chrly/api/mojang"
|
"github.com/elyby/chrly/api/mojang"
|
||||||
"github.com/stretchr/testify/mock"
|
"github.com/stretchr/testify/mock"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MojangApiMocks struct {
|
type mojangApiMocks struct {
|
||||||
mock.Mock
|
mock.Mock
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *MojangApiMocks) UsernameToUuids(usernames []string) ([]*mojang.ProfileInfo, error) {
|
func (o *mojangApiMocks) UsernamesToUuids(usernames []string) ([]*mojang.ProfileInfo, error) {
|
||||||
args := o.Called(usernames)
|
args := o.Called(usernames)
|
||||||
var result []*mojang.ProfileInfo
|
var result []*mojang.ProfileInfo
|
||||||
if casted, ok := args.Get(0).([]*mojang.ProfileInfo); ok {
|
if casted, ok := args.Get(0).([]*mojang.ProfileInfo); ok {
|
||||||
@@ -25,7 +27,7 @@ func (o *MojangApiMocks) UsernameToUuids(usernames []string) ([]*mojang.ProfileI
|
|||||||
return result, args.Error(1)
|
return result, args.Error(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *MojangApiMocks) UuidToTextures(uuid string, signed bool) (*mojang.SignedTexturesResponse, error) {
|
func (o *mojangApiMocks) UuidToTextures(uuid string, signed bool) (*mojang.SignedTexturesResponse, error) {
|
||||||
args := o.Called(uuid, signed)
|
args := o.Called(uuid, signed)
|
||||||
var result *mojang.SignedTexturesResponse
|
var result *mojang.SignedTexturesResponse
|
||||||
if casted, ok := args.Get(0).(*mojang.SignedTexturesResponse); ok {
|
if casted, ok := args.Get(0).(*mojang.SignedTexturesResponse); ok {
|
||||||
@@ -35,20 +37,20 @@ func (o *MojangApiMocks) UuidToTextures(uuid string, signed bool) (*mojang.Signe
|
|||||||
return result, args.Error(1)
|
return result, args.Error(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
type MockStorage struct {
|
type mockStorage struct {
|
||||||
mock.Mock
|
mock.Mock
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MockStorage) GetUuid(username string) (string, error) {
|
func (m *mockStorage) GetUuid(username string) (string, error) {
|
||||||
args := m.Called(username)
|
args := m.Called(username)
|
||||||
return args.String(0), args.Error(1)
|
return args.String(0), args.Error(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MockStorage) StoreUuid(username string, uuid string) {
|
func (m *mockStorage) StoreUuid(username string, uuid string) {
|
||||||
m.Called(username, uuid)
|
m.Called(username, uuid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MockStorage) GetTextures(uuid string) (*mojang.SignedTexturesResponse, error) {
|
func (m *mockStorage) GetTextures(uuid string) (*mojang.SignedTexturesResponse, error) {
|
||||||
args := m.Called(uuid)
|
args := m.Called(uuid)
|
||||||
var result *mojang.SignedTexturesResponse
|
var result *mojang.SignedTexturesResponse
|
||||||
if casted, ok := args.Get(0).(*mojang.SignedTexturesResponse); ok {
|
if casted, ok := args.Get(0).(*mojang.SignedTexturesResponse); ok {
|
||||||
@@ -58,27 +60,27 @@ func (m *MockStorage) GetTextures(uuid string) (*mojang.SignedTexturesResponse,
|
|||||||
return result, args.Error(1)
|
return result, args.Error(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MockStorage) StoreTextures(textures *mojang.SignedTexturesResponse) {
|
func (m *mockStorage) StoreTextures(textures *mojang.SignedTexturesResponse) {
|
||||||
m.Called(textures)
|
m.Called(textures)
|
||||||
}
|
}
|
||||||
|
|
||||||
type QueueTestSuite struct {
|
type queueTestSuite struct {
|
||||||
suite.Suite
|
suite.Suite
|
||||||
Queue *JobsQueue
|
Queue *JobsQueue
|
||||||
Storage *MockStorage
|
Storage *mockStorage
|
||||||
MojangApi *MojangApiMocks
|
MojangApi *mojangApiMocks
|
||||||
Iterate func()
|
Iterate func()
|
||||||
|
|
||||||
iterateChan chan bool
|
iterateChan chan bool
|
||||||
done func()
|
done func()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *QueueTestSuite) SetupSuite() {
|
func (suite *queueTestSuite) SetupSuite() {
|
||||||
delay = 0
|
delay = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *QueueTestSuite) SetupTest() {
|
func (suite *queueTestSuite) SetupTest() {
|
||||||
suite.Storage = &MockStorage{}
|
suite.Storage = &mockStorage{}
|
||||||
|
|
||||||
suite.Queue = &JobsQueue{Storage: suite.Storage}
|
suite.Queue = &JobsQueue{Storage: suite.Storage}
|
||||||
|
|
||||||
@@ -95,25 +97,25 @@ func (suite *QueueTestSuite) SetupTest() {
|
|||||||
suite.iterateChan <- false
|
suite.iterateChan <- false
|
||||||
}
|
}
|
||||||
|
|
||||||
suite.MojangApi = new(MojangApiMocks)
|
suite.MojangApi = new(mojangApiMocks)
|
||||||
usernamesToUuids = suite.MojangApi.UsernameToUuids
|
usernamesToUuids = suite.MojangApi.UsernamesToUuids
|
||||||
uuidToTextures = suite.MojangApi.UuidToTextures
|
uuidToTextures = suite.MojangApi.UuidToTextures
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *QueueTestSuite) TearDownTest() {
|
func (suite *queueTestSuite) TearDownTest() {
|
||||||
suite.done()
|
suite.done()
|
||||||
suite.MojangApi.AssertExpectations(suite.T())
|
suite.MojangApi.AssertExpectations(suite.T())
|
||||||
suite.Storage.AssertExpectations(suite.T())
|
suite.Storage.AssertExpectations(suite.T())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *QueueTestSuite) TestReceiveTexturesForOneUsernameWithoutAnyCache() {
|
func (suite *queueTestSuite) TestReceiveTexturesForOneUsernameWithoutAnyCache() {
|
||||||
expectedResult := &mojang.SignedTexturesResponse{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"}
|
expectedResult := &mojang.SignedTexturesResponse{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"}
|
||||||
|
|
||||||
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("", &ValueNotFound{})
|
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("", &ValueNotFound{})
|
||||||
suite.Storage.On("StoreUuid", "maksimkurb", "0d252b7218b648bfb86c2ae476954d32").Once()
|
suite.Storage.On("StoreUuid", "maksimkurb", "0d252b7218b648bfb86c2ae476954d32").Once()
|
||||||
suite.Storage.On("GetTextures", "0d252b7218b648bfb86c2ae476954d32").Once().Return(nil, &ValueNotFound{})
|
suite.Storage.On("GetTextures", "0d252b7218b648bfb86c2ae476954d32").Once().Return(nil, &ValueNotFound{})
|
||||||
suite.Storage.On("StoreTextures", expectedResult).Once()
|
suite.Storage.On("StoreTextures", expectedResult).Once()
|
||||||
suite.MojangApi.On("UsernameToUuids", []string{"maksimkurb"}).Once().Return([]*mojang.ProfileInfo{
|
suite.MojangApi.On("UsernamesToUuids", []string{"maksimkurb"}).Once().Return([]*mojang.ProfileInfo{
|
||||||
{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"},
|
{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"},
|
||||||
}, nil)
|
}, nil)
|
||||||
suite.MojangApi.On("UuidToTextures", "0d252b7218b648bfb86c2ae476954d32", true).Once().Return(expectedResult, nil)
|
suite.MojangApi.On("UuidToTextures", "0d252b7218b648bfb86c2ae476954d32", true).Once().Return(expectedResult, nil)
|
||||||
@@ -126,7 +128,7 @@ func (suite *QueueTestSuite) TestReceiveTexturesForOneUsernameWithoutAnyCache()
|
|||||||
suite.Assert().Equal(expectedResult, result)
|
suite.Assert().Equal(expectedResult, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *QueueTestSuite) TestReceiveTexturesForFewUsernamesWithoutAnyCache() {
|
func (suite *queueTestSuite) TestReceiveTexturesForFewUsernamesWithoutAnyCache() {
|
||||||
expectedResult1 := &mojang.SignedTexturesResponse{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"}
|
expectedResult1 := &mojang.SignedTexturesResponse{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"}
|
||||||
expectedResult2 := &mojang.SignedTexturesResponse{Id: "4566e69fc90748ee8d71d7ba5aa00d20", Name: "Thinkofdeath"}
|
expectedResult2 := &mojang.SignedTexturesResponse{Id: "4566e69fc90748ee8d71d7ba5aa00d20", Name: "Thinkofdeath"}
|
||||||
|
|
||||||
@@ -138,7 +140,7 @@ func (suite *QueueTestSuite) TestReceiveTexturesForFewUsernamesWithoutAnyCache()
|
|||||||
suite.Storage.On("GetTextures", "4566e69fc90748ee8d71d7ba5aa00d20").Once().Return(nil, &ValueNotFound{})
|
suite.Storage.On("GetTextures", "4566e69fc90748ee8d71d7ba5aa00d20").Once().Return(nil, &ValueNotFound{})
|
||||||
suite.Storage.On("StoreTextures", expectedResult1).Once()
|
suite.Storage.On("StoreTextures", expectedResult1).Once()
|
||||||
suite.Storage.On("StoreTextures", expectedResult2).Once()
|
suite.Storage.On("StoreTextures", expectedResult2).Once()
|
||||||
suite.MojangApi.On("UsernameToUuids", []string{"maksimkurb", "Thinkofdeath"}).Once().Return([]*mojang.ProfileInfo{
|
suite.MojangApi.On("UsernamesToUuids", []string{"maksimkurb", "Thinkofdeath"}).Once().Return([]*mojang.ProfileInfo{
|
||||||
{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"},
|
{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"},
|
||||||
{Id: "4566e69fc90748ee8d71d7ba5aa00d20", Name: "Thinkofdeath"},
|
{Id: "4566e69fc90748ee8d71d7ba5aa00d20", Name: "Thinkofdeath"},
|
||||||
}, nil)
|
}, nil)
|
||||||
@@ -154,14 +156,14 @@ func (suite *QueueTestSuite) TestReceiveTexturesForFewUsernamesWithoutAnyCache()
|
|||||||
suite.Assert().Equal(expectedResult2, <-resultChan2)
|
suite.Assert().Equal(expectedResult2, <-resultChan2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *QueueTestSuite) TestReceiveTexturesForUsernameWithCachedUuid() {
|
func (suite *queueTestSuite) TestReceiveTexturesForUsernameWithCachedUuid() {
|
||||||
expectedResult := &mojang.SignedTexturesResponse{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"}
|
expectedResult := &mojang.SignedTexturesResponse{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"}
|
||||||
|
|
||||||
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("0d252b7218b648bfb86c2ae476954d32", nil)
|
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("0d252b7218b648bfb86c2ae476954d32", nil)
|
||||||
// Storage.StoreUuid shouldn't be called
|
// Storage.StoreUuid shouldn't be called
|
||||||
suite.Storage.On("GetTextures", "0d252b7218b648bfb86c2ae476954d32").Once().Return(nil, &ValueNotFound{})
|
suite.Storage.On("GetTextures", "0d252b7218b648bfb86c2ae476954d32").Once().Return(nil, &ValueNotFound{})
|
||||||
suite.Storage.On("StoreTextures", expectedResult).Once()
|
suite.Storage.On("StoreTextures", expectedResult).Once()
|
||||||
// MojangApi.UsernameToUuids shouldn't be called
|
// MojangApi.UsernamesToUuids shouldn't be called
|
||||||
suite.MojangApi.On("UuidToTextures", "0d252b7218b648bfb86c2ae476954d32", true).Once().Return(expectedResult, nil)
|
suite.MojangApi.On("UuidToTextures", "0d252b7218b648bfb86c2ae476954d32", true).Once().Return(expectedResult, nil)
|
||||||
|
|
||||||
resultChan := suite.Queue.GetTexturesForUsername("maksimkurb")
|
resultChan := suite.Queue.GetTexturesForUsername("maksimkurb")
|
||||||
@@ -172,14 +174,14 @@ func (suite *QueueTestSuite) TestReceiveTexturesForUsernameWithCachedUuid() {
|
|||||||
suite.Assert().Equal(expectedResult, result)
|
suite.Assert().Equal(expectedResult, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *QueueTestSuite) TestReceiveTexturesForUsernameWithFullyCachedResult() {
|
func (suite *queueTestSuite) TestReceiveTexturesForUsernameWithFullyCachedResult() {
|
||||||
expectedResult := &mojang.SignedTexturesResponse{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"}
|
expectedResult := &mojang.SignedTexturesResponse{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"}
|
||||||
|
|
||||||
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("0d252b7218b648bfb86c2ae476954d32", nil)
|
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("0d252b7218b648bfb86c2ae476954d32", nil)
|
||||||
// Storage.StoreUuid shouldn't be called
|
// Storage.StoreUuid shouldn't be called
|
||||||
suite.Storage.On("GetTextures", "0d252b7218b648bfb86c2ae476954d32").Once().Return(expectedResult, nil)
|
suite.Storage.On("GetTextures", "0d252b7218b648bfb86c2ae476954d32").Once().Return(expectedResult, nil)
|
||||||
// Storage.StoreTextures shouldn't be called
|
// Storage.StoreTextures shouldn't be called
|
||||||
// MojangApi.UsernameToUuids shouldn't be called
|
// MojangApi.UsernamesToUuids shouldn't be called
|
||||||
// MojangApi.UuidToTextures shouldn't be called
|
// MojangApi.UuidToTextures shouldn't be called
|
||||||
|
|
||||||
resultChan := suite.Queue.GetTexturesForUsername("maksimkurb")
|
resultChan := suite.Queue.GetTexturesForUsername("maksimkurb")
|
||||||
@@ -190,12 +192,12 @@ func (suite *QueueTestSuite) TestReceiveTexturesForUsernameWithFullyCachedResult
|
|||||||
suite.Assert().Equal(expectedResult, result)
|
suite.Assert().Equal(expectedResult, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *QueueTestSuite) TestReceiveTexturesForUsernameWithCachedUnknownUuid() {
|
func (suite *queueTestSuite) TestReceiveTexturesForUsernameWithCachedUnknownUuid() {
|
||||||
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("", nil)
|
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("", nil)
|
||||||
// Storage.StoreUuid shouldn't be called
|
// Storage.StoreUuid shouldn't be called
|
||||||
// Storage.GetTextures shouldn't be called
|
// Storage.GetTextures shouldn't be called
|
||||||
// Storage.StoreTextures shouldn't be called
|
// Storage.StoreTextures shouldn't be called
|
||||||
// MojangApi.UsernameToUuids shouldn't be called
|
// MojangApi.UsernamesToUuids shouldn't be called
|
||||||
// MojangApi.UuidToTextures shouldn't be called
|
// MojangApi.UuidToTextures shouldn't be called
|
||||||
|
|
||||||
resultChan := suite.Queue.GetTexturesForUsername("maksimkurb")
|
resultChan := suite.Queue.GetTexturesForUsername("maksimkurb")
|
||||||
@@ -205,7 +207,7 @@ func (suite *QueueTestSuite) TestReceiveTexturesForUsernameWithCachedUnknownUuid
|
|||||||
suite.Assert().Nil(<-resultChan)
|
suite.Assert().Nil(<-resultChan)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *QueueTestSuite) TestReceiveTexturesForMoreThan100Usernames() {
|
func (suite *queueTestSuite) TestReceiveTexturesForMoreThan100Usernames() {
|
||||||
usernames := make([]string, 120, 120)
|
usernames := make([]string, 120, 120)
|
||||||
for i := 0; i < 120; i++ {
|
for i := 0; i < 120; i++ {
|
||||||
usernames[i] = randStr(8)
|
usernames[i] = randStr(8)
|
||||||
@@ -214,8 +216,8 @@ func (suite *QueueTestSuite) TestReceiveTexturesForMoreThan100Usernames() {
|
|||||||
suite.Storage.On("GetUuid", mock.Anything).Times(120).Return("", &ValueNotFound{})
|
suite.Storage.On("GetUuid", mock.Anything).Times(120).Return("", &ValueNotFound{})
|
||||||
suite.Storage.On("StoreUuid", mock.Anything, "").Times(120) // if username is not compared to uuid, then receive ""
|
suite.Storage.On("StoreUuid", mock.Anything, "").Times(120) // if username is not compared to uuid, then receive ""
|
||||||
// Storage.GetTextures and Storage.SetTextures shouldn't be called
|
// Storage.GetTextures and Storage.SetTextures shouldn't be called
|
||||||
suite.MojangApi.On("UsernameToUuids", usernames[0:100]).Once().Return([]*mojang.ProfileInfo{}, nil)
|
suite.MojangApi.On("UsernamesToUuids", usernames[0:100]).Once().Return([]*mojang.ProfileInfo{}, nil)
|
||||||
suite.MojangApi.On("UsernameToUuids", usernames[100:120]).Once().Return([]*mojang.ProfileInfo{}, nil)
|
suite.MojangApi.On("UsernamesToUuids", usernames[100:120]).Once().Return([]*mojang.ProfileInfo{}, nil)
|
||||||
|
|
||||||
for _, username := range usernames {
|
for _, username := range usernames {
|
||||||
suite.Queue.GetTexturesForUsername(username)
|
suite.Queue.GetTexturesForUsername(username)
|
||||||
@@ -225,14 +227,14 @@ func (suite *QueueTestSuite) TestReceiveTexturesForMoreThan100Usernames() {
|
|||||||
suite.Iterate()
|
suite.Iterate()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *QueueTestSuite) TestReceiveTexturesForTheSameUsernames() {
|
func (suite *queueTestSuite) TestReceiveTexturesForTheSameUsernames() {
|
||||||
expectedResult := &mojang.SignedTexturesResponse{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"}
|
expectedResult := &mojang.SignedTexturesResponse{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"}
|
||||||
|
|
||||||
suite.Storage.On("GetUuid", "maksimkurb").Twice().Return("", &ValueNotFound{})
|
suite.Storage.On("GetUuid", "maksimkurb").Twice().Return("", &ValueNotFound{})
|
||||||
suite.Storage.On("StoreUuid", "maksimkurb", "0d252b7218b648bfb86c2ae476954d32").Once()
|
suite.Storage.On("StoreUuid", "maksimkurb", "0d252b7218b648bfb86c2ae476954d32").Once()
|
||||||
suite.Storage.On("GetTextures", "0d252b7218b648bfb86c2ae476954d32").Once().Return(nil, &ValueNotFound{})
|
suite.Storage.On("GetTextures", "0d252b7218b648bfb86c2ae476954d32").Once().Return(nil, &ValueNotFound{})
|
||||||
suite.Storage.On("StoreTextures", expectedResult).Once()
|
suite.Storage.On("StoreTextures", expectedResult).Once()
|
||||||
suite.MojangApi.On("UsernameToUuids", []string{"maksimkurb"}).Once().Return([]*mojang.ProfileInfo{
|
suite.MojangApi.On("UsernamesToUuids", []string{"maksimkurb"}).Once().Return([]*mojang.ProfileInfo{
|
||||||
{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"},
|
{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"},
|
||||||
}, nil)
|
}, nil)
|
||||||
suite.MojangApi.On("UuidToTextures", "0d252b7218b648bfb86c2ae476954d32", true).Once().Return(expectedResult, nil)
|
suite.MojangApi.On("UuidToTextures", "0d252b7218b648bfb86c2ae476954d32", true).Once().Return(expectedResult, nil)
|
||||||
@@ -246,14 +248,14 @@ func (suite *QueueTestSuite) TestReceiveTexturesForTheSameUsernames() {
|
|||||||
suite.Assert().Equal(expectedResult, <-resultChan2)
|
suite.Assert().Equal(expectedResult, <-resultChan2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *QueueTestSuite) TestReceiveTexturesForUsernameThatAlreadyProcessing() {
|
func (suite *queueTestSuite) TestReceiveTexturesForUsernameThatAlreadyProcessing() {
|
||||||
expectedResult := &mojang.SignedTexturesResponse{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"}
|
expectedResult := &mojang.SignedTexturesResponse{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"}
|
||||||
|
|
||||||
suite.Storage.On("GetUuid", "maksimkurb").Twice().Return("", &ValueNotFound{})
|
suite.Storage.On("GetUuid", "maksimkurb").Twice().Return("", &ValueNotFound{})
|
||||||
suite.Storage.On("StoreUuid", "maksimkurb", "0d252b7218b648bfb86c2ae476954d32").Once()
|
suite.Storage.On("StoreUuid", "maksimkurb", "0d252b7218b648bfb86c2ae476954d32").Once()
|
||||||
suite.Storage.On("GetTextures", "0d252b7218b648bfb86c2ae476954d32").Once().Return(nil, &ValueNotFound{})
|
suite.Storage.On("GetTextures", "0d252b7218b648bfb86c2ae476954d32").Once().Return(nil, &ValueNotFound{})
|
||||||
suite.Storage.On("StoreTextures", expectedResult).Once()
|
suite.Storage.On("StoreTextures", expectedResult).Once()
|
||||||
suite.MojangApi.On("UsernameToUuids", []string{"maksimkurb"}).Once().Return([]*mojang.ProfileInfo{
|
suite.MojangApi.On("UsernamesToUuids", []string{"maksimkurb"}).Once().Return([]*mojang.ProfileInfo{
|
||||||
{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"},
|
{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"},
|
||||||
}, nil)
|
}, nil)
|
||||||
suite.MojangApi.On("UuidToTextures", "0d252b7218b648bfb86c2ae476954d32", true).
|
suite.MojangApi.On("UuidToTextures", "0d252b7218b648bfb86c2ae476954d32", true).
|
||||||
@@ -275,11 +277,11 @@ func (suite *QueueTestSuite) TestReceiveTexturesForUsernameThatAlreadyProcessing
|
|||||||
suite.Assert().Equal(expectedResult, <-resultChan2)
|
suite.Assert().Equal(expectedResult, <-resultChan2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *QueueTestSuite) TestDoNothingWhenNoTasks() {
|
func (suite *queueTestSuite) TestDoNothingWhenNoTasks() {
|
||||||
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("", &ValueNotFound{})
|
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("", &ValueNotFound{})
|
||||||
suite.Storage.On("StoreUuid", "maksimkurb", "").Once()
|
suite.Storage.On("StoreUuid", "maksimkurb", "").Once()
|
||||||
// Storage.GetTextures and Storage.StoreTextures shouldn't be called
|
// Storage.GetTextures and Storage.StoreTextures shouldn't be called
|
||||||
suite.MojangApi.On("UsernameToUuids", []string{"maksimkurb"}).Once().Return([]*mojang.ProfileInfo{}, nil)
|
suite.MojangApi.On("UsernamesToUuids", []string{"maksimkurb"}).Once().Return([]*mojang.ProfileInfo{}, nil)
|
||||||
|
|
||||||
// Perform first iteration and await it finish
|
// Perform first iteration and await it finish
|
||||||
resultChan := suite.Queue.GetTexturesForUsername("maksimkurb")
|
resultChan := suite.Queue.GetTexturesForUsername("maksimkurb")
|
||||||
@@ -293,97 +295,60 @@ func (suite *QueueTestSuite) TestDoNothingWhenNoTasks() {
|
|||||||
suite.Iterate()
|
suite.Iterate()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *QueueTestSuite) TestHandleTooManyRequestsResponseWhenExchangingUsernamesToUuids() {
|
type timeoutError struct {
|
||||||
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("", &ValueNotFound{})
|
|
||||||
// Storage.StoreUuid, Storage.GetTextures and Storage.StoreTextures shouldn't be called
|
|
||||||
suite.MojangApi.On("UsernameToUuids", []string{"maksimkurb"}).Once().Return(nil, &mojang.TooManyRequestsError{})
|
|
||||||
|
|
||||||
resultChan := suite.Queue.GetTexturesForUsername("maksimkurb")
|
|
||||||
|
|
||||||
suite.Iterate()
|
|
||||||
|
|
||||||
suite.Assert().Nil(<-resultChan)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *QueueTestSuite) TestHandleServerErrorWhenExchangingUsernamesToUuids() {
|
func (*timeoutError) Error() string { return "timeout error" }
|
||||||
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("", &ValueNotFound{})
|
func (*timeoutError) Timeout() bool { return true }
|
||||||
// Storage.StoreUuid, Storage.GetTextures and Storage.StoreTextures shouldn't be called
|
func (*timeoutError) Temporary() bool { return false }
|
||||||
suite.MojangApi.On("UsernameToUuids", []string{"maksimkurb"}).Once().Return(nil, &mojang.ServerError{Status: 500})
|
|
||||||
|
|
||||||
resultChan := suite.Queue.GetTexturesForUsername("maksimkurb")
|
var expectedErrors = []error{
|
||||||
|
&mojang.BadRequestError{},
|
||||||
suite.Iterate()
|
&mojang.TooManyRequestsError{},
|
||||||
|
&mojang.ServerError{},
|
||||||
suite.Assert().Nil(<-resultChan)
|
&timeoutError{},
|
||||||
|
&net.OpError{Op: "read"},
|
||||||
|
&net.OpError{Op: "dial"},
|
||||||
|
syscall.ECONNREFUSED,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *QueueTestSuite) TestHandleEmptyResponseWhenRequestingUsersTextures() {
|
func (suite *queueTestSuite) TestShouldNotPanicWhenExpectedErrorReturnedFromUsernameToUuidRequest() {
|
||||||
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("", &ValueNotFound{})
|
for _, err := range expectedErrors {
|
||||||
suite.Storage.On("StoreUuid", "maksimkurb", "0d252b7218b648bfb86c2ae476954d32").Once()
|
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("", &ValueNotFound{})
|
||||||
suite.Storage.On("GetTextures", "0d252b7218b648bfb86c2ae476954d32").Once().Return(nil, &ValueNotFound{})
|
suite.MojangApi.On("UsernamesToUuids", []string{"maksimkurb"}).Once().Return(nil, err)
|
||||||
// Storage.StoreTextures shouldn't be called
|
resultChan := suite.Queue.GetTexturesForUsername("maksimkurb")
|
||||||
suite.MojangApi.On("UsernameToUuids", []string{"maksimkurb"}).Once().Return([]*mojang.ProfileInfo{
|
suite.Iterate()
|
||||||
{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"},
|
suite.Assert().Nil(<-resultChan)
|
||||||
}, nil)
|
suite.MojangApi.AssertExpectations(suite.T())
|
||||||
suite.MojangApi.On("UuidToTextures", "0d252b7218b648bfb86c2ae476954d32", true).Once().Return(
|
suite.MojangApi.ExpectedCalls = nil // https://github.com/stretchr/testify/issues/558#issuecomment-372112364
|
||||||
nil,
|
}
|
||||||
&mojang.EmptyResponse{},
|
|
||||||
)
|
|
||||||
|
|
||||||
resultChan := suite.Queue.GetTexturesForUsername("maksimkurb")
|
|
||||||
|
|
||||||
suite.Iterate()
|
|
||||||
|
|
||||||
suite.Assert().Nil(<-resultChan)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *QueueTestSuite) TestHandleTooManyRequestsResponseWhenRequestingUsersTextures() {
|
func (suite *queueTestSuite) TestShouldNotPanicWhenExpectedErrorReturnedFromUuidToTexturesRequest() {
|
||||||
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("", &ValueNotFound{})
|
for _, err := range expectedErrors {
|
||||||
suite.Storage.On("StoreUuid", "maksimkurb", "0d252b7218b648bfb86c2ae476954d32").Once()
|
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("", &ValueNotFound{})
|
||||||
suite.Storage.On("GetTextures", "0d252b7218b648bfb86c2ae476954d32").Once().Return(nil, &ValueNotFound{})
|
suite.Storage.On("StoreUuid", "maksimkurb", "0d252b7218b648bfb86c2ae476954d32").Once()
|
||||||
// Storage.StoreTextures shouldn't be called
|
suite.Storage.On("GetTextures", "0d252b7218b648bfb86c2ae476954d32").Once().Return(nil, &ValueNotFound{})
|
||||||
suite.MojangApi.On("UsernameToUuids", []string{"maksimkurb"}).Once().Return([]*mojang.ProfileInfo{
|
// Storage.StoreTextures shouldn't be called
|
||||||
{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"},
|
suite.MojangApi.On("UsernamesToUuids", []string{"maksimkurb"}).Once().Return([]*mojang.ProfileInfo{
|
||||||
}, nil)
|
{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"},
|
||||||
suite.MojangApi.On("UuidToTextures", "0d252b7218b648bfb86c2ae476954d32", true).Once().Return(
|
}, nil)
|
||||||
nil,
|
suite.MojangApi.On("UuidToTextures", "0d252b7218b648bfb86c2ae476954d32", true).Once().Return(nil, err)
|
||||||
&mojang.TooManyRequestsError{},
|
resultChan := suite.Queue.GetTexturesForUsername("maksimkurb")
|
||||||
)
|
suite.Iterate()
|
||||||
|
suite.Assert().Nil(<-resultChan)
|
||||||
resultChan := suite.Queue.GetTexturesForUsername("maksimkurb")
|
suite.MojangApi.AssertExpectations(suite.T())
|
||||||
|
suite.MojangApi.ExpectedCalls = nil // https://github.com/stretchr/testify/issues/558#issuecomment-372112364
|
||||||
suite.Iterate()
|
}
|
||||||
|
|
||||||
suite.Assert().Nil(<-resultChan)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *QueueTestSuite) TestHandleServerErrorWhenRequestingUsersTextures() {
|
func (suite *queueTestSuite) TestReceiveTexturesForNotAllowedMojangUsername() {
|
||||||
suite.Storage.On("GetUuid", "maksimkurb").Once().Return("", &ValueNotFound{})
|
|
||||||
suite.Storage.On("StoreUuid", "maksimkurb", "0d252b7218b648bfb86c2ae476954d32").Once()
|
|
||||||
suite.Storage.On("GetTextures", "0d252b7218b648bfb86c2ae476954d32").Once().Return(nil, &ValueNotFound{})
|
|
||||||
// Storage.StoreTextures shouldn't be called
|
|
||||||
suite.MojangApi.On("UsernameToUuids", []string{"maksimkurb"}).Once().Return([]*mojang.ProfileInfo{
|
|
||||||
{Id: "0d252b7218b648bfb86c2ae476954d32", Name: "maksimkurb"},
|
|
||||||
}, nil)
|
|
||||||
suite.MojangApi.On("UuidToTextures", "0d252b7218b648bfb86c2ae476954d32", true).Once().Return(
|
|
||||||
nil,
|
|
||||||
&mojang.ServerError{Status: 500},
|
|
||||||
)
|
|
||||||
|
|
||||||
resultChan := suite.Queue.GetTexturesForUsername("maksimkurb")
|
|
||||||
|
|
||||||
suite.Iterate()
|
|
||||||
|
|
||||||
suite.Assert().Nil(<-resultChan)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (suite *QueueTestSuite) TestReceiveTexturesForNotAllowedMojangUsername() {
|
|
||||||
resultChan := suite.Queue.GetTexturesForUsername("Not allowed")
|
resultChan := suite.Queue.GetTexturesForUsername("Not allowed")
|
||||||
suite.Assert().Nil(<-resultChan)
|
suite.Assert().Nil(<-resultChan)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestJobsQueueSuite(t *testing.T) {
|
func TestJobsQueueSuite(t *testing.T) {
|
||||||
suite.Run(t, new(QueueTestSuite))
|
suite.Run(t, new(queueTestSuite))
|
||||||
}
|
}
|
||||||
|
|
||||||
var replacer = strings.NewReplacer("-", "_", "=", "")
|
var replacer = strings.NewReplacer("-", "_", "=", "")
|
||||||
|
Reference in New Issue
Block a user