Skip to content

Commit

Permalink
Merge pull request #5 from Questspace-v2/user/1
Browse files Browse the repository at this point in the history
Refactor user handlers' code
  • Loading branch information
BasedDepartment1 authored Oct 30, 2023
2 parents b65c660 + 09223c8 commit 57f440b
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 39 deletions.
9 changes: 8 additions & 1 deletion internal/handlers/user/create_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package user
import (
"encoding/json"
"errors"
"hash"
"net/http"
"questspace/internal/validate"
aerrors "questspace/pkg/application/errors"
Expand All @@ -18,15 +19,20 @@ const defaultAvatarURL = "https://api.dicebear.com/7.x/thumbs/svg"
type CreateHandler struct {
storage storage.UserStorage
fetcher http.Client
hasher hash.Hash
}

func NewCreateHandler(s storage.UserStorage, f http.Client) CreateHandler {
func NewCreateHandler(s storage.UserStorage, f http.Client, h hash.Hash) CreateHandler {
return CreateHandler{
storage: s,
fetcher: f,
hasher: h,
}
}

// @Param request body storage.CreateUserRequest true "query params"
// @Success 200 {object} storage.User
// @Router /user [post]
func (h CreateHandler) Handle(c *gin.Context) error {
data, err := c.GetRawData()
if err != nil {
Expand All @@ -42,6 +48,7 @@ func (h CreateHandler) Handle(c *gin.Context) error {
if req.AvatarURL == "" {
req.AvatarURL = defaultAvatarURL
}
req.Password = string(h.hasher.Sum([]byte(req.Password)))
user, err := h.storage.CreateUser(c, &req)
if err != nil {
if errors.Is(err, storage.ErrExists) {
Expand Down
16 changes: 12 additions & 4 deletions internal/handlers/user/create_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package user

import (
"bytes"
"crypto/sha256"
"encoding/json"
"net/http"
"net/http/httptest"
Expand Down Expand Up @@ -86,7 +87,8 @@ func TestCreateHandler_CommonCases(t *testing.T) {
ctrl := gomock.NewController(t)
userStorage := mocks.NewMockUserStorage(ctrl)
router := gin.Default()
handler := NewCreateHandler(userStorage, http.Client{})
hasher := sha256.New()
handler := NewCreateHandler(userStorage, http.Client{}, hasher)
router.POST("/test", application.AsGinHandler(handler.Handle))

for _, tc := range testCases {
Expand All @@ -105,9 +107,14 @@ func TestCreateHandler_CommonCases(t *testing.T) {
require.NoError(t, err)
request, err := http.NewRequest(http.MethodPost, "/test", bytes.NewReader(raw))
require.NoError(t, err)
actualReq := &storage.CreateUserRequest{
Username: tc.req.Username,
Password: string(hasher.Sum([]byte(tc.req.Password))),
AvatarURL: tc.req.AvatarURL,
}

if tc.wantStore {
userStorage.EXPECT().CreateUser(gomock.Any(), tc.req).Return(nil, tc.storeErr)
userStorage.EXPECT().CreateUser(gomock.Any(), actualReq).Return(nil, tc.storeErr)
}

router.ServeHTTP(rr, request)
Expand All @@ -120,9 +127,10 @@ func TestCreateHandler_SetsDefaultURL(t *testing.T) {
gin.SetMode(gin.TestMode)
ctrl := gomock.NewController(t)
userStorage := mocks.NewMockUserStorage(ctrl)
hasher := sha256.New()
rr := httptest.NewRecorder()
router := gin.Default()
handler := NewCreateHandler(userStorage, http.Client{})
handler := NewCreateHandler(userStorage, http.Client{}, hasher)
router.POST("/test", application.AsGinHandler(handler.Handle))

req := &storage.CreateUserRequest{
Expand All @@ -131,7 +139,7 @@ func TestCreateHandler_SetsDefaultURL(t *testing.T) {
}
storageReq := &storage.CreateUserRequest{
Username: "user",
Password: "password",
Password: string(hasher.Sum([]byte("password"))),
AvatarURL: defaultAvatarURL,
}

Expand Down
11 changes: 6 additions & 5 deletions internal/pgdb/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,6 @@ func (c *Client) CreateUser(ctx context.Context, req *storage.CreateUserRequest)
Columns("username", "password").
Suffix("RETURNING id").
PlaceholderFormat(sq.Dollar)
if req.FirstName != "" && req.LastName != "" {
query = query.Columns("first_name", "last_name")
values = append(values, req.FirstName, req.LastName)
}
if req.AvatarURL != "" {
query = query.Columns("avatar_url")
values = append(values, req.AvatarURL)
Expand All @@ -64,7 +60,12 @@ func (c *Client) CreateUser(ctx context.Context, req *storage.CreateUserRequest)
if err := row.Scan(&id); err != nil {
return nil, xerrors.Errorf("failed to scan row: %w", err)
}
user := storage.User(*req)
user := storage.User{
Id: id,
Username: req.Username,
Password: req.Password,
AvatarURL: req.AvatarURL,
}
user.Id = id
return &user, nil
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE "user" DROP COLUMN first_name, DROP COLUMN last_name;
4 changes: 3 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"crypto/sha256"
"fmt"
"net/http"
user "questspace/internal/handlers/user"
Expand Down Expand Up @@ -70,10 +71,11 @@ func Init(app application.App) error {
}
sqlStorage := pgdb.NewClient(conn)
client := http.Client{}
hasher := sha256.New()

userGroup := app.Router().Group("/user")

createHandler := user.NewCreateHandler(sqlStorage, client)
createHandler := user.NewCreateHandler(sqlStorage, client, hasher)
userGroup.POST("", application.AsGinHandler(createHandler.Handle))

getHandler := user.NewGetHandler(sqlStorage)
Expand Down
28 changes: 0 additions & 28 deletions pkg/storage/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,6 @@ type Quest struct {
MaxTeamCap *int
}

type CreateQuestRequest Quest

type GetQuestRequest struct {
Id string
}

type UpdateQuestRequest Quest

type DeleteQuestRequest GetQuestRequest

type Team struct {
Id string
Name string
Expand All @@ -58,25 +48,7 @@ type Team struct {
InviteLink string
}

type CreateTeamRequest Team

type User struct {
Id string `json:"id"`
Username string `json:"username"`
Password string `json:"password,omitempty"`
FirstName string `json:"first_name,omitempty"`
LastName string `json:"last_name,omitempty"`
AvatarURL string `json:"avatar_url,omitempty"`
}

type CreateUserRequest User

type GetUserRequest struct {
Id string
Username string
}

type UpdateUserRequest struct {
Id string `json:"id"`
Username string `json:"username"`
Password string `json:"password,omitempty"`
Expand Down
56 changes: 56 additions & 0 deletions pkg/storage/requests.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package storage

import "time"

type CreateUserRequest struct {
Username string `json:"username"`
Password string `json:"password,omitempty"`
AvatarURL string `json:"avatar_url,omitempty"`
}

type GetUserRequest struct {
Id string
Username string
}

type UpdateUserRequest struct {
Id string `json:"id"`
Username string `json:"username"`
Password string `json:"password,omitempty"`
AvatarURL string `json:"avatar_url,omitempty"`
}

type CreateQuestRequest struct {
Name string `json:"name"`
Description string `json:"description,omitempty"`
Access AccessType `json:"access"`
CreatorName string `json:"creator_name"`
Creator *User `json:"-"`
RegistrationDeadline *time.Time `json:"registration_deadline"`
StartTime *time.Time `json:"start_time"`
FinishTime *time.Time `json:"finish_time"`
MediaLink string `json:"media_link"`
MaxTeamCap *int `json:"max_team_cap"`
}

type GetQuestRequest struct {
Id string
}

type UpdateQuestRequest struct {
Id string `json:"id"`
Name string `json:"name"`
Description string `json:"description,omitempty"`
Access AccessType `json:"access"`
CreatorName string `json:"creator_name"`
Creator *User `json:"-"`
RegistrationDeadline *time.Time `json:"registration_deadline"`
StartTime *time.Time `json:"start_time"`
FinishTime *time.Time `json:"finish_time"`
MediaLink string `json:"media_link"`
MaxTeamCap *int `json:"max_team_cap"`
}

type DeleteQuestRequest struct {
Id string
}

0 comments on commit 57f440b

Please sign in to comment.