2020-04-19 05:01:09 +05:30
|
|
|
package http
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
2024-02-13 06:38:42 +05:30
|
|
|
"context"
|
2020-04-19 05:01:09 +05:30
|
|
|
"errors"
|
|
|
|
"io"
|
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
|
|
|
"net/url"
|
2024-01-30 13:35:04 +05:30
|
|
|
"strings"
|
2020-04-19 05:01:09 +05:30
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/mock"
|
|
|
|
"github.com/stretchr/testify/suite"
|
|
|
|
|
2024-02-01 12:42:34 +05:30
|
|
|
"ely.by/chrly/internal/db"
|
|
|
|
"ely.by/chrly/internal/profiles"
|
2020-04-19 05:01:09 +05:30
|
|
|
)
|
|
|
|
|
2024-01-30 13:35:04 +05:30
|
|
|
type ProfilesManagerMock struct {
|
|
|
|
mock.Mock
|
2020-04-19 05:01:09 +05:30
|
|
|
}
|
|
|
|
|
2024-02-13 06:38:42 +05:30
|
|
|
func (m *ProfilesManagerMock) PersistProfile(ctx context.Context, profile *db.Profile) error {
|
|
|
|
return m.Called(ctx, profile).Error(0)
|
2020-04-19 05:01:09 +05:30
|
|
|
}
|
|
|
|
|
2024-02-13 06:38:42 +05:30
|
|
|
func (m *ProfilesManagerMock) RemoveProfileByUuid(ctx context.Context, uuid string) error {
|
|
|
|
return m.Called(ctx, uuid).Error(0)
|
2020-04-19 05:01:09 +05:30
|
|
|
}
|
|
|
|
|
2024-03-05 17:37:54 +05:30
|
|
|
type ProfilesTestSuite struct {
|
2024-01-30 13:35:04 +05:30
|
|
|
suite.Suite
|
2020-04-19 05:01:09 +05:30
|
|
|
|
2024-03-05 17:37:54 +05:30
|
|
|
App *ProfilesApi
|
2020-04-19 05:01:09 +05:30
|
|
|
|
2024-01-30 13:35:04 +05:30
|
|
|
ProfilesManager *ProfilesManagerMock
|
2020-04-19 05:01:09 +05:30
|
|
|
}
|
|
|
|
|
2024-03-05 17:37:54 +05:30
|
|
|
func (t *ProfilesTestSuite) SetupSubTest() {
|
2024-01-30 13:35:04 +05:30
|
|
|
t.ProfilesManager = &ProfilesManagerMock{}
|
2024-03-13 05:59:26 +05:30
|
|
|
t.App, _ = NewProfilesApi(t.ProfilesManager)
|
2024-01-30 13:35:04 +05:30
|
|
|
}
|
2020-04-19 05:01:09 +05:30
|
|
|
|
2024-03-05 17:37:54 +05:30
|
|
|
func (t *ProfilesTestSuite) TearDownSubTest() {
|
2024-01-30 13:35:04 +05:30
|
|
|
t.ProfilesManager.AssertExpectations(t.T())
|
2020-04-19 05:01:09 +05:30
|
|
|
}
|
|
|
|
|
2024-03-05 17:37:54 +05:30
|
|
|
func (t *ProfilesTestSuite) TestPostProfile() {
|
2024-01-30 13:35:04 +05:30
|
|
|
t.Run("successfully post profile", func() {
|
2024-02-13 06:38:42 +05:30
|
|
|
t.ProfilesManager.On("PersistProfile", mock.Anything, &db.Profile{
|
2024-01-30 13:35:04 +05:30
|
|
|
Uuid: "0f657aa8-bfbe-415d-b700-5750090d3af3",
|
|
|
|
Username: "mock_username",
|
|
|
|
SkinUrl: "https://example.com/skin.png",
|
|
|
|
SkinModel: "slim",
|
|
|
|
CapeUrl: "https://example.com/cape.png",
|
|
|
|
MojangTextures: "bW9jawo=",
|
|
|
|
MojangSignature: "bW9jawo=",
|
|
|
|
}).Once().Return(nil)
|
|
|
|
|
2024-03-05 17:37:54 +05:30
|
|
|
req := httptest.NewRequest("POST", "http://chrly/", bytes.NewBufferString(url.Values{
|
2023-12-22 06:26:02 +05:30
|
|
|
"uuid": {"0f657aa8-bfbe-415d-b700-5750090d3af3"},
|
2024-01-30 13:35:04 +05:30
|
|
|
"username": {"mock_username"},
|
|
|
|
"skinUrl": {"https://example.com/skin.png"},
|
|
|
|
"skinModel": {"slim"},
|
|
|
|
"capeUrl": {"https://example.com/cape.png"},
|
|
|
|
"mojangTextures": {"bW9jawo="},
|
|
|
|
"mojangSignature": {"bW9jawo="},
|
|
|
|
}.Encode()))
|
|
|
|
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
|
|
|
w := httptest.NewRecorder()
|
2020-04-19 05:01:09 +05:30
|
|
|
|
2024-01-30 13:35:04 +05:30
|
|
|
t.App.Handler().ServeHTTP(w, req)
|
|
|
|
result := w.Result()
|
2020-04-19 05:01:09 +05:30
|
|
|
|
2024-01-30 13:35:04 +05:30
|
|
|
t.Equal(http.StatusCreated, result.StatusCode)
|
|
|
|
body, _ := io.ReadAll(result.Body)
|
|
|
|
t.Empty(body)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("handle malformed body", func() {
|
2024-03-05 17:37:54 +05:30
|
|
|
req := httptest.NewRequest("POST", "http://chrly/", strings.NewReader("invalid;=url?encoded_string"))
|
2020-04-19 05:01:09 +05:30
|
|
|
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
|
|
|
w := httptest.NewRecorder()
|
|
|
|
|
2024-01-30 13:35:04 +05:30
|
|
|
t.App.Handler().ServeHTTP(w, req)
|
|
|
|
result := w.Result()
|
2020-04-19 05:01:09 +05:30
|
|
|
|
2024-01-30 13:35:04 +05:30
|
|
|
t.Equal(http.StatusBadRequest, result.StatusCode)
|
|
|
|
body, _ := io.ReadAll(result.Body)
|
|
|
|
t.JSONEq(`{
|
2020-04-19 05:01:09 +05:30
|
|
|
"errors": {
|
2024-01-30 13:35:04 +05:30
|
|
|
"body": [
|
|
|
|
"The body of the request must be a valid url-encoded string"
|
2020-04-19 05:01:09 +05:30
|
|
|
]
|
|
|
|
}
|
|
|
|
}`, string(body))
|
|
|
|
})
|
|
|
|
|
2024-01-30 13:35:04 +05:30
|
|
|
t.Run("receive validation errors", func() {
|
2024-02-13 06:38:42 +05:30
|
|
|
t.ProfilesManager.On("PersistProfile", mock.Anything, mock.Anything).Once().Return(&profiles.ValidationError{
|
2024-01-30 13:35:04 +05:30
|
|
|
Errors: map[string][]string{
|
|
|
|
"mock": {"error1", "error2"},
|
|
|
|
},
|
|
|
|
})
|
2020-04-19 05:01:09 +05:30
|
|
|
|
2024-03-05 17:37:54 +05:30
|
|
|
req := httptest.NewRequest("POST", "http://chrly/", strings.NewReader(""))
|
2024-01-30 13:35:04 +05:30
|
|
|
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
2020-04-19 05:01:09 +05:30
|
|
|
w := httptest.NewRecorder()
|
|
|
|
|
2024-01-30 13:35:04 +05:30
|
|
|
t.App.Handler().ServeHTTP(w, req)
|
|
|
|
result := w.Result()
|
2020-04-19 05:01:09 +05:30
|
|
|
|
2024-01-30 13:35:04 +05:30
|
|
|
t.Equal(http.StatusBadRequest, result.StatusCode)
|
|
|
|
body, _ := io.ReadAll(result.Body)
|
|
|
|
t.JSONEq(`{
|
|
|
|
"errors": {
|
|
|
|
"mock": [
|
|
|
|
"error1",
|
|
|
|
"error2"
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}`, string(body))
|
2020-04-19 05:01:09 +05:30
|
|
|
})
|
|
|
|
|
2024-01-30 13:35:04 +05:30
|
|
|
t.Run("receive other error", func() {
|
2024-02-13 06:38:42 +05:30
|
|
|
t.ProfilesManager.On("PersistProfile", mock.Anything, mock.Anything).Once().Return(errors.New("mock error"))
|
2020-04-19 05:01:09 +05:30
|
|
|
|
2024-03-05 17:37:54 +05:30
|
|
|
req := httptest.NewRequest("POST", "http://chrly/", strings.NewReader(""))
|
2024-01-30 13:35:04 +05:30
|
|
|
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
2020-04-19 05:01:09 +05:30
|
|
|
w := httptest.NewRecorder()
|
|
|
|
|
2024-01-30 13:35:04 +05:30
|
|
|
t.App.Handler().ServeHTTP(w, req)
|
|
|
|
result := w.Result()
|
2020-04-19 05:01:09 +05:30
|
|
|
|
2024-01-30 13:35:04 +05:30
|
|
|
t.Equal(http.StatusInternalServerError, result.StatusCode)
|
2020-04-19 05:01:09 +05:30
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2024-03-05 17:37:54 +05:30
|
|
|
func (t *ProfilesTestSuite) TestDeleteProfileByUuid() {
|
2024-01-30 13:35:04 +05:30
|
|
|
t.Run("successfully delete", func() {
|
2024-02-13 06:38:42 +05:30
|
|
|
t.ProfilesManager.On("RemoveProfileByUuid", mock.Anything, "0f657aa8-bfbe-415d-b700-5750090d3af3").Once().Return(nil)
|
2020-04-19 05:01:09 +05:30
|
|
|
|
2024-03-05 17:37:54 +05:30
|
|
|
req := httptest.NewRequest("DELETE", "http://chrly/0f657aa8-bfbe-415d-b700-5750090d3af3", nil)
|
2020-04-19 05:01:09 +05:30
|
|
|
w := httptest.NewRecorder()
|
|
|
|
|
2024-01-30 13:35:04 +05:30
|
|
|
t.App.Handler().ServeHTTP(w, req)
|
2020-04-19 05:01:09 +05:30
|
|
|
|
|
|
|
resp := w.Result()
|
2024-01-30 13:35:04 +05:30
|
|
|
t.Equal(http.StatusNoContent, resp.StatusCode)
|
|
|
|
body, _ := io.ReadAll(resp.Body)
|
|
|
|
t.Empty(body)
|
2020-04-19 05:01:09 +05:30
|
|
|
})
|
|
|
|
|
2024-01-30 13:35:04 +05:30
|
|
|
t.Run("error from manager", func() {
|
2024-02-13 06:38:42 +05:30
|
|
|
t.ProfilesManager.On("RemoveProfileByUuid", mock.Anything, mock.Anything).Return(errors.New("mock error"))
|
2020-04-19 05:01:09 +05:30
|
|
|
|
2024-03-05 17:37:54 +05:30
|
|
|
req := httptest.NewRequest("DELETE", "http://chrly/0f657aa8-bfbe-415d-b700-5750090d3af3", nil)
|
2020-04-19 05:01:09 +05:30
|
|
|
w := httptest.NewRecorder()
|
|
|
|
|
2024-01-30 13:35:04 +05:30
|
|
|
t.App.Handler().ServeHTTP(w, req)
|
2020-04-19 05:01:09 +05:30
|
|
|
|
|
|
|
resp := w.Result()
|
2024-01-30 13:35:04 +05:30
|
|
|
t.Equal(http.StatusInternalServerError, resp.StatusCode)
|
2020-04-19 05:01:09 +05:30
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2024-03-05 17:37:54 +05:30
|
|
|
func TestProfilesApi(t *testing.T) {
|
|
|
|
suite.Run(t, new(ProfilesTestSuite))
|
2020-04-19 05:01:09 +05:30
|
|
|
}
|