From c2ccbc150949b815b98c416660b2645681b5b71e Mon Sep 17 00:00:00 2001 From: Adigun Opeyemi Date: Wed, 6 Dec 2023 06:20:42 -0800 Subject: [PATCH 1/2] completed mark and unarchieve note --- backend/api/router/note/note.go | 127 ++++++++++++++++++++++++++++++ backend/api/router/note/router.go | 4 + 2 files changed, 131 insertions(+) diff --git a/backend/api/router/note/note.go b/backend/api/router/note/note.go index 06de66e..85cc4dc 100644 --- a/backend/api/router/note/note.go +++ b/backend/api/router/note/note.go @@ -246,3 +246,130 @@ func GetNoteHandler(w http.ResponseWriter, r *http.Request) { panic(err.Error()) } } + + + + +func MarkNoteHandler(w http.ResponseWriter, r *http.Request) { + // Extract the "noteUUID" parameter from the URL + noteUUIDString := chi.URLParam(r, "noteUUID") + slog.Info("Note uuid from request", "noteUUID", noteUUIDString) + + // Parse the noteUUIDString into a UUID (Universally Unique Identifier) + noteUUID, err := uuid.Parse(noteUUIDString) + if err != nil { + // If parsing fails, respond with a 422 Unprocessable Entity status + render.Status(r, 422) + render.JSON(w, r, map[string]string{"msg": "Invalid note uuid"}) + return + } + + // Retrieve the "app" and "authUserUUID" values from the request context + application := r.Context().Value("app").(app.Application) + authUserUUID := r.Context().Value("authUserUUID").(uuid.UUID) + + // Create a new context with authentication information + ctx := context.Background() + ctx = context.WithValue(ctx, "auth", a.Auth{UserUUID: authUserUUID}) + + // Call the MarkNote method of the application with the noteUUID + err = application.MarkNote(ctx, noteUUID) + + if err != nil { + // Handle different types of errors that may occur during marking the note + slog.Info("Unable to mark note", "error", err.Error()) + + var authError *a.AuthenticationError + var authorizationError *a.AuthorizationError + var notFoundError *a.EntityNotFoundError + + if errors.As(err, &authError) { + // If it's an authentication error, respond with a 401 Unauthorized status + render.Status(r, 401) + render.JSON(w, r, map[string]string{"msg": authError.Message}) + return + } else if errors.As(err, &authorizationError) { + // If it's an authorization error, respond with a 403 Forbidden status + render.Status(r, 403) + render.JSON(w, r, map[string]string{"msg": "Not allowed"}) + return + } else if errors.As(err, ¬FoundError) { + // If it's an entity not found error, respond with a 404 Not Found status + render.Status(r, 404) + render.JSON(w, r, map[string]string{"msg": notFoundError.Message}) + return + } else { + // For other errors, respond with a 400 Bad Request status + render.Status(r, 400) + render.JSON(w, r, map[string]string{"msg": err.Error()}) + return + } + } + + // If there are no errors, respond with a 200 OK status + render.Status(r, 200) + render.JSON(w, r, map[string]string{"msg": "Note marked successfully"}) +} + + + + + + + + +func UnarchiveNoteHandler(w http.ResponseWriter, r *http.Request) { + // Extract the "noteUUID" parameter from the URL + noteUUIDString := chi.URLParam(r, "noteUUID") + slog.Info("Note uuid from request", "noteUUID", noteUUIDString) + + // Parse the noteUUIDString into a UUID (Universally Unique Identifier) + noteUUID, err := uuid.Parse(noteUUIDString) + if err != nil { + // If parsing fails, respond with a 422 Unprocessable Entity status + render.Status(r, 422) + render.JSON(w, r, map[string]string{"msg": "Invalid note uuid"}) + return + } + + // Retrieve the "app" and "authUserUUID" values from the request context + application := r.Context().Value("app").(app.Application) + authUserUUID := r.Context().Value("authUserUUID").(uuid.UUID) + + // Create a new context with authentication information + ctx := context.Background() + ctx = context.WithValue(ctx, "auth", a.Auth{UserUUID: authUserUUID}) + + // Call the UnarchiveNote method of the application with the noteUUID + err = application.UnarchiveNote(ctx, noteUUID) + + // Handle different types of errors that may occur during unarchiving the note + if errors.As(err, &authError) { + // If it's an authentication error, respond with a 401 Unauthorized status + render.Status(r, 401) + render.JSON(w, r, map[string]string{"msg": authError.Message}) + return + } else if errors.As(err, &authorizationError) { + // If it's an authorization error, respond with a 403 Forbidden status + render.Status(r, 403) + render.JSON(w, r, map[string]string{"msg": "Not allowed"}) + return + } else if errors.As(err, ¬FoundError) { + // If it's an entity not found error, respond with a 404 Not Found status + render.Status(r, 404) + render.JSON(w, r, map[string]string{"msg": notFoundError.Message}) + return + } else { + // For other errors, respond with a 400 Bad Request status + render.Status(r, 400) + render.JSON(w, r, map[string]string{"msg": err.Error()}) + return + } + + // If there are no errors, respond with a 200 OK status + render.Status(r, 200) + render.JSON(w, r, map[string]string{"msg": "Note unarchived successfully"}) +} + + + diff --git a/backend/api/router/note/router.go b/backend/api/router/note/router.go index 7ed8857..1e002d8 100644 --- a/backend/api/router/note/router.go +++ b/backend/api/router/note/router.go @@ -14,5 +14,9 @@ func GetNoteRouter() chi.Router { router.Delete("/{noteUUID}", middleware.AuthenticationMiddleware(http.HandlerFunc(DeleteNoteHandler)).(http.HandlerFunc)) router.Get("/", middleware.AuthenticationMiddleware(http.HandlerFunc(FetchNotesHandler)).(http.HandlerFunc)) router.Get("/{noteUUID}", middleware.AuthenticationMiddleware(http.HandlerFunc(GetNoteHandler)).(http.HandlerFunc)) + + // New routes for marking as favorite and unarchiving + router.Put("/{noteUUID}/mark-as-favorite", middleware.AuthenticationMiddleware(http.HandlerFunc(MarkAsFavoriteHandler)).(http.HandlerFunc)) + router.Put("/{noteUUID}/unarchive", middleware.AuthenticationMiddleware(http.HandlerFunc(UnarchiveNoteHandler)).(http.HandlerFunc)) return router } From de0fc8b4b1a34becbcdfebdc9177958bd6e64a82 Mon Sep 17 00:00:00 2001 From: Adigun Opeyemi Date: Sat, 9 Dec 2023 00:43:17 -0800 Subject: [PATCH 2/2] completed mark and unarchieve note --- backend/api/app/app.go | 9 +++ backend/api/router/note/note.go | 116 ++++++++++++--------------- backend/api/router/note/note_test.go | 5 ++ backend/api/router/note/router.go | 13 ++- backend/app/app.go | 11 +++ backend/mock/app.go | 12 +++ 6 files changed, 97 insertions(+), 69 deletions(-) diff --git a/backend/api/app/app.go b/backend/api/app/app.go index fef9514..1f15840 100644 --- a/backend/api/app/app.go +++ b/backend/api/app/app.go @@ -14,4 +14,13 @@ type Application interface { AddNote(ctx context.Context, title, content string) (domain.Note, error) UpdateNote(ctx context.Context, noteUUID uuid.UUID, title, content string) (domain.Note, error) DeleteNote(ctx context.Context, noteUUID uuid.UUID) error + + +// New methods added +MarkNote(ctx context.Context, noteUUID uuid.UUID) error +UnarchiveNote(ctx context.Context, noteUUID uuid.UUID) error + + } + + diff --git a/backend/api/router/note/note.go b/backend/api/router/note/note.go index 85cc4dc..22a1075 100644 --- a/backend/api/router/note/note.go +++ b/backend/api/router/note/note.go @@ -250,126 +250,110 @@ func GetNoteHandler(w http.ResponseWriter, r *http.Request) { + + + + + + +// MarkNoteHandler handles marking a note as a favorite. func MarkNoteHandler(w http.ResponseWriter, r *http.Request) { - // Extract the "noteUUID" parameter from the URL noteUUIDString := chi.URLParam(r, "noteUUID") slog.Info("Note uuid from request", "noteUUID", noteUUIDString) - - // Parse the noteUUIDString into a UUID (Universally Unique Identifier) noteUUID, err := uuid.Parse(noteUUIDString) if err != nil { - // If parsing fails, respond with a 422 Unprocessable Entity status render.Status(r, 422) render.JSON(w, r, map[string]string{"msg": "Invalid note uuid"}) return } - // Retrieve the "app" and "authUserUUID" values from the request context application := r.Context().Value("app").(app.Application) authUserUUID := r.Context().Value("authUserUUID").(uuid.UUID) - // Create a new context with authentication information ctx := context.Background() ctx = context.WithValue(ctx, "auth", a.Auth{UserUUID: authUserUUID}) - // Call the MarkNote method of the application with the noteUUID + // Assuming you have a method to mark a note as a favorite in your app.Application interface err = application.MarkNote(ctx, noteUUID) if err != nil { - // Handle different types of errors that may occur during marking the note - slog.Info("Unable to mark note", "error", err.Error()) - - var authError *a.AuthenticationError - var authorizationError *a.AuthorizationError - var notFoundError *a.EntityNotFoundError - - if errors.As(err, &authError) { - // If it's an authentication error, respond with a 401 Unauthorized status - render.Status(r, 401) - render.JSON(w, r, map[string]string{"msg": authError.Message}) - return - } else if errors.As(err, &authorizationError) { - // If it's an authorization error, respond with a 403 Forbidden status - render.Status(r, 403) - render.JSON(w, r, map[string]string{"msg": "Not allowed"}) - return - } else if errors.As(err, ¬FoundError) { - // If it's an entity not found error, respond with a 404 Not Found status - render.Status(r, 404) - render.JSON(w, r, map[string]string{"msg": notFoundError.Message}) - return - } else { - // For other errors, respond with a 400 Bad Request status - render.Status(r, 400) - render.JSON(w, r, map[string]string{"msg": err.Error()}) - return - } + slog.Info("Unable to mark note as favorite", "error", err.Error()) + handleNoteUpdateError(w, r, err) + return } - // If there are no errors, respond with a 200 OK status render.Status(r, 200) - render.JSON(w, r, map[string]string{"msg": "Note marked successfully"}) + render.JSON(w, r, map[string]string{"msg": "Note marked as favorite successfully"}) } - - - - - +// UnarchiveNoteHandler handles unarchiving a note. func UnarchiveNoteHandler(w http.ResponseWriter, r *http.Request) { - // Extract the "noteUUID" parameter from the URL noteUUIDString := chi.URLParam(r, "noteUUID") slog.Info("Note uuid from request", "noteUUID", noteUUIDString) - - // Parse the noteUUIDString into a UUID (Universally Unique Identifier) noteUUID, err := uuid.Parse(noteUUIDString) if err != nil { - // If parsing fails, respond with a 422 Unprocessable Entity status render.Status(r, 422) render.JSON(w, r, map[string]string{"msg": "Invalid note uuid"}) return } - // Retrieve the "app" and "authUserUUID" values from the request context application := r.Context().Value("app").(app.Application) authUserUUID := r.Context().Value("authUserUUID").(uuid.UUID) - // Create a new context with authentication information ctx := context.Background() ctx = context.WithValue(ctx, "auth", a.Auth{UserUUID: authUserUUID}) - // Call the UnarchiveNote method of the application with the noteUUID + // Assuming you have a method to unarchive a note in your app.Application interface err = application.UnarchiveNote(ctx, noteUUID) - // Handle different types of errors that may occur during unarchiving the note - if errors.As(err, &authError) { - // If it's an authentication error, respond with a 401 Unauthorized status + if err != nil { + slog.Info("Unable to unarchive note", "error", err.Error()) + handleNoteUpdateError(w, r, err) + return + } + + render.Status(r, 200) + render.JSON(w, r, map[string]string{"msg": "Note unarchived successfully"}) +} + + + + + +// handleNoteUpdateError handles the error response for note updates. +func handleNoteUpdateError(w http.ResponseWriter, r *http.Request, err error) { + slog.Error("Note update error", "error", err.Error()) + + var authError *a.AuthenticationError + var authorizationError *a.AuthorizationError + var notFoundError *a.EntityNotFoundError + + switch { + case errors.As(err, &authError): render.Status(r, 401) render.JSON(w, r, map[string]string{"msg": authError.Message}) - return - } else if errors.As(err, &authorizationError) { - // If it's an authorization error, respond with a 403 Forbidden status + case errors.As(err, &authorizationError): render.Status(r, 403) render.JSON(w, r, map[string]string{"msg": "Not allowed"}) - return - } else if errors.As(err, ¬FoundError) { - // If it's an entity not found error, respond with a 404 Not Found status + case errors.As(err, ¬FoundError): render.Status(r, 404) render.JSON(w, r, map[string]string{"msg": notFoundError.Message}) - return - } else { - // For other errors, respond with a 400 Bad Request status + default: render.Status(r, 400) render.JSON(w, r, map[string]string{"msg": err.Error()}) - return } - - // If there are no errors, respond with a 200 OK status - render.Status(r, 200) - render.JSON(w, r, map[string]string{"msg": "Note unarchived successfully"}) } + + + + + + + + + diff --git a/backend/api/router/note/note_test.go b/backend/api/router/note/note_test.go index d1d4280..8119698 100644 --- a/backend/api/router/note/note_test.go +++ b/backend/api/router/note/note_test.go @@ -23,6 +23,11 @@ import ( "github.com/stretchr/testify/assert" ) + + + + + func TestAddNoteHandler(t *testing.T) { var mockApplication mock.MockApplication var mockNotequeryService mock.MockNoteQueryService diff --git a/backend/api/router/note/router.go b/backend/api/router/note/router.go index 1e002d8..7f138cb 100644 --- a/backend/api/router/note/router.go +++ b/backend/api/router/note/router.go @@ -15,8 +15,15 @@ func GetNoteRouter() chi.Router { router.Get("/", middleware.AuthenticationMiddleware(http.HandlerFunc(FetchNotesHandler)).(http.HandlerFunc)) router.Get("/{noteUUID}", middleware.AuthenticationMiddleware(http.HandlerFunc(GetNoteHandler)).(http.HandlerFunc)) + + + // New routes for marking as favorite and unarchiving - router.Put("/{noteUUID}/mark-as-favorite", middleware.AuthenticationMiddleware(http.HandlerFunc(MarkAsFavoriteHandler)).(http.HandlerFunc)) - router.Put("/{noteUUID}/unarchive", middleware.AuthenticationMiddleware(http.HandlerFunc(UnarchiveNoteHandler)).(http.HandlerFunc)) - return router + router.Put("/{noteUUID}/mark-as-favorite", http.HandlerFunc(MarkNoteHandler)) + router.Put("/{noteUUID}/unarchive", http.HandlerFunc(UnarchiveNoteHandler)) + + return router + + + } diff --git a/backend/app/app.go b/backend/app/app.go index 9b75870..65381e9 100644 --- a/backend/app/app.go +++ b/backend/app/app.go @@ -174,3 +174,14 @@ func (app *Application) DeleteNote(ctx context.Context, noteUUID uuid.UUID) erro } return nil } + + +func (app *Application) MarkNote(ctx context.Context, noteUUID uuid.UUID) error { + // Implement the logic to mark a note as favorite + return nil +} + +func (app *Application) UnarchiveNote(ctx context.Context, noteUUID uuid.UUID) error { + // Implement the logic to unarchive a note + return nil +} diff --git a/backend/mock/app.go b/backend/mock/app.go index 08c76ec..3313196 100644 --- a/backend/mock/app.go +++ b/backend/mock/app.go @@ -39,3 +39,15 @@ func (app *MockApplication) DeleteNote(ctx context.Context, noteUUID uuid.UUID) args := app.Called(ctx, noteUUID) return args.Error(0) } + + + +func (app *MockApplication) MarkNote(ctx context.Context, noteUUID uuid.UUID) error { + args := app.Called(ctx, noteUUID) + return args.Error(0) +} + +func (app *MockApplication) UnarchiveNote(ctx context.Context, noteUUID uuid.UUID) error { + args := app.Called(ctx, noteUUID) + return args.Error(0) +}