From a311b4c838c4bcfd581719f2a056e7eb1f7b0406 Mon Sep 17 00:00:00 2001 From: Jeferson Date: Sun, 9 Feb 2025 21:09:23 -0300 Subject: [PATCH 1/2] =?UTF-8?q?fix:=20envia=20e-mail=20do=20usu=C3=A1rio?= =?UTF-8?q?=20na=20mensagem=20do=20sqs;=20remove=20middleware=20de=20auth?= =?UTF-8?q?=20para=20update=20da=20thumb?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/adapters/db/thumb_repository.go | 3 ++ .../adapters/rest/handler/thumb_handler.go | 28 +++++++++++-------- .../rest/middleware/authmiddleware.go | 5 +--- internal/adapters/rest/server/server.go | 7 ++--- internal/core/domain/entity/thumb_process.go | 5 +++- internal/core/ports/thumb_ports.go | 3 +- internal/core/thumb/thumb_service.go | 2 +- 7 files changed, 29 insertions(+), 24 deletions(-) diff --git a/internal/adapters/db/thumb_repository.go b/internal/adapters/db/thumb_repository.go index bc31470..b5f2298 100644 --- a/internal/adapters/db/thumb_repository.go +++ b/internal/adapters/db/thumb_repository.go @@ -25,6 +25,9 @@ type PostgresThumbRepository struct { func (r *PostgresThumbRepository) Create(process *entity.ThumbProcess) error { record := &ThumbPostgres{ + BaseModel: BaseModel{ + ID: process.ID, + }, VideoPath: process.Video.Path, ThumbnailPath: process.Thumbnail.Path, Status: process.Status, diff --git a/internal/adapters/rest/handler/thumb_handler.go b/internal/adapters/rest/handler/thumb_handler.go index 1869fdd..69ab28e 100644 --- a/internal/adapters/rest/handler/thumb_handler.go +++ b/internal/adapters/rest/handler/thumb_handler.go @@ -1,13 +1,13 @@ package handler import ( - "net/http" - "time" - "github.com/gin-gonic/gin" "github.com/google/uuid" + "github.com/pangolin-do-golang/thumb-processor-api/internal/adapters/rest/middleware" "github.com/pangolin-do-golang/thumb-processor-api/internal/core/ports" "github.com/pangolin-do-golang/thumb-processor-api/internal/core/thumb" + "github.com/pangolin-do-golang/thumb-processor-api/internal/core/users" + "net/http" ) type ThumbHandler struct { @@ -22,9 +22,9 @@ func NewThumbHandler(service thumb.IThumbService) *ThumbHandler { func (h *ThumbHandler) RegisterRoutes(router *gin.RouterGroup) { thumbGroup := router.Group("/thumbs") - thumbGroup.POST("", h.CreateProcess) + thumbGroup.POST("", middleware.AuthMiddleware(users.GetAllowedUsers), h.CreateProcess) thumbGroup.PUT("/:id", h.UpdateProcess) - thumbGroup.GET("", h.ListProcesses) + thumbGroup.GET("", middleware.AuthMiddleware(users.GetAllowedUsers), h.ListProcesses) } // @Summary Create a new thumbnail process @@ -53,8 +53,14 @@ func (h *ThumbHandler) CreateProcess(c *gin.Context) { return } + var userEmail string + ctxUser, ok := c.Get("user") + if ok { + userEmail = ctxUser.(string) + } err := h.thumbService.CreateProcessAsync(&ports.CreateProcessRequest{ - Url: request.URL, + UserEmail: userEmail, + Url: request.URL, }) if err != nil { c.JSON(http.StatusInternalServerError, ErrorResponse{ @@ -153,12 +159,10 @@ type UpdateProcessRequest struct { } type ThumbProcessResponse struct { - ID string `json:"id"` - Status string `json:"status"` - Error string `json:"error,omitempty"` - ThumbnailPath string `json:"thumbnail_path,omitempty"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + ID string `json:"id"` + Status string `json:"status"` + Error string `json:"error,omitempty"` + ThumbnailPath string `json:"thumbnail_path,omitempty"` } type ErrorResponse struct { diff --git a/internal/adapters/rest/middleware/authmiddleware.go b/internal/adapters/rest/middleware/authmiddleware.go index 6d013d5..7aff4cc 100644 --- a/internal/adapters/rest/middleware/authmiddleware.go +++ b/internal/adapters/rest/middleware/authmiddleware.go @@ -2,7 +2,6 @@ package middleware import ( "github.com/gin-gonic/gin" - "github.com/pangolin-do-golang/thumb-processor-api/internal/core/users" "net/http" ) @@ -22,9 +21,7 @@ func AuthMiddleware(allowedUsersFunc func() gin.Accounts) gin.HandlerFunc { return } - loggedUser := users.GetUserByNickname(username) - - c.Set("logged_user_id", loggedUser.ID) + c.Set("user", username) c.Next() // Continue to the handler } diff --git a/internal/adapters/rest/server/server.go b/internal/adapters/rest/server/server.go index 739c363..1f7e786 100644 --- a/internal/adapters/rest/server/server.go +++ b/internal/adapters/rest/server/server.go @@ -5,7 +5,6 @@ import ( "github.com/pangolin-do-golang/thumb-processor-api/internal/adapters/rest/handler" "github.com/pangolin-do-golang/thumb-processor-api/internal/adapters/rest/middleware" "github.com/pangolin-do-golang/thumb-processor-api/internal/core/thumb" - "github.com/pangolin-do-golang/thumb-processor-api/internal/core/users" ) type RestServer struct { @@ -33,11 +32,9 @@ func (rs RestServer) Serve() { handler.RegisterUserRoutes(r) // Rotes that need authentication - authorizedGroup := r.Group("/", middleware.AuthMiddleware(users.GetAllowedUsers)) + handler.RegisterLoginHandlers(r.Group("/")) - handler.RegisterLoginHandlers(authorizedGroup) - - handler.NewThumbHandler(rs.thumbService).RegisterRoutes(authorizedGroup) + handler.NewThumbHandler(rs.thumbService).RegisterRoutes(r.Group("/")) err := r.Run("0.0.0.0:8080") if err != nil { diff --git a/internal/core/domain/entity/thumb_process.go b/internal/core/domain/entity/thumb_process.go index 0a08635..b303eaf 100644 --- a/internal/core/domain/entity/thumb_process.go +++ b/internal/core/domain/entity/thumb_process.go @@ -16,6 +16,7 @@ var AllowedProcessStatus = map[string]bool{ type ThumbProcess struct { ID uuid.UUID `json:"id"` + UserEmail string `json:"user_email"` Video ThumbProcessVideo `json:"video"` Status string `json:"status"` Error string `json:"error,omitempty"` @@ -30,8 +31,10 @@ type ThumbProcessThumb struct { Path string `json:"url"` } -func NewThumbProcess(url string) *ThumbProcess { +func NewThumbProcess(url, email string) *ThumbProcess { return &ThumbProcess{ + ID: uuid.New(), + UserEmail: email, Video: ThumbProcessVideo{ Path: url, }, diff --git a/internal/core/ports/thumb_ports.go b/internal/core/ports/thumb_ports.go index 2647831..c197029 100644 --- a/internal/core/ports/thumb_ports.go +++ b/internal/core/ports/thumb_ports.go @@ -3,7 +3,8 @@ package ports import "github.com/google/uuid" type CreateProcessRequest struct { - Url string `json:"url"` + UserEmail string `json:"user_email"` + Url string `json:"url"` } type UpdateProcessRequest struct { diff --git a/internal/core/thumb/thumb_service.go b/internal/core/thumb/thumb_service.go index 1da98ef..fb5b6a8 100644 --- a/internal/core/thumb/thumb_service.go +++ b/internal/core/thumb/thumb_service.go @@ -22,7 +22,7 @@ func NewThumbService(repo contracts.IThumbRepositoryAdapter, q contracts.IThumbQ } func (s *Service) CreateProcessAsync(request *ports.CreateProcessRequest) error { - thumbProcess := entity.NewThumbProcess(request.Url) + thumbProcess := entity.NewThumbProcess(request.Url, request.UserEmail) if err := s.processRepository.Create(thumbProcess); err != nil { return err From 1e842bc79203169d90bc5d73cb3d72ecf134841c Mon Sep 17 00:00:00 2001 From: Jeferson Date: Sun, 9 Feb 2025 21:48:48 -0300 Subject: [PATCH 2/2] test: corrige testes com auth --- .../rest/handler/thumb_handler_test.go | 134 ++++++++++-------- internal/core/thumb/thumb_service_test.go | 4 +- 2 files changed, 74 insertions(+), 64 deletions(-) diff --git a/internal/adapters/rest/handler/thumb_handler_test.go b/internal/adapters/rest/handler/thumb_handler_test.go index d50bf84..525b606 100644 --- a/internal/adapters/rest/handler/thumb_handler_test.go +++ b/internal/adapters/rest/handler/thumb_handler_test.go @@ -26,60 +26,61 @@ func setupTest() (*gin.Engine, *servicemocks.IThumbService) { return router, mockService } -func TestCreateProcess(t *testing.T) { +func TestUpdateProcess(t *testing.T) { router, mockService := setupTest() + mockedUUID, _ := uuid.NewV7() - t.Run("successful creation", func(t *testing.T) { - mockService.On("CreateProcessAsync", mock.AnythingOfType("*ports.CreateProcessRequest")).Return(nil).Once() - - body := CreateProcessRequest{URL: "https://example.com/video.mp4"} - jsonBody, _ := json.Marshal(body) - - w := httptest.NewRecorder() - req, _ := http.NewRequest("POST", "/thumbs", bytes.NewBuffer(jsonBody)) - req.Header.Set("Content-Type", "application/json") - router.ServeHTTP(w, req) + t.Run("successful update", func(t *testing.T) { + updatedProcess := &entity.ThumbProcess{ + ID: mockedUUID, + Status: "completed", + Thumbnail: entity.ThumbProcessThumb{ + Path: "path/to/thumbnail.jpg", + }, + } - assert.Equal(t, http.StatusAccepted, w.Code) - }) + mockService.On("UpdateProcess", mock.AnythingOfType("*ports.UpdateProcessRequest")).Return(updatedProcess, nil).Once() - t.Run("invalid request", func(t *testing.T) { - body := CreateProcessRequest{URL: ""} // Empty URL + body := UpdateProcessRequest{ + Status: "completed", + ThumbnailPath: "path/to/thumbnail.jpg", + } jsonBody, _ := json.Marshal(body) w := httptest.NewRecorder() - req, _ := http.NewRequest("POST", "/thumbs", bytes.NewBuffer(jsonBody)) + req, _ := http.NewRequest("PUT", "/thumbs/"+mockedUUID.String(), bytes.NewBuffer(jsonBody)) req.Header.Set("Content-Type", "application/json") router.ServeHTTP(w, req) - assert.Equal(t, http.StatusBadRequest, w.Code) + assert.Equal(t, http.StatusOK, w.Code) }) - t.Run("service error", func(t *testing.T) { - mockService.On("CreateProcessAsync", mock.AnythingOfType("*ports.CreateProcessRequest")). - Return(errors.New("service error")).Once() - - body := CreateProcessRequest{URL: "https://example.com/video.mp4"} + t.Run("api bind ID param error", func(t *testing.T) { + body := UpdateProcessRequest{ + Status: "completed", + ThumbnailPath: "path/to/thumbnail.jpg", + } jsonBody, _ := json.Marshal(body) w := httptest.NewRecorder() - req, _ := http.NewRequest("POST", "/thumbs", bytes.NewBuffer(jsonBody)) + + req, _ := http.NewRequest("PUT", "/thumbs/invalid-uuid", bytes.NewBuffer(jsonBody)) req.Header.Set("Content-Type", "application/json") router.ServeHTTP(w, req) - assert.Equal(t, http.StatusInternalServerError, w.Code) + assert.Equal(t, http.StatusBadRequest, w.Code) var response ErrorResponse err := json.Unmarshal(w.Body.Bytes(), &response) assert.NoError(t, err) - assert.Equal(t, "service error", response.Error) + assert.Equal(t, "Process ID is required", response.Error) }) t.Run("api bind json error", func(t *testing.T) { - invalidJSON := []byte(`{"url": invalid-json}`) + invalidJSON := []byte(`{"status": invalid-json}`) w := httptest.NewRecorder() - req, _ := http.NewRequest("POST", "/thumbs", bytes.NewBuffer(invalidJSON)) + req, _ := http.NewRequest("PUT", "/thumbs/"+mockedUUID.String(), bytes.NewBuffer(invalidJSON)) req.Header.Set("Content-Type", "application/json") router.ServeHTTP(w, req) @@ -90,22 +91,10 @@ func TestCreateProcess(t *testing.T) { assert.NoError(t, err) assert.Equal(t, "Invalid request format", response.Error) }) -} - -func TestUpdateProcess(t *testing.T) { - router, mockService := setupTest() - mockedUUID, _ := uuid.NewV7() - t.Run("successful update", func(t *testing.T) { - updatedProcess := &entity.ThumbProcess{ - ID: mockedUUID, - Status: "completed", - Thumbnail: entity.ThumbProcessThumb{ - Path: "path/to/thumbnail.jpg", - }, - } - - mockService.On("UpdateProcess", mock.AnythingOfType("*ports.UpdateProcessRequest")).Return(updatedProcess, nil).Once() + t.Run("service error", func(t *testing.T) { + mockService.On("UpdateProcess", mock.AnythingOfType("*ports.UpdateProcessRequest")). + Return(nil, errors.New("service error")).Once() body := UpdateProcessRequest{ Status: "completed", @@ -118,40 +107,62 @@ func TestUpdateProcess(t *testing.T) { req.Header.Set("Content-Type", "application/json") router.ServeHTTP(w, req) - assert.Equal(t, http.StatusOK, w.Code) + assert.Equal(t, http.StatusInternalServerError, w.Code) + + var response ErrorResponse + err := json.Unmarshal(w.Body.Bytes(), &response) + assert.NoError(t, err) + assert.Equal(t, "service error", response.Error) }) +} - t.Run("api bind ID param error", func(t *testing.T) { - body := UpdateProcessRequest{ - Status: "completed", - ThumbnailPath: "path/to/thumbnail.jpg", +func TestCreateProcess(t *testing.T) { + router, mockService := setupTest() + + t.Run("successful create", func(t *testing.T) { + body := CreateProcessRequest{ + URL: "http://example.com/video.mp4", } jsonBody, _ := json.Marshal(body) + mockService.On("CreateProcessAsync", mock.AnythingOfType("*ports.CreateProcessRequest")).Return(nil).Once() + w := httptest.NewRecorder() + req, _ := http.NewRequest("POST", "/thumbs", bytes.NewBuffer(jsonBody)) + req.Header.Set("Content-Type", "application/json") + req.SetBasicAuth("test", "test") + router.ServeHTTP(w, req) - req, _ := http.NewRequest("PUT", "/thumbs/invalid-uuid", bytes.NewBuffer(jsonBody)) + assert.Equal(t, http.StatusAccepted, w.Code) + }) + + t.Run("invalid request format", func(t *testing.T) { + invalidJSON := []byte(`{"url": 123}`) + + w := httptest.NewRecorder() + req, _ := http.NewRequest("POST", "/thumbs", bytes.NewBuffer(invalidJSON)) req.Header.Set("Content-Type", "application/json") + req.SetBasicAuth("test", "test") router.ServeHTTP(w, req) assert.Equal(t, http.StatusBadRequest, w.Code) - var response ErrorResponse err := json.Unmarshal(w.Body.Bytes(), &response) assert.NoError(t, err) - assert.Equal(t, "Process ID is required", response.Error) + assert.Equal(t, "Invalid request format", response.Error) }) - t.Run("api bind json error", func(t *testing.T) { - invalidJSON := []byte(`{"status": invalid-json}`) + t.Run("missing URL", func(t *testing.T) { + body := CreateProcessRequest{} + jsonBody, _ := json.Marshal(body) w := httptest.NewRecorder() - req, _ := http.NewRequest("PUT", "/thumbs/"+mockedUUID.String(), bytes.NewBuffer(invalidJSON)) + req, _ := http.NewRequest("POST", "/thumbs", bytes.NewBuffer(jsonBody)) req.Header.Set("Content-Type", "application/json") + req.SetBasicAuth("test", "test") router.ServeHTTP(w, req) assert.Equal(t, http.StatusBadRequest, w.Code) - var response ErrorResponse err := json.Unmarshal(w.Body.Bytes(), &response) assert.NoError(t, err) @@ -159,22 +170,20 @@ func TestUpdateProcess(t *testing.T) { }) t.Run("service error", func(t *testing.T) { - mockService.On("UpdateProcess", mock.AnythingOfType("*ports.UpdateProcessRequest")). - Return(nil, errors.New("service error")).Once() - - body := UpdateProcessRequest{ - Status: "completed", - ThumbnailPath: "path/to/thumbnail.jpg", + body := CreateProcessRequest{ + URL: "http://example.com/video.mp4", } jsonBody, _ := json.Marshal(body) + mockService.On("CreateProcessAsync", mock.AnythingOfType("*ports.CreateProcessRequest")).Return(errors.New("service error")).Once() + w := httptest.NewRecorder() - req, _ := http.NewRequest("PUT", "/thumbs/"+mockedUUID.String(), bytes.NewBuffer(jsonBody)) + req, _ := http.NewRequest("POST", "/thumbs", bytes.NewBuffer(jsonBody)) req.Header.Set("Content-Type", "application/json") + req.SetBasicAuth("test", "test") router.ServeHTTP(w, req) assert.Equal(t, http.StatusInternalServerError, w.Code) - var response ErrorResponse err := json.Unmarshal(w.Body.Bytes(), &response) assert.NoError(t, err) @@ -204,6 +213,7 @@ func TestListProcesses(t *testing.T) { w := httptest.NewRecorder() req, _ := http.NewRequest("GET", "/thumbs", nil) + req.SetBasicAuth("test", "test") router.ServeHTTP(w, req) assert.Equal(t, http.StatusOK, w.Code) diff --git a/internal/core/thumb/thumb_service_test.go b/internal/core/thumb/thumb_service_test.go index 0537b9e..ba75476 100644 --- a/internal/core/thumb/thumb_service_test.go +++ b/internal/core/thumb/thumb_service_test.go @@ -52,8 +52,8 @@ func TestListProcess(t *testing.T) { service := NewThumbService(mockRepo, mockQueue) expectedList := &[]entity.ThumbProcess{ - *entity.NewThumbProcess("https://example.com/video1.mp4"), - *entity.NewThumbProcess("https://example.com/video2.mp4"), + *entity.NewThumbProcess("https://example.com/video1.mp4", "teste@teste.com"), + *entity.NewThumbProcess("https://example.com/video2.mp4", "teste@teste.com"), } mockRepo.On("List").Return(expectedList)