Skip to content

Commit

Permalink
Merge pull request #114 from go-park-mail-ru/NM-99
Browse files Browse the repository at this point in the history
NM-99
  • Loading branch information
bocharovatd authored Dec 18, 2024
2 parents c116619 + 5349efd commit 601eef7
Show file tree
Hide file tree
Showing 40 changed files with 1,487 additions and 6 deletions.
5 changes: 5 additions & 0 deletions internal/utils/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,8 @@ func JSONError(response http.ResponseWriter, statusCode int, message string) {
type ExistsResponse struct {
Exists bool `json:"exists"`
}

//easyjson:json
type CountResponse struct {
Count uint64 `json:"count"`
}
78 changes: 72 additions & 6 deletions internal/utils/response_easyjson.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions microservices/album/delivery.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ type Handlers interface {
DeleteFavoriteAlbum(response http.ResponseWriter, request *http.Request)
IsFavoriteAlbum(response http.ResponseWriter, request *http.Request)
GetFavoriteAlbums(response http.ResponseWriter, request *http.Request)
GetFavoriteAlbumsCount(response http.ResponseWriter, request *http.Request)
GetAlbumLikesCount(response http.ResponseWriter, request *http.Request)
}
73 changes: 73 additions & 0 deletions microservices/album/delivery/http/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,3 +327,76 @@ func (handlers *albumHandlers) GetFavoriteAlbums(response http.ResponseWriter, r
return
}
}

func (handlers *albumHandlers) GetFavoriteAlbumsCount(response http.ResponseWriter, request *http.Request) {
requestID := request.Context().Value(utils.RequestIDKey{})
vars := mux.Vars(request)
userID, err := uuid.Parse(vars["userID"])
if err != nil {
handlers.logger.Error(fmt.Sprintf("Get '%s' wrong user id: %v", vars["userID"], err), requestID)
utils.JSONError(response, http.StatusBadRequest, "Wrong id value")
return
}

count, err := handlers.usecase.GetFavoriteAlbumsCount(request.Context(), userID)
if err != nil {
handlers.logger.Error(fmt.Sprintf("Failed to get favorite albums count: %v", err), requestID)
utils.JSONError(response, http.StatusInternalServerError, fmt.Sprintf("Failed to get favorite albums count: %v", err))
return
} else if count == 0 {
utils.JSONError(response, http.StatusNotFound, "No favorite albums were found")
return
}

response.Header().Set("Content-Type", "application/json")
countResponse := &utils.CountResponse{Count: count}
rawBytes, err := easyjson.Marshal(countResponse)
if err != nil {
handlers.logger.Error(fmt.Sprintf("Failed to encode favorite albums count: %v", err), requestID)
utils.JSONError(response, http.StatusInternalServerError, fmt.Sprintf("Failed to encode favorite albums count: %v", err))
return
}

response.WriteHeader(http.StatusOK)
_, err = response.Write(rawBytes)
if err != nil {
handlers.logger.Error(fmt.Sprintf("Failed to write response: %v", err), requestID)
utils.JSONError(response, http.StatusInternalServerError, "Write response fail")
return
}
}

func (handlers *albumHandlers) GetAlbumLikesCount(response http.ResponseWriter, request *http.Request) {
requestID := request.Context().Value(utils.RequestIDKey{})
vars := mux.Vars(request)
albumID, err := strconv.ParseUint(vars["albumID"], 10, 64)
if err != nil {
handlers.logger.Error(fmt.Sprintf("Invalid album ID: %v", err), requestID)
utils.JSONError(response, http.StatusBadRequest, fmt.Sprintf("Invalid album ID: %v", err))
return
}

likesCount, err := handlers.usecase.GetAlbumLikesCount(request.Context(), albumID)
if err != nil {
handlers.logger.Error("Failed to get album likes count", requestID)
utils.JSONError(response, http.StatusInternalServerError, "Can't check is album in favorite")
return
}

response.Header().Set("Content-Type", "application/json")
countResponse := &utils.CountResponse{Count: likesCount}
rawBytes, err := easyjson.Marshal(countResponse)
if err != nil {
handlers.logger.Error(fmt.Sprintf("Failed to encode: %v", err), requestID)
utils.JSONError(response, http.StatusInternalServerError, fmt.Sprintf("Failed to encode: %v", err))
return
}

response.WriteHeader(http.StatusOK)
_, err = response.Write(rawBytes)
if err != nil {
handlers.logger.Error(fmt.Sprintf("Failed to write response: %v", err), requestID)
utils.JSONError(response, http.StatusInternalServerError, "Write response fail")
return
}
}
128 changes: 128 additions & 0 deletions microservices/album/delivery/http/handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,134 @@ func TestAlbumHandlers_GetFavoriteAlbums(t *testing.T) {
})
}

func TestAlbumHandlers_GetFavoriteAlbumsCount(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

cfg := &config.Config{}
logger := logger.New(&cfg.Service.Logger)
usecaseMock := mocks.NewMockUsecase(ctrl)
albumHandlers := NewAlbumHandlers(usecaseMock, logger)

t.Run("Success", func(t *testing.T) {
userID := uuid.New()
count := uint64(2)

usecaseMock.EXPECT().GetFavoriteAlbumsCount(gomock.Any(), userID).Return(count, nil)

router := mux.NewRouter()
router.HandleFunc("/api/v1/albums/favorite/count/{userID:[0-9a-fA-F-]+}", albumHandlers.GetFavoriteAlbumsCount).Methods("GET")

request, err := http.NewRequest(http.MethodGet, fmt.Sprintf("/api/v1/albums/favorite/count/%s", userID.String()), nil)
assert.NoError(t, err)

response := httptest.NewRecorder()
router.ServeHTTP(response, request)

res := response.Result()
assert.Equal(t, http.StatusOK, res.StatusCode)
assert.Contains(t, response.Body.String(), fmt.Sprintf(`"count":%d`, count))
})

t.Run("Wrong id value", func(t *testing.T) {
router := mux.NewRouter()
router.HandleFunc("/api/v1/albums/favorite/count/{userID:[0-9a-fA-F-]+}", albumHandlers.GetFavoriteAlbumsCount).Methods("GET")

request, err := http.NewRequest(http.MethodGet, "/api/v1/albums/favorite/count/123", nil)
assert.NoError(t, err)

response := httptest.NewRecorder()
router.ServeHTTP(response, request)

res := response.Result()
assert.Equal(t, http.StatusBadRequest, res.StatusCode)
assert.Contains(t, response.Body.String(), "Wrong id value")
})

t.Run("Error while getting favorite albums count", func(t *testing.T) {
userID := uuid.New()
mockError := fmt.Errorf("usecase error")
usecaseMock.EXPECT().GetFavoriteAlbumsCount(gomock.Any(), userID).Return(uint64(0), mockError)

router := mux.NewRouter()
router.HandleFunc("/api/v1/albums/favorite/count/{userID:[0-9a-fA-F-]+}", albumHandlers.GetFavoriteAlbumsCount).Methods("GET")

request, err := http.NewRequest(http.MethodGet, fmt.Sprintf("/api/v1/albums/favorite/count/%s", userID.String()), nil)
assert.NoError(t, err)

response := httptest.NewRecorder()
router.ServeHTTP(response, request)

res := response.Result()
assert.Equal(t, http.StatusInternalServerError, res.StatusCode)
assert.Contains(t, response.Body.String(), "Failed to get favorite albums count")
})
}

func TestAlbumHandlers_GetAlbumLikesCount(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

cfg := &config.Config{}
logger := logger.New(&cfg.Service.Logger)
usecaseMock := mocks.NewMockUsecase(ctrl)
albumHandlers := NewAlbumHandlers(usecaseMock, logger)

t.Run("Success", func(t *testing.T) {
albumID := uint64(123)
likesCount := uint64(10)

usecaseMock.EXPECT().GetAlbumLikesCount(gomock.Any(), albumID).Return(likesCount, nil)

router := mux.NewRouter()
router.HandleFunc("/api/v1/albums/likes/{albumID:[0-9]+}", albumHandlers.GetAlbumLikesCount).Methods("GET")

request, err := http.NewRequest(http.MethodGet, fmt.Sprintf("/api/v1/albums/likes/%d", albumID), nil)
assert.NoError(t, err)

response := httptest.NewRecorder()
router.ServeHTTP(response, request)

res := response.Result()
assert.Equal(t, http.StatusOK, res.StatusCode)
assert.Contains(t, response.Body.String(), fmt.Sprintf(`"count":%d`, likesCount))
})

t.Run("Invalid album ID", func(t *testing.T) {
router := mux.NewRouter()
router.HandleFunc("/api/v1/albums/likes/{albumID}", albumHandlers.GetAlbumLikesCount).Methods("GET")

request, err := http.NewRequest(http.MethodGet, "/api/v1/albums/likes/abc", nil)
assert.NoError(t, err)

response := httptest.NewRecorder()
router.ServeHTTP(response, request)

res := response.Result()
assert.Equal(t, http.StatusBadRequest, res.StatusCode)
assert.Contains(t, response.Body.String(), "Invalid album ID")
})

t.Run("Error while getting album likes count", func(t *testing.T) {
albumID := uint64(123)
mockError := fmt.Errorf("usecase error")
usecaseMock.EXPECT().GetAlbumLikesCount(gomock.Any(), albumID).Return(uint64(0), mockError)

router := mux.NewRouter()
router.HandleFunc("/api/v1/albums/likes/{albumID:[0-9]+}", albumHandlers.GetAlbumLikesCount).Methods("GET")

request, err := http.NewRequest(http.MethodGet, fmt.Sprintf("/api/v1/albums/likes/%d", albumID), nil)
assert.NoError(t, err)

response := httptest.NewRecorder()
router.ServeHTTP(response, request)

res := response.Result()
assert.Equal(t, http.StatusInternalServerError, res.StatusCode)
assert.Contains(t, response.Body.String(), "Can't check is album in favorite")
})
}

func createRequestWithVars(requestID string, userID uuid.UUID) *http.Request {
request := httptest.NewRequest(http.MethodGet, "/api/v1/albums/favorite/byUser/"+userID.String(), nil)
request = request.WithContext(context.WithValue(request.Context(), utils.RequestIDKey{}, requestID))
Expand Down
10 changes: 10 additions & 0 deletions microservices/album/delivery/http/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ func BindRoutes(s *httpServer.Server, artistClient artistService.ArtistServiceCl
middleware.AuthMiddleware(&s.CFG.Service.Auth, s.Logger, http.HandlerFunc(albumHandleres.GetFavoriteAlbums)),
).Methods("GET")

s.MUX.Handle(
"/api/v1/albums/favorite/count/{userID:[0-9a-fA-F-]+}",
middleware.AuthMiddleware(&s.CFG.Service.Auth, s.Logger, http.HandlerFunc(albumHandleres.GetFavoriteAlbumsCount)),
).Methods("GET")

s.MUX.Handle(
"/api/v1/albums/favorite/{albumID:[0-9]+}",
middleware.AuthMiddleware(&s.CFG.Service.Auth, s.Logger, http.HandlerFunc(albumHandleres.IsFavoriteAlbum)),
Expand All @@ -42,4 +47,9 @@ func BindRoutes(s *httpServer.Server, artistClient artistService.ArtistServiceCl
"/api/v1/albums/favorite/{albumID:[0-9]+}",
middleware.AuthMiddleware(&s.CFG.Service.Auth, s.Logger, http.HandlerFunc(albumHandleres.DeleteFavoriteAlbum)),
).Methods("DELETE")

s.MUX.Handle(
"/api/v1/albums/likes/{albumID:[0-9]+}",
middleware.AuthMiddleware(&s.CFG.Service.Auth, s.Logger, http.HandlerFunc(albumHandleres.GetAlbumLikesCount)),
).Methods("GET")
}
Loading

0 comments on commit 601eef7

Please sign in to comment.