Implemented skin deleting

This commit is contained in:
ErickSkrauch 2018-01-23 22:58:42 +03:00
parent 1e2f30c6c7
commit 968c83db99
No known key found for this signature in database
GPG Key ID: 669339FCBB30EE0E
3 changed files with 147 additions and 4 deletions

View File

@ -13,6 +13,7 @@ import (
"elyby/minecraft-skinsystem/interfaces" "elyby/minecraft-skinsystem/interfaces"
"elyby/minecraft-skinsystem/model" "elyby/minecraft-skinsystem/model"
"github.com/gorilla/mux"
"github.com/mono83/slf/wd" "github.com/mono83/slf/wd"
"github.com/thedevsaddam/govalidator" "github.com/thedevsaddam/govalidator"
) )
@ -80,6 +81,28 @@ func (cfg *Config) PostSkin(resp http.ResponseWriter, req *http.Request) {
resp.WriteHeader(http.StatusCreated) resp.WriteHeader(http.StatusCreated)
} }
func (cfg *Config) DeleteSkinByUserId(resp http.ResponseWriter, req *http.Request) {
id, _ := strconv.Atoi(mux.Vars(req)["id"])
skin, err := cfg.SkinsRepo.FindByUserId(id)
if err != nil {
apiNotFound(resp, "Cannot find record for requested user id")
return
}
cfg.deleteSkin(skin, resp)
}
func (cfg *Config) DeleteSkinByUsername(resp http.ResponseWriter, req *http.Request) {
username := mux.Vars(req)["username"]
skin, err := cfg.SkinsRepo.FindByUsername(username)
if err != nil {
apiNotFound(resp, "Cannot find record for requested username")
return
}
cfg.deleteSkin(skin, resp)
}
func (cfg *Config) Authenticate(handler http.Handler) http.Handler { func (cfg *Config) Authenticate(handler http.Handler) http.Handler {
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
err := cfg.Auth.Check(req) err := cfg.Auth.Check(req)
@ -98,6 +121,17 @@ func (cfg *Config) Authenticate(handler http.Handler) http.Handler {
}) })
} }
func (cfg *Config) deleteSkin(skin *model.Skin, resp http.ResponseWriter) {
err := cfg.SkinsRepo.RemoveByUserId(skin.UserId)
if err != nil {
cfg.Logger.Error("Cannot delete skin by error: :err", wd.ErrParam(err))
apiServerError(resp)
return
}
resp.WriteHeader(http.StatusNoContent)
}
func validatePostSkinRequest(request *http.Request) map[string][]string { func validatePostSkinRequest(request *http.Request) map[string][]string {
const maxMultipartMemory int64 = 32 << 20 const maxMultipartMemory int64 = 32 << 20
const oneOfSkinOrUrlMessage = "One of url or skin should be provided, but not both" const oneOfSkinOrUrlMessage = "One of url or skin should be provided, but not both"
@ -197,6 +231,15 @@ func apiForbidden(resp http.ResponseWriter, reason string) {
resp.Write(result) resp.Write(result)
} }
func apiNotFound(resp http.ResponseWriter, reason string) {
resp.WriteHeader(http.StatusNotFound)
resp.Header().Set("Content-Type", "application/json")
result, _ := json.Marshal([]interface{}{
reason,
})
resp.Write(result)
}
func apiServerError(resp http.ResponseWriter) { func apiServerError(resp http.ResponseWriter) {
resp.WriteHeader(http.StatusInternalServerError) resp.WriteHeader(http.StatusInternalServerError)
} }

View File

@ -56,7 +56,7 @@ func TestConfig_PostSkin_Valid(t *testing.T) {
defer resp.Body.Close() defer resp.Body.Close()
assert.Equal(201, resp.StatusCode) assert.Equal(201, resp.StatusCode)
response, _ := ioutil.ReadAll(resp.Body) response, _ := ioutil.ReadAll(resp.Body)
assert.Empty(string(response)) assert.Empty(response)
} }
func TestConfig_PostSkin_ChangedIdentityId(t *testing.T) { func TestConfig_PostSkin_ChangedIdentityId(t *testing.T) {
@ -102,7 +102,7 @@ func TestConfig_PostSkin_ChangedIdentityId(t *testing.T) {
defer resp.Body.Close() defer resp.Body.Close()
assert.Equal(201, resp.StatusCode) assert.Equal(201, resp.StatusCode)
response, _ := ioutil.ReadAll(resp.Body) response, _ := ioutil.ReadAll(resp.Body)
assert.Empty(string(response)) assert.Empty(response)
} }
func TestConfig_PostSkin_ChangedUsername(t *testing.T) { func TestConfig_PostSkin_ChangedUsername(t *testing.T) {
@ -146,7 +146,7 @@ func TestConfig_PostSkin_ChangedUsername(t *testing.T) {
defer resp.Body.Close() defer resp.Body.Close()
assert.Equal(201, resp.StatusCode) assert.Equal(201, resp.StatusCode)
response, _ := ioutil.ReadAll(resp.Body) response, _ := ioutil.ReadAll(resp.Body)
assert.Empty(string(response)) assert.Empty(response)
} }
func TestConfig_PostSkin_CompletelyNewIdentity(t *testing.T) { func TestConfig_PostSkin_CompletelyNewIdentity(t *testing.T) {
@ -190,7 +190,7 @@ func TestConfig_PostSkin_CompletelyNewIdentity(t *testing.T) {
defer resp.Body.Close() defer resp.Body.Close()
assert.Equal(201, resp.StatusCode) assert.Equal(201, resp.StatusCode)
response, _ := ioutil.ReadAll(resp.Body) response, _ := ioutil.ReadAll(resp.Body)
assert.Empty(string(response)) assert.Empty(response)
} }
func TestConfig_PostSkin_UploadSkin(t *testing.T) { func TestConfig_PostSkin_UploadSkin(t *testing.T) {
@ -323,6 +323,104 @@ func TestConfig_PostSkin_Unauthorized(t *testing.T) {
]`, string(response)) ]`, string(response))
} }
func TestConfig_DeleteSkinByUserId_Success(t *testing.T) {
assert := testify.New(t)
ctrl := gomock.NewController(t)
defer ctrl.Finish()
config, mocks := setupMocks(ctrl)
req := httptest.NewRequest("DELETE", "http://skinsystem.ely.by/api/skins/id:1", nil)
w := httptest.NewRecorder()
mocks.Auth.EXPECT().Check(gomock.Any()).Return(nil)
mocks.Skins.EXPECT().FindByUserId(1).Return(createSkinModel("mock_user", false), nil)
mocks.Skins.EXPECT().RemoveByUserId(1).Return(nil)
config.CreateHandler().ServeHTTP(w, req)
resp := w.Result()
defer resp.Body.Close()
assert.Equal(204, resp.StatusCode)
response, _ := ioutil.ReadAll(resp.Body)
assert.Empty(response)
}
func TestConfig_DeleteSkinByUserId_NotFound(t *testing.T) {
assert := testify.New(t)
ctrl := gomock.NewController(t)
defer ctrl.Finish()
config, mocks := setupMocks(ctrl)
req := httptest.NewRequest("DELETE", "http://skinsystem.ely.by/api/skins/id:2", nil)
w := httptest.NewRecorder()
mocks.Auth.EXPECT().Check(gomock.Any()).Return(nil)
mocks.Skins.EXPECT().FindByUserId(2).Return(nil, &db.SkinNotFoundError{"unknown"})
config.CreateHandler().ServeHTTP(w, req)
resp := w.Result()
defer resp.Body.Close()
assert.Equal(404, resp.StatusCode)
response, _ := ioutil.ReadAll(resp.Body)
assert.JSONEq(`[
"Cannot find record for requested user id"
]`, string(response))
}
func TestConfig_DeleteSkinByUsername_Success(t *testing.T) {
assert := testify.New(t)
ctrl := gomock.NewController(t)
defer ctrl.Finish()
config, mocks := setupMocks(ctrl)
req := httptest.NewRequest("DELETE", "http://skinsystem.ely.by/api/skins/mock_user", nil)
w := httptest.NewRecorder()
mocks.Auth.EXPECT().Check(gomock.Any()).Return(nil)
mocks.Skins.EXPECT().FindByUsername("mock_user").Return(createSkinModel("mock_user", false), nil)
mocks.Skins.EXPECT().RemoveByUserId(1).Return(nil)
config.CreateHandler().ServeHTTP(w, req)
resp := w.Result()
defer resp.Body.Close()
assert.Equal(204, resp.StatusCode)
response, _ := ioutil.ReadAll(resp.Body)
assert.Empty(response)
}
func TestConfig_DeleteSkinByUsername_NotFound(t *testing.T) {
assert := testify.New(t)
ctrl := gomock.NewController(t)
defer ctrl.Finish()
config, mocks := setupMocks(ctrl)
req := httptest.NewRequest("DELETE", "http://skinsystem.ely.by/api/skins/mock_user_2", nil)
w := httptest.NewRecorder()
mocks.Auth.EXPECT().Check(gomock.Any()).Return(nil)
mocks.Skins.EXPECT().FindByUsername("mock_user_2").Return(nil, &db.SkinNotFoundError{"mock_user_2"})
config.CreateHandler().ServeHTTP(w, req)
resp := w.Result()
defer resp.Body.Close()
assert.Equal(404, resp.StatusCode)
response, _ := ioutil.ReadAll(resp.Body)
assert.JSONEq(`[
"Cannot find record for requested username"
]`, string(response))
}
// base64 https://github.com/mathiasbynens/small/blob/0ca3c51/png-transparent.png // base64 https://github.com/mathiasbynens/small/blob/0ca3c51/png-transparent.png
var OnePxPng = []byte("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg==") var OnePxPng = []byte("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg==")

View File

@ -62,6 +62,8 @@ func (cfg *Config) CreateHandler() http.Handler {
router.HandleFunc("/cloaks", cfg.CapeGET).Methods("GET") router.HandleFunc("/cloaks", cfg.CapeGET).Methods("GET")
// API // API
router.Handle("/api/skins", cfg.Authenticate(http.HandlerFunc(cfg.PostSkin))).Methods("POST") router.Handle("/api/skins", cfg.Authenticate(http.HandlerFunc(cfg.PostSkin))).Methods("POST")
router.Handle("/api/skins/id:{id:[0-9]+}", cfg.Authenticate(http.HandlerFunc(cfg.DeleteSkinByUserId))).Methods("DELETE")
router.Handle("/api/skins/{username}", cfg.Authenticate(http.HandlerFunc(cfg.DeleteSkinByUsername))).Methods("DELETE")
// 404 // 404
router.NotFoundHandler = http.HandlerFunc(cfg.NotFound) router.NotFoundHandler = http.HandlerFunc(cfg.NotFound)