From 1887454328438266f7246bc2fdd34239991644f5 Mon Sep 17 00:00:00 2001 From: Vargha Csongor Date: Fri, 18 Apr 2025 11:58:15 +0200 Subject: [PATCH] fix everysingle lint issue --- apps/db-adapter/internal/api/admin.go | 6 +- apps/db-adapter/internal/api/admin_test.go | 12 +- .../internal/api/auth/admin_operations.go | 16 +- .../internal/api/auth/read_operations.go | 8 +- apps/db-adapter/internal/api/person.go | 38 ++-- .../internal/api/person_and_relationship.go | 13 +- .../internal/api/person_family_tree.go | 15 +- apps/db-adapter/internal/api/person_google.go | 3 +- .../internal/api/person_google_test.go | 36 ++-- .../db-adapter/internal/api/person_recipes.go | 4 +- apps/db-adapter/internal/api/person_test.go | 202 ++++++++++++++++++ .../internal/api/recipe_relationship.go | 8 +- apps/db-adapter/internal/api/recipes.go | 6 +- apps/db-adapter/internal/api/relationship.go | 28 ++- apps/db-adapter/internal/api/server.go | 23 +- apps/db-adapter/internal/memgraph/admin.go | 6 +- .../internal/memgraph/admin_test.go | 12 +- .../internal/memgraph/cypher_verify_string.go | 2 +- .../internal/memgraph/family_tree.go | 4 +- .../internal/memgraph/family_tree_test.go | 22 +- apps/db-adapter/internal/memgraph/person.go | 4 +- .../internal/memgraph/person_google.go | 4 +- .../internal/memgraph/person_google_test.go | 41 ++-- .../internal/memgraph/person_test.go | 36 ++-- .../internal/memgraph/relationship.go | 16 +- .../internal/memgraph/relationship_test.go | 34 +-- apps/db-adapter/main.go | 2 +- apps/db-adapter/main_test.go | 2 +- .../pkg/gin/healthcheck/health_check_test.go | 2 +- 29 files changed, 435 insertions(+), 170 deletions(-) create mode 100644 apps/db-adapter/internal/api/person_test.go diff --git a/apps/db-adapter/internal/api/admin.go b/apps/db-adapter/internal/api/admin.go index 273b852..71aebef 100644 --- a/apps/db-adapter/internal/api/admin.go +++ b/apps/db-adapter/internal/api/admin.go @@ -12,7 +12,7 @@ import ( "github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/pkg/api" ) -func (srv *server) CreateAdminRelationship(c *gin.Context, id1 int, id2 int, params api.CreateAdminRelationshipParams) { +func (srv *server) CreateAdminRelationship(c *gin.Context, id1, id2 int, params api.CreateAdminRelationshipParams) { session := srv.db.NewSession(c.Request.Context(), neo4j.SessionConfig{}) defer closeSession(c.Request.Context(), srv.logger, session, srv.dbOpTimeout) @@ -37,7 +37,7 @@ func (srv *server) CreateAdminRelationship(c *gin.Context, id1 int, id2 int, par c.JSON(http.StatusOK, res) } -func (srv *server) DeleteAdminRelationship(c *gin.Context, id1 int, id2 int, params api.DeleteAdminRelationshipParams) { +func (srv *server) DeleteAdminRelationship(c *gin.Context, id1, id2 int, params api.DeleteAdminRelationshipParams) { session := srv.db.NewSession(c.Request.Context(), neo4j.SessionConfig{}) defer closeSession(c.Request.Context(), srv.logger, session, srv.dbOpTimeout) @@ -62,7 +62,7 @@ func (srv *server) DeleteAdminRelationship(c *gin.Context, id1 int, id2 int, par c.JSON(http.StatusOK, gin.H{"msg": "admin relationship was deleted"}) } -func (srv *server) GetAdminRelationship(c *gin.Context, id1 int, id2 int, params api.GetAdminRelationshipParams) { +func (srv *server) GetAdminRelationship(c *gin.Context, id1, id2 int, params api.GetAdminRelationshipParams) { session := srv.db.NewSession(c.Request.Context(), neo4j.SessionConfig{}) defer closeSession(c.Request.Context(), srv.logger, session, srv.dbOpTimeout) diff --git a/apps/db-adapter/internal/api/admin_test.go b/apps/db-adapter/internal/api/admin_test.go index 3118c0b..f46b0db 100644 --- a/apps/db-adapter/internal/api/admin_test.go +++ b/apps/db-adapter/internal/api/admin_test.go @@ -34,7 +34,7 @@ func TestCreateAdminRelationship(t *testing.T) { w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) - c.Request = httptest.NewRequest(http.MethodPost, "/admin", nil) + c.Request = httptest.NewRequestWithContext(t.Context(), http.MethodPost, "/admin", http.NoBody) params := api.CreateAdminRelationshipParams{XUserID: *api.IntPtr(1)} srv.CreateAdminRelationship(c, 1, 2, params) @@ -58,7 +58,7 @@ func TestCreateAdminRelationship(t *testing.T) { w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) - c.Request = httptest.NewRequest(http.MethodPost, "/admin", nil) + c.Request = httptest.NewRequestWithContext(t.Context(), http.MethodPost, "/admin", http.NoBody) params := api.CreateAdminRelationshipParams{XUserID: *api.IntPtr(3)} srv.CreateAdminRelationship(c, 1, 2, params) @@ -83,7 +83,7 @@ func TestCreateAdminRelationship(t *testing.T) { w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) - c.Request = httptest.NewRequest(http.MethodPost, "/admin", nil) + c.Request = httptest.NewRequestWithContext(t.Context(), http.MethodPost, "/admin", http.NoBody) params := api.CreateAdminRelationshipParams{XUserID: 1} srv.CreateAdminRelationship(c, 1, 2, params) @@ -112,7 +112,7 @@ func TestDeleteAdminRelationship(t *testing.T) { w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) - c.Request = httptest.NewRequest(http.MethodDelete, "/admin", nil) + c.Request = httptest.NewRequestWithContext(t.Context(), http.MethodDelete, "/admin", http.NoBody) params := api.DeleteAdminRelationshipParams{XUserID: 2} srv.DeleteAdminRelationship(c, 1, 2, params) @@ -136,7 +136,7 @@ func TestDeleteAdminRelationship(t *testing.T) { w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) - c.Request = httptest.NewRequest(http.MethodDelete, "/admin", nil) + c.Request = httptest.NewRequestWithContext(t.Context(), http.MethodDelete, "/admin", http.NoBody) params := api.DeleteAdminRelationshipParams{XUserID: 3} srv.DeleteAdminRelationship(c, 1, 2, params) @@ -161,7 +161,7 @@ func TestDeleteAdminRelationship(t *testing.T) { w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) - c.Request = httptest.NewRequest(http.MethodDelete, "/admin", nil) + c.Request = httptest.NewRequestWithContext(t.Context(), http.MethodDelete, "/admin", http.NoBody) params := api.DeleteAdminRelationshipParams{XUserID: 2} srv.DeleteAdminRelationship(c, 1, 2, params) diff --git a/apps/db-adapter/internal/api/auth/admin_operations.go b/apps/db-adapter/internal/api/auth/admin_operations.go index 6a8b8f9..f7509bb 100644 --- a/apps/db-adapter/internal/api/auth/admin_operations.go +++ b/apps/db-adapter/internal/api/auth/admin_operations.go @@ -16,17 +16,17 @@ import ( // - session: The Neo4j session used for database operations. // - userId: The ID of the user being managed. // - adminId: The ID of the admin attempting to manage the user. -// - XUserID: The ID of the currently authenticated user. +// - xUserID: The ID of the currently authenticated user. // // Returns: // - An error if the admin does not have the authority to manage the person, // or nil if the operation is allowed. -func CouldManagePerson(ctx context.Context, session neo4j.SessionWithContext, userId, adminId, XUserID int) error { - if adminId == XUserID { +func CouldManagePerson(ctx context.Context, session neo4j.SessionWithContext, userId, adminId, xUserID int) error { + if adminId == xUserID { return nil } - return CouldManagePersonUnknownAdmin(ctx, session, userId, XUserID) + return CouldManagePersonUnknownAdmin(ctx, session, userId, xUserID) } // CouldManagePersonUnknownAdmin checks if a user can manage another person @@ -38,16 +38,16 @@ func CouldManagePerson(ctx context.Context, session neo4j.SessionWithContext, us // - ctx: The context for managing request-scoped values, deadlines, and cancellations. // - session: The Neo4j session used to execute the database query. // - userId: The ID of the user attempting to manage another person. -// - XUserID: The ID of the person being managed. +// - xUserID: The ID of the person being managed. // // Returns: // - An error if the user is not allowed to manage the person or if there is // an issue querying the database. Returns nil if the user is allowed. -func CouldManagePersonUnknownAdmin(ctx context.Context, session neo4j.SessionWithContext, userId, XUserID int) error { - if userId == XUserID { +func CouldManagePersonUnknownAdmin(ctx context.Context, session neo4j.SessionWithContext, userId, xUserID int) error { + if userId == xUserID { return nil } - _, err := session.ExecuteRead(ctx, memgraph.GetAdminRelationship(ctx, userId, XUserID)) + _, err := session.ExecuteRead(ctx, memgraph.GetAdminRelationship(ctx, userId, xUserID)) return err } diff --git a/apps/db-adapter/internal/api/auth/read_operations.go b/apps/db-adapter/internal/api/auth/read_operations.go index a48b08d..4732c29 100644 --- a/apps/db-adapter/internal/api/auth/read_operations.go +++ b/apps/db-adapter/internal/api/auth/read_operations.go @@ -9,12 +9,12 @@ import ( "github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/pkg/api" ) -func CouldSeePersonsProfile(ctx context.Context, session neo4j.SessionWithContext, userId, XUserID int) error { - if CouldManagePersonUnknownAdmin(ctx, session, userId, XUserID) == nil { +func CouldSeePersonsProfile(ctx context.Context, session neo4j.SessionWithContext, userId, xUserID int) error { + if CouldManagePersonUnknownAdmin(ctx, session, userId, xUserID) == nil { return nil } - res, err := session.ExecuteRead(ctx, memgraph.GetFamilyTreeById(ctx, XUserID)) + res, err := session.ExecuteRead(ctx, memgraph.GetFamilyTreeById(ctx, xUserID)) if err != nil { return err } @@ -35,5 +35,5 @@ func CouldSeePersonsProfile(ctx context.Context, session neo4j.SessionWithContex } } - return fmt.Errorf("user %d does not have permission to see user %d", XUserID, userId) + return fmt.Errorf("user %d does not have permission to see user %d", xUserID, userId) } diff --git a/apps/db-adapter/internal/api/person.go b/apps/db-adapter/internal/api/person.go index c78d25f..e04e220 100644 --- a/apps/db-adapter/internal/api/person.go +++ b/apps/db-adapter/internal/api/person.go @@ -10,6 +10,7 @@ import ( "github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/internal/api/auth" "github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/internal/memgraph" "github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/pkg/api" + "go.uber.org/zap" ) func (srv *server) CreatePerson(c *gin.Context, params api.CreatePersonParams) { @@ -30,8 +31,9 @@ func (srv *server) CreatePerson(c *gin.Context, params api.CreatePersonParams) { return } defer func() { - trs.Commit(c.Request.Context()) - trs.Close(c.Request.Context()) + if err := trs.Close(c.Request.Context()); err != nil { //nolint:govet // ignore shadowing + srv.logger.Error("failed to close transaction", zap.Error(err)) + } }() qctx, qCancel := context.WithTimeout(c.Request.Context(), srv.dbOpTimeout) @@ -51,6 +53,7 @@ func (srv *server) CreatePerson(c *gin.Context, params api.CreatePersonParams) { return } + personId, ok := singleRes.Get("id") if !ok { c.JSON(http.StatusInternalServerError, gin.H{"msg": "Person ID not found in response"}) @@ -70,13 +73,18 @@ func (srv *server) CreatePerson(c *gin.Context, params api.CreatePersonParams) { return } + if err := trs.Commit(c.Request.Context()); err != nil { + srv.logger.Error("failed to commit transaction", zap.Error(err)) + c.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + + return + } + c.JSON(http.StatusOK, singleRes.AsMap()) } -func (srv *server) GetPersonById(c *gin.Context, id int, params api.GetPersonByIdParams) { - ctx, cancel := context.WithTimeout(c.Request.Context(), srv.dbOpTimeout) - defer cancel() - session := srv.db.NewSession(ctx, neo4j.SessionConfig{}) +func (srv *server) GetPersonById(c *gin.Context, id int, params api.GetPersonByIdParams) { //nolint:dupl // not worth abstracting more + session := srv.createSessionWithTimeout(c.Request.Context()) defer closeSession(c.Request.Context(), srv.logger, session, srv.dbOpTimeout) actx, acancel := context.WithTimeout(c.Request.Context(), srv.dbOpTimeout) @@ -99,10 +107,8 @@ func (srv *server) GetPersonById(c *gin.Context, id int, params api.GetPersonByI c.JSON(http.StatusOK, res) } -func (srv *server) SoftDeletePerson(c *gin.Context, id int, params api.SoftDeletePersonParams) { - ctx, cancel := context.WithTimeout(c.Request.Context(), srv.dbOpTimeout) - defer cancel() - session := srv.db.NewSession(ctx, neo4j.SessionConfig{}) +func (srv *server) SoftDeletePerson(c *gin.Context, id int, params api.SoftDeletePersonParams) { //nolint:dupl,lll // not worth abstracting more than this + session := srv.createSessionWithTimeout(c.Request.Context()) defer closeSession(c.Request.Context(), srv.logger, session, srv.dbOpTimeout) actx, acancel := context.WithTimeout(c.Request.Context(), srv.dbOpTimeout) @@ -133,11 +139,11 @@ func (srv *server) UpdatePerson(c *gin.Context, id int, params api.UpdatePersonP return } - actx, acancel := context.WithTimeout(c.Request.Context(), srv.dbOpTimeout) - defer acancel() - session := srv.db.NewSession(actx, neo4j.SessionConfig{}) + session := srv.createSessionWithTimeout(c.Request.Context()) defer closeSession(c.Request.Context(), srv.logger, session, srv.dbOpTimeout) + actx, acancel := context.WithTimeout(c.Request.Context(), srv.dbOpTimeout) + defer acancel() if err := auth.CouldManagePersonUnknownAdmin(actx, session, id, params.XUserID); err != nil { c.JSON(http.StatusUnauthorized, gin.H{"msg": fmt.Sprint("User does not have access to this person", err.Error())}) @@ -156,10 +162,8 @@ func (srv *server) UpdatePerson(c *gin.Context, id int, params api.UpdatePersonP c.JSON(http.StatusOK, res) } -func (srv *server) HardDeletePerson(c *gin.Context, id int, params api.HardDeletePersonParams) { - ctx, cancel := context.WithTimeout(c.Request.Context(), srv.dbOpTimeout) - defer cancel() - session := srv.db.NewSession(ctx, neo4j.SessionConfig{}) +func (srv *server) HardDeletePerson(c *gin.Context, id int, params api.HardDeletePersonParams) { //nolint:dupl,lll // This just does not worth abstracting anymore + session := srv.createSessionWithTimeout(c.Request.Context()) defer closeSession(c.Request.Context(), srv.logger, session, srv.dbOpTimeout) actx, acancel := context.WithTimeout(c.Request.Context(), srv.dbOpTimeout) diff --git a/apps/db-adapter/internal/api/person_and_relationship.go b/apps/db-adapter/internal/api/person_and_relationship.go index 58263b2..5c925c5 100644 --- a/apps/db-adapter/internal/api/person_and_relationship.go +++ b/apps/db-adapter/internal/api/person_and_relationship.go @@ -8,6 +8,7 @@ import ( "github.com/neo4j/neo4j-go-driver/v5/neo4j" "github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/internal/memgraph" "github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/pkg/api" + "go.uber.org/zap" ) func (srv *server) CreatePersonAndRelationship(c *gin.Context, id int, params api.CreatePersonAndRelationshipParams) { @@ -28,8 +29,9 @@ func (srv *server) CreatePersonAndRelationship(c *gin.Context, id int, params ap return } defer func() { - trs.Commit(c.Request.Context()) - trs.Close(c.Request.Context()) + if err := trs.Close(c.Request.Context()); err != nil { //nolint:govet // ignore errcheck + srv.logger.Error("failed to close transaction", zap.Error(err)) + } }() qctx, qCancel := context.WithTimeout(context.Background(), srv.dbOpTimeout) @@ -111,6 +113,13 @@ func (srv *server) CreatePersonAndRelationship(c *gin.Context, id int, params ap return } + if err := trs.Commit(c.Request.Context()); err != nil { + srv.logger.Error("failed to commit transaction", zap.Error(err)) + c.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()}) + + return + } + c.JSON(http.StatusOK, struct { Person any `json:"person"` Rel any `json:"relationship"` diff --git a/apps/db-adapter/internal/api/person_family_tree.go b/apps/db-adapter/internal/api/person_family_tree.go index 12b2bd5..7cd7fb5 100644 --- a/apps/db-adapter/internal/api/person_family_tree.go +++ b/apps/db-adapter/internal/api/person_family_tree.go @@ -5,17 +5,14 @@ import ( "net/http" "github.com/gin-gonic/gin" - "github.com/neo4j/neo4j-go-driver/v5/neo4j" "github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/internal/memgraph" "github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/pkg/api" ) func (srv *server) GetFamilyTreeById(c *gin.Context, params api.GetFamilyTreeByIdParams) { - ctx, cancel := context.WithTimeout(context.Background(), srv.dbOpTimeout) - defer cancel() - session := srv.db.NewSession(ctx, neo4j.SessionConfig{}) + session := srv.createSessionWithTimeout(c.Request.Context()) - qctx, qCancel := context.WithTimeout(context.Background(), srv.dbOpTimeout) + qctx, qCancel := context.WithTimeout(c.Request.Context(), srv.dbOpTimeout) defer qCancel() res, err := session.ExecuteRead(qctx, memgraph.GetFamilyTreeById(qctx, params.XUserID)) if err != nil { @@ -26,10 +23,10 @@ func (srv *server) GetFamilyTreeById(c *gin.Context, params api.GetFamilyTreeByI c.JSON(http.StatusOK, res) } -func (srv *server) GetFamilyTreeWithSpousesById(c *gin.Context, params api.GetFamilyTreeWithSpousesByIdParams) { - ctx, cancel := context.WithTimeout(context.Background(), srv.dbOpTimeout) - defer cancel() - session := srv.db.NewSession(ctx, neo4j.SessionConfig{}) +func (srv *server) GetFamilyTreeWithSpousesById( + c *gin.Context, params api.GetFamilyTreeWithSpousesByIdParams, +) { + session := srv.createSessionWithTimeout(c.Request.Context()) qctx, qCancel := context.WithTimeout(context.Background(), srv.dbOpTimeout) defer qCancel() diff --git a/apps/db-adapter/internal/api/person_google.go b/apps/db-adapter/internal/api/person_google.go index dd15bfe..6b8869b 100644 --- a/apps/db-adapter/internal/api/person_google.go +++ b/apps/db-adapter/internal/api/person_google.go @@ -29,8 +29,8 @@ func (srv *server) GetPersonByGoogleId(c *gin.Context, googleId string) { func (srv *server) CreatePersonByGoogleIdAndInviteCode(c *gin.Context, googleId string) { var person struct { - InviteCode string `json:"invite_code"` Props *api.PersonProperties `json:"person"` + InviteCode string `json:"invite_code"` } if err := c.ShouldBindJSON(&person); err != nil { c.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()}) @@ -40,6 +40,7 @@ func (srv *server) CreatePersonByGoogleIdAndInviteCode(c *gin.Context, googleId emptyString := "" person.Props.InviteCode = &emptyString + person.Props.GoogleId = &googleId ctx, cancel := context.WithTimeout(c.Request.Context(), srv.dbOpTimeout) defer cancel() diff --git a/apps/db-adapter/internal/api/person_google_test.go b/apps/db-adapter/internal/api/person_google_test.go index 0aaf321..d3e8c9b 100644 --- a/apps/db-adapter/internal/api/person_google_test.go +++ b/apps/db-adapter/internal/api/person_google_test.go @@ -22,7 +22,9 @@ func TestGetPersonByGoogleId(t *testing.T) { mockSession := new(memgraphMock.SessionWithContext) mockDriver := new(memgraphMock.DriverWithContext) mockDriver.On("NewSession", mock.Anything, mock.Anything).Return(mockSession) - mockSession.On("ExecuteRead", mock.Anything, mock.Anything, mock.Anything).Return(map[string]any{"person": "test-person"}, nil) + mockSession.On("ExecuteRead", mock.Anything, mock.Anything, mock.Anything).Return( + map[string]any{"person": "test-person"}, nil, + ) mockSession.On("Close", mock.Anything).Return(nil) srv := &server{ @@ -33,7 +35,9 @@ func TestGetPersonByGoogleId(t *testing.T) { w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) - c.Request = httptest.NewRequest(http.MethodGet, "/person/google-id", nil) + c.Request = httptest.NewRequestWithContext( + t.Context(), http.MethodGet, "/person/google-id", http.NoBody, + ) srv.GetPersonByGoogleId(c, "test-google-id") @@ -56,7 +60,7 @@ func TestGetPersonByGoogleId(t *testing.T) { w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) - c.Request = httptest.NewRequest(http.MethodGet, "/person/google-id", nil) + c.Request = httptest.NewRequestWithContext(t.Context(), http.MethodGet, "/person/google-id", http.NoBody) srv.GetPersonByGoogleId(c, "test-google-id") @@ -83,9 +87,10 @@ func TestCreatePersonByGoogleIdAndInviteCode(t *testing.T) { w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) - body := `{"invite_code": "test-code", "person": {"name": "test-person"}}` - c.Request = httptest.NewRequest(http.MethodPost, "/person/google-id/invite-code", nil) - c.Request.Body = io.NopCloser(strings.NewReader(body)) + body := `{"invite_code": "test-code", "person": {"first_name": "test-person"}}` + c.Request = httptest.NewRequest( + http.MethodPost, "/person/google-id/invite-code", io.NopCloser(strings.NewReader(body)), + ) srv.CreatePersonByGoogleIdAndInviteCode(c, "test-google-id") @@ -100,8 +105,9 @@ func TestCreatePersonByGoogleIdAndInviteCode(t *testing.T) { c, _ := gin.CreateTestContext(w) body := `{"invalid_json":` - c.Request = httptest.NewRequest(http.MethodPost, "/person/google-id/invite-code", nil) - c.Request.Body = io.NopCloser(strings.NewReader(body)) + c.Request = httptest.NewRequest( + http.MethodPost, "/person/google-id/invite-code", io.NopCloser(strings.NewReader(body)), + ) srv.CreatePersonByGoogleIdAndInviteCode(c, "test-google-id") @@ -117,7 +123,9 @@ func TestCreatePersonByGoogleId(t *testing.T) { mockSession := new(memgraphMock.SessionWithContext) mockDriver := new(memgraphMock.DriverWithContext) mockDriver.On("NewSession", mock.Anything, mock.Anything).Return(mockSession) - mockSession.On("ExecuteWrite", mock.Anything, mock.Anything, mock.Anything).Return(map[string]any{"result": "success"}, nil) + mockSession.On("ExecuteWrite", mock.Anything, mock.Anything, mock.Anything).Return( + map[string]any{"result": "success"}, nil, + ) mockSession.On("Close", mock.Anything).Return(nil) srv := &server{ @@ -129,8 +137,9 @@ func TestCreatePersonByGoogleId(t *testing.T) { c, _ := gin.CreateTestContext(w) body := `{"name": "test-person"}` - c.Request = httptest.NewRequest(http.MethodPost, "/person/google-id", nil) - c.Request.Body = io.NopCloser(strings.NewReader(body)) + c.Request = httptest.NewRequestWithContext( + t.Context(), http.MethodPost, "/person/google-id", io.NopCloser(strings.NewReader(body)), + ) srv.CreatePersonByGoogleId(c, "test-google-id") @@ -145,8 +154,9 @@ func TestCreatePersonByGoogleId(t *testing.T) { c, _ := gin.CreateTestContext(w) body := `{"invalid_json":` - c.Request = httptest.NewRequest(http.MethodPost, "/person/google-id", nil) - c.Request.Body = io.NopCloser(strings.NewReader(body)) + c.Request = httptest.NewRequestWithContext( + t.Context(), http.MethodPost, "/person/google-id", io.NopCloser(strings.NewReader(body)), + ) srv.CreatePersonByGoogleId(c, "test-google-id") diff --git a/apps/db-adapter/internal/api/person_recipes.go b/apps/db-adapter/internal/api/person_recipes.go index 94dd6fb..b556610 100644 --- a/apps/db-adapter/internal/api/person_recipes.go +++ b/apps/db-adapter/internal/api/person_recipes.go @@ -7,6 +7,8 @@ import ( "github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/pkg/api" ) -func (srv *server) GetRecipesByPersonId(c *gin.Context, id int, params api.GetRecipesByPersonIdParams) { +func (srv *server) GetRecipesByPersonId( //nolint:revive // not implemented + c *gin.Context, id int, params api.GetRecipesByPersonIdParams, //nolint:revive // not implemented +) { c.JSON(http.StatusServiceUnavailable, gin.H{"msg": "not implemented"}) } diff --git a/apps/db-adapter/internal/api/person_test.go b/apps/db-adapter/internal/api/person_test.go new file mode 100644 index 0000000..e5fdc9f --- /dev/null +++ b/apps/db-adapter/internal/api/person_test.go @@ -0,0 +1,202 @@ +package api + +import ( + "errors" + "fmt" + "io" + "net/http" + "net/http/httptest" + "strings" + "testing" + "time" + + "github.com/gin-gonic/gin" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/internal/memgraph" + memgraphMock "github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/internal/memgraph/mock" + "github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/pkg/api" +) + +func TestCreatePerson(t *testing.T) { + gin.SetMode(gin.TestMode) + + t.Run("Successful case", func(t *testing.T) { + mockSession := new(memgraphMock.SessionWithContext) + mockResult := new(memgraphMock.Result) + mockResult.On("Single", mock.Anything).Return(map[string]any{"id": 1}, nil) + mockDriver := new(memgraphMock.DriverWithContext) + mockDriver.On("NewSession", mock.Anything, mock.Anything).Return(mockSession) + mockSession.On("BeginTransaction", mock.Anything).Return(mockSession, nil) + mockSession.On("Run", mock.Anything, memgraph.CreatePersonCypherQuery, mock.Anything).Return(mockResult, nil) + mockSession.On("Run", mock.Anything, memgraph.CreateAdminRelationshipCypherQuery, mock.Anything).Return(nil, nil) + mockSession.On("Commit", mock.Anything).Return(nil) + mockSession.On("Close", mock.Anything).Return(nil) + + srv := &server{ + db: mockDriver, + dbOpTimeout: 5 * time.Second, + } + + body := `{"first_name": "test-person"}` + + w := httptest.NewRecorder() + c, _ := gin.CreateTestContext(w) + + c.Request = httptest.NewRequestWithContext( + t.Context(), http.MethodPost, "/person", io.NopCloser(strings.NewReader(body)), + ) + params := api.CreatePersonParams{XUserID: 1, XUserName: "test"} + + srv.CreatePerson(c, params) + + assert.Equal(t, http.StatusOK, w.Code) + assert.Contains(t, w.Body.String(), "id") + }) + + t.Run("Bad request case", func(t *testing.T) { + srv := &server{} + + w := httptest.NewRecorder() + c, _ := gin.CreateTestContext(w) + + c.Request = httptest.NewRequestWithContext(t.Context(), http.MethodPost, "/person", http.NoBody) + + srv.CreatePerson(c, api.CreatePersonParams{}) + + assert.Equal(t, http.StatusBadRequest, w.Code) + assert.Contains(t, w.Body.String(), "msg") + }) + + t.Run("Internal server error case during transaction", func(t *testing.T) { + mockSession := new(memgraphMock.SessionWithContext) + mockDriver := new(memgraphMock.DriverWithContext) + mockDriver.On("NewSession", mock.Anything, mock.Anything).Return(mockSession) + mockSession.On("BeginTransaction", mock.Anything).Return(nil, errors.New("transaction error")) + mockSession.On("Close", mock.Anything).Return(nil) + + srv := &server{ + db: mockDriver, + dbOpTimeout: 5 * time.Second, + } + + body := `{"first_name": "test-person"}` + + w := httptest.NewRecorder() + c, _ := gin.CreateTestContext(w) + + c.Request = httptest.NewRequestWithContext( + t.Context(), http.MethodPost, "/person", io.NopCloser(strings.NewReader(body)), + ) + params := api.CreatePersonParams{XUserID: 1} + + srv.CreatePerson(c, params) + + assert.Equal(t, http.StatusInternalServerError, w.Code) + assert.Contains(t, w.Body.String(), "transaction error") + }) +} + +func TestGetPersonById(t *testing.T) { + gin.SetMode(gin.TestMode) + + t.Run("Successful case", func(t *testing.T) { + mockSession := new(memgraphMock.SessionWithContext) + mockDriver := new(memgraphMock.DriverWithContext) + mockDriver.On("NewSession", mock.Anything, mock.Anything).Return(mockSession) + mockSession.On("ExecuteRead", mock.Anything, mock.Anything).Return(map[string]any{"id": 1}, nil) + mockSession.On("Close", mock.Anything).Return(nil) + + srv := &server{ + db: mockDriver, + dbOpTimeout: 5 * time.Second, + } + + w := httptest.NewRecorder() + c, _ := gin.CreateTestContext(w) + + c.Request = httptest.NewRequestWithContext(t.Context(), http.MethodGet, "/person/1", http.NoBody) + params := api.GetPersonByIdParams{XUserID: 1} + + srv.GetPersonById(c, 1, params) + + assert.Equal(t, http.StatusOK, w.Code) + assert.Contains(t, w.Body.String(), "id") + }) + + t.Run("Unauthorized case", func(t *testing.T) { + mockSession := new(memgraphMock.SessionWithContext) + mockDriver := new(memgraphMock.DriverWithContext) + mockDriver.On("NewSession", mock.Anything, mock.Anything).Return(mockSession) + mockSession.On("ExecuteRead", mock.Anything, mock.Anything).Return(nil, fmt.Errorf("unauthorized")) + mockSession.On("Close", mock.Anything).Return(nil) + + srv := &server{ + db: mockDriver, + dbOpTimeout: 5 * time.Second, + } + + w := httptest.NewRecorder() + c, _ := gin.CreateTestContext(w) + + c.Request = httptest.NewRequestWithContext(t.Context(), http.MethodGet, "/person/1", http.NoBody) + params := api.GetPersonByIdParams{XUserID: 2} + + srv.GetPersonById(c, 1, params) + + assert.Equal(t, http.StatusUnauthorized, w.Code) + assert.Contains(t, w.Body.String(), "unauthorized") + }) +} + +func TestSoftDeletePerson(t *testing.T) { + gin.SetMode(gin.TestMode) + + t.Run("Successful case", func(t *testing.T) { + mockSession := new(memgraphMock.SessionWithContext) + mockDriver := new(memgraphMock.DriverWithContext) + mockDriver.On("NewSession", mock.Anything, mock.Anything).Return(mockSession) + mockSession.On("ExecuteWrite", mock.Anything, mock.Anything).Return(nil, nil) + mockSession.On("Close", mock.Anything).Return(nil) + + srv := &server{ + db: mockDriver, + dbOpTimeout: 5 * time.Second, + } + + w := httptest.NewRecorder() + c, _ := gin.CreateTestContext(w) + + c.Request = httptest.NewRequestWithContext(t.Context(), http.MethodDelete, "/person/1", http.NoBody) + params := api.SoftDeletePersonParams{XUserID: 1} + + srv.SoftDeletePerson(c, 1, params) + + assert.Equal(t, http.StatusOK, w.Code) + assert.Contains(t, w.Body.String(), "deleted") + }) + + t.Run("Unauthorized case", func(t *testing.T) { + mockSession := new(memgraphMock.SessionWithContext) + mockDriver := new(memgraphMock.DriverWithContext) + mockDriver.On("NewSession", mock.Anything, mock.Anything).Return(mockSession) + mockSession.On("ExecuteWrite", mock.Anything, mock.Anything).Return(nil, fmt.Errorf("unauthorized")) + mockSession.On("Close", mock.Anything).Return(nil) + + srv := &server{ + db: mockDriver, + dbOpTimeout: 5 * time.Second, + } + + w := httptest.NewRecorder() + c, _ := gin.CreateTestContext(w) + + c.Request = httptest.NewRequestWithContext(t.Context(), http.MethodDelete, "/person/1", http.NoBody) + params := api.SoftDeletePersonParams{XUserID: 2} + + srv.SoftDeletePerson(c, 1, params) + + assert.Equal(t, http.StatusUnauthorized, w.Code) + assert.Contains(t, w.Body.String(), "unauthorized") + }) +} diff --git a/apps/db-adapter/internal/api/recipe_relationship.go b/apps/db-adapter/internal/api/recipe_relationship.go index 5399f69..5782bfb 100644 --- a/apps/db-adapter/internal/api/recipe_relationship.go +++ b/apps/db-adapter/internal/api/recipe_relationship.go @@ -7,10 +7,14 @@ import ( "github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/pkg/api" ) -func (srv *server) DeleteRecipeRelationship(c *gin.Context, recipeId int, params api.DeleteRecipeRelationshipParams) { +func (srv *server) DeleteRecipeRelationship( //nolint:revive // not implemented + c *gin.Context, recipeId int, params api.DeleteRecipeRelationshipParams, //nolint:revive // not implemented +) { c.JSON(http.StatusServiceUnavailable, gin.H{"msg": "not implemented"}) } -func (srv *server) CreateRecipeRelationship(c *gin.Context, recipeId int, params api.CreateRecipeRelationshipParams) { +func (srv *server) CreateRecipeRelationship( //nolint:revive // not implemented + c *gin.Context, recipeId int, params api.CreateRecipeRelationshipParams, //nolint:revive // not implemented +) { c.JSON(http.StatusServiceUnavailable, gin.H{"msg": "not implemented"}) } diff --git a/apps/db-adapter/internal/api/recipes.go b/apps/db-adapter/internal/api/recipes.go index 0481774..0c4faee 100644 --- a/apps/db-adapter/internal/api/recipes.go +++ b/apps/db-adapter/internal/api/recipes.go @@ -7,14 +7,14 @@ import ( "github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/pkg/api" ) -func (srv *server) SoftDeleteRecipe(c *gin.Context, id int, params api.SoftDeleteRecipeParams) { +func (srv *server) SoftDeleteRecipe(c *gin.Context, id int, params api.SoftDeleteRecipeParams) { //nolint:revive // not implemented c.JSON(http.StatusServiceUnavailable, gin.H{"msg": "not implemented"}) } -func (srv *server) UpdateRecipe(c *gin.Context, id int, params api.UpdateRecipeParams) { +func (srv *server) UpdateRecipe(c *gin.Context, id int, params api.UpdateRecipeParams) { //nolint:revive // not implemented c.JSON(http.StatusServiceUnavailable, gin.H{"msg": "not implemented"}) } -func (srv *server) HardDeleteRecipe(c *gin.Context, id int, params api.HardDeleteRecipeParams) { +func (srv *server) HardDeleteRecipe(c *gin.Context, id int, params api.HardDeleteRecipeParams) { //nolint:revive // not implemented c.JSON(http.StatusServiceUnavailable, gin.H{"msg": "not implemented"}) } diff --git a/apps/db-adapter/internal/api/relationship.go b/apps/db-adapter/internal/api/relationship.go index 99ce781..c1de9cf 100644 --- a/apps/db-adapter/internal/api/relationship.go +++ b/apps/db-adapter/internal/api/relationship.go @@ -41,13 +41,29 @@ func (srv *server) CreateRelationship(c *gin.Context, params api.CreateRelations var relationshipError error switch *relationship.Type { case api.CreateRelationshipJSONBodyTypeChild: - relationShipResultRaw, relationshipError = session.ExecuteWrite(qctx, memgraph.CreateChildParentRelationship(qctx, *relationship.Id1, *relationship.Id2, *relationship.Relationship)) + relationShipResultRaw, relationshipError = session.ExecuteWrite( + qctx, memgraph.CreateChildParentRelationship( + qctx, *relationship.Id1, *relationship.Id2, *relationship.Relationship, + ), + ) case api.CreateRelationshipJSONBodyTypeParent: - relationShipResultRaw, relationshipError = session.ExecuteWrite(qctx, memgraph.CreateChildParentRelationship(qctx, *relationship.Id1, *relationship.Id2, *relationship.Relationship)) + relationShipResultRaw, relationshipError = session.ExecuteWrite( + qctx, memgraph.CreateChildParentRelationship( + qctx, *relationship.Id1, *relationship.Id2, *relationship.Relationship, + ), + ) case api.CreateRelationshipJSONBodyTypeSibling: - relationShipResultRaw, relationshipError = session.ExecuteWrite(qctx, memgraph.CreateSiblingRelationship(qctx, *relationship.Id1, *relationship.Id2, *relationship.Relationship)) + relationShipResultRaw, relationshipError = session.ExecuteWrite( + qctx, memgraph.CreateSiblingRelationship( + qctx, *relationship.Id1, *relationship.Id2, *relationship.Relationship, + ), + ) case api.CreateRelationshipJSONBodyTypeSpouse: - relationShipResultRaw, relationshipError = session.ExecuteWrite(qctx, memgraph.CreateSpouseRelationship(qctx, *relationship.Id1, *relationship.Id2, *relationship.Relationship)) + relationShipResultRaw, relationshipError = session.ExecuteWrite( + qctx, memgraph.CreateSpouseRelationship( + qctx, *relationship.Id1, *relationship.Id2, *relationship.Relationship, + ), + ) default: c.JSON(http.StatusBadRequest, gin.H{"msg": "invalid relationship type"}) } @@ -94,7 +110,7 @@ func (srv *server) UpdateRelationship(c *gin.Context, id1, id2 int, params api.U c.JSON(http.StatusOK, res) } -func (srv *server) GetRelationship(c *gin.Context, id1 int, id2 int, params api.GetRelationshipParams) { +func (srv *server) GetRelationship(c *gin.Context, id1, id2 int, params api.GetRelationshipParams) { session := srv.db.NewSession(c.Request.Context(), neo4j.SessionConfig{}) defer closeSession(c.Request.Context(), srv.logger, session, srv.dbOpTimeout) @@ -122,7 +138,7 @@ func (srv *server) GetRelationship(c *gin.Context, id1 int, id2 int, params api. c.JSON(http.StatusOK, res) } -func (srv *server) DeleteRelationship(c *gin.Context, id1 int, id2 int, params api.DeleteRelationshipParams) { +func (srv *server) DeleteRelationship(c *gin.Context, id1, id2 int, params api.DeleteRelationshipParams) { session := srv.db.NewSession(c.Request.Context(), neo4j.SessionConfig{}) defer closeSession(c.Request.Context(), srv.logger, session, srv.dbOpTimeout) diff --git a/apps/db-adapter/internal/api/server.go b/apps/db-adapter/internal/api/server.go index f794911..8650812 100644 --- a/apps/db-adapter/internal/api/server.go +++ b/apps/db-adapter/internal/api/server.go @@ -1,6 +1,7 @@ package api import ( + "context" "time" "github.com/gin-gonic/gin" @@ -11,13 +12,15 @@ import ( ) type server struct { - db neo4j.DriverWithContext - dbOpTimeout time.Duration - health healthcheck.HealthCheck logger *zap.Logger + db neo4j.DriverWithContext + health healthcheck.HealthCheck + dbOpTimeout time.Duration } -func New(logger *zap.Logger, drv neo4j.DriverWithContext, healthcheck healthcheck.HealthCheck, databaseOperationTimeout time.Duration) api.ServerInterface { +func New( + logger *zap.Logger, drv neo4j.DriverWithContext, hc healthcheck.HealthCheck, databaseOperationTimeout time.Duration, +) api.ServerInterface { if logger == nil { panic("logger is required") } @@ -26,7 +29,7 @@ func New(logger *zap.Logger, drv neo4j.DriverWithContext, healthcheck healthchec panic("neo4j driver is required") } - if healthcheck == nil { + if hc == nil { panic("healthcheck is required") } @@ -34,9 +37,17 @@ func New(logger *zap.Logger, drv neo4j.DriverWithContext, healthcheck healthchec panic("database operation timeout is required") } - return &server{db: drv, health: healthcheck, logger: logger} + return &server{db: drv, health: hc, logger: logger} } func (srv *server) HealthCheck(c *gin.Context) { srv.health.HealthCheckHandler(c) } + +// Helper function to create a session with timeout +func (srv *server) createSessionWithTimeout(ctx context.Context) neo4j.SessionWithContext { + actx, acancel := context.WithTimeout(ctx, srv.dbOpTimeout) + defer acancel() + session := srv.db.NewSession(actx, neo4j.SessionConfig{}) + return session +} diff --git a/apps/db-adapter/internal/memgraph/admin.go b/apps/db-adapter/internal/memgraph/admin.go index a2d6720..981c7c0 100644 --- a/apps/db-adapter/internal/memgraph/admin.go +++ b/apps/db-adapter/internal/memgraph/admin.go @@ -7,7 +7,7 @@ import ( "github.com/neo4j/neo4j-go-driver/v5/neo4j" ) -func CreateAdminRelationship(ctx context.Context, userId int, adminId int) neo4j.ManagedTransactionWork { +func CreateAdminRelationship(ctx context.Context, userId, adminId int) neo4j.ManagedTransactionWork { return func(tx neo4j.ManagedTransaction) (any, error) { result, err := tx.Run(ctx, CreateAdminRelationshipCypherQuery, map[string]any{ "id1": adminId, @@ -26,7 +26,7 @@ func CreateAdminRelationship(ctx context.Context, userId int, adminId int) neo4j } } -func DeleteAdminRelationship(ctx context.Context, userId int, adminId int) neo4j.ManagedTransactionWork { +func DeleteAdminRelationship(ctx context.Context, userId, adminId int) neo4j.ManagedTransactionWork { return func(tx neo4j.ManagedTransaction) (any, error) { result, err := tx.Run(ctx, DeleteAdminRelationshipCypherQuery, map[string]any{ "id1": adminId, @@ -44,7 +44,7 @@ func DeleteAdminRelationship(ctx context.Context, userId int, adminId int) neo4j } } -func GetAdminRelationship(ctx context.Context, userId int, adminId int) neo4j.ManagedTransactionWork { +func GetAdminRelationship(ctx context.Context, userId, adminId int) neo4j.ManagedTransactionWork { return func(tx neo4j.ManagedTransaction) (any, error) { result, err := tx.Run(ctx, GetAdminRelationshipCypherQuery, map[string]any{ "id1": adminId, diff --git a/apps/db-adapter/internal/memgraph/admin_test.go b/apps/db-adapter/internal/memgraph/admin_test.go index 2aecae0..81f9851 100644 --- a/apps/db-adapter/internal/memgraph/admin_test.go +++ b/apps/db-adapter/internal/memgraph/admin_test.go @@ -6,16 +6,16 @@ import ( "testing" "github.com/neo4j/neo4j-go-driver/v5/neo4j" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/internal/memgraph/mock" ) func TestGetManagedProfiles(t *testing.T) { testCases := []struct { - name string mockTxSetup func() *mock.Transaction expectedResult map[string]any expectedError error + name string }{ { name: "Successful case", @@ -67,11 +67,11 @@ func TestGetManagedProfiles(t *testing.T) { result, err := work(mockTx) if tc.expectedError != nil { - assert.Error(t, err) - assert.Nil(t, result) + require.Error(t, err) + require.Nil(t, result) } else { - assert.NoError(t, err) - assert.Equal(t, tc.expectedResult, result) + require.NoError(t, err) + require.Equal(t, tc.expectedResult, result) } }) } diff --git a/apps/db-adapter/internal/memgraph/cypher_verify_string.go b/apps/db-adapter/internal/memgraph/cypher_verify_string.go index 3b64557..6469fb0 100644 --- a/apps/db-adapter/internal/memgraph/cypher_verify_string.go +++ b/apps/db-adapter/internal/memgraph/cypher_verify_string.go @@ -38,7 +38,7 @@ var cypherKeywords = []string{ "WHERE", } -var cypherOperators = []string{ +var cypherOperators = []string{ //nolint: unused // this could be used in the future "+", "-", "*", diff --git a/apps/db-adapter/internal/memgraph/family_tree.go b/apps/db-adapter/internal/memgraph/family_tree.go index 9516ec1..ea8b356 100644 --- a/apps/db-adapter/internal/memgraph/family_tree.go +++ b/apps/db-adapter/internal/memgraph/family_tree.go @@ -6,7 +6,7 @@ import ( "github.com/neo4j/neo4j-go-driver/v5/neo4j" ) -// returned map has "people" which is a slice of OptimizedPersonNode and relationships wich a slice of Relatioship type. +// returned map has "people" which is a slice of OptimizedPersonNode and relationships which a slice of Relatioship type. func GetFamilyTreeById(ctx context.Context, userId int) neo4j.ManagedTransactionWork { return func(tx neo4j.ManagedTransaction) (any, error) { result, err := tx.Run(ctx, GetBloodRelativesCypherQuery, map[string]any{ @@ -25,7 +25,7 @@ func GetFamilyTreeById(ctx context.Context, userId int) neo4j.ManagedTransaction } } -// returned map has "people" which is a slice of OptimizedPersonNode and relationships wich a slice of Relatioship type. +// returned map has "people" which is a slice of OptimizedPersonNode and relationships which a slice of Relatioship type. func GetFamilyTreeWithSpousesById(ctx context.Context, userId int) neo4j.ManagedTransactionWork { return func(tx neo4j.ManagedTransaction) (any, error) { result, err := tx.Run(ctx, GetFamilyTreeWithSpousesCypherQuery, map[string]any{ diff --git a/apps/db-adapter/internal/memgraph/family_tree_test.go b/apps/db-adapter/internal/memgraph/family_tree_test.go index 70c509b..fb2e919 100644 --- a/apps/db-adapter/internal/memgraph/family_tree_test.go +++ b/apps/db-adapter/internal/memgraph/family_tree_test.go @@ -6,16 +6,16 @@ import ( "testing" "github.com/neo4j/neo4j-go-driver/v5/neo4j" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/internal/memgraph/mock" ) func TestGetFamilyTreeById(t *testing.T) { testCases := []struct { - name string mockTxSetup func() *mock.Transaction expectedResult map[string]any expectedError error + name string }{ { name: "Successful case", @@ -67,11 +67,11 @@ func TestGetFamilyTreeById(t *testing.T) { result, err := work(mockTx) if tc.expectedError != nil { - assert.Error(t, err) - assert.Nil(t, result) + require.Error(t, err) + require.Nil(t, result) } else { - assert.NoError(t, err) - assert.Equal(t, tc.expectedResult, result) + require.NoError(t, err) + require.Equal(t, tc.expectedResult, result) } }) } @@ -79,10 +79,10 @@ func TestGetFamilyTreeById(t *testing.T) { func TestGetFamilyTreeWithSpousesById(t *testing.T) { testCases := []struct { - name string mockTxSetup func() *mock.Transaction expectedResult map[string]any expectedError error + name string }{ { name: "Successful case", @@ -134,11 +134,11 @@ func TestGetFamilyTreeWithSpousesById(t *testing.T) { result, err := work(mockTx) if tc.expectedError != nil { - assert.Error(t, err) - assert.Nil(t, result) + require.Error(t, err) + require.Nil(t, result) } else { - assert.NoError(t, err) - assert.Equal(t, tc.expectedResult, result) + require.NoError(t, err) + require.Equal(t, tc.expectedResult, result) } }) } diff --git a/apps/db-adapter/internal/memgraph/person.go b/apps/db-adapter/internal/memgraph/person.go index 1889ea5..03ddacf 100644 --- a/apps/db-adapter/internal/memgraph/person.go +++ b/apps/db-adapter/internal/memgraph/person.go @@ -8,10 +8,10 @@ import ( "github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/pkg/api" ) -func CreatePerson(ctx context.Context, Person *api.PersonProperties) neo4j.ManagedTransactionWork { +func CreatePerson(ctx context.Context, person *api.PersonProperties) neo4j.ManagedTransactionWork { return func(tx neo4j.ManagedTransaction) (any, error) { result, err := tx.Run(ctx, CreatePersonCypherQuery, map[string]any{ - "Person": *Person, + "Person": *person, }) if err != nil { return nil, err diff --git a/apps/db-adapter/internal/memgraph/person_google.go b/apps/db-adapter/internal/memgraph/person_google.go index 15941eb..80b52a8 100644 --- a/apps/db-adapter/internal/memgraph/person_google.go +++ b/apps/db-adapter/internal/memgraph/person_google.go @@ -25,11 +25,11 @@ func GetPersonByGoogleId(ctx context.Context, googleId string) neo4j.ManagedTran } } -func UpdatePersonByInviteCode(ctx context.Context, inviteCode string, Person *api.PersonProperties) neo4j.ManagedTransactionWork { +func UpdatePersonByInviteCode(ctx context.Context, inviteCode string, person *api.PersonProperties) neo4j.ManagedTransactionWork { return func(tx neo4j.ManagedTransaction) (any, error) { result, err := tx.Run(ctx, UpdatePersonByInviteCodeCypherQuery, map[string]any{ "invite_code": inviteCode, - "props": *Person, + "props": *person, }) if err != nil { return nil, err diff --git a/apps/db-adapter/internal/memgraph/person_google_test.go b/apps/db-adapter/internal/memgraph/person_google_test.go index e20b21f..7765a2a 100644 --- a/apps/db-adapter/internal/memgraph/person_google_test.go +++ b/apps/db-adapter/internal/memgraph/person_google_test.go @@ -6,20 +6,21 @@ import ( "testing" "github.com/neo4j/neo4j-go-driver/v5/neo4j" - "github.com/stretchr/testify/assert" + tmock "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" "github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/internal/memgraph/mock" "github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/pkg/api" ) func TestGetPersonByGoogleId(t *testing.T) { tests := []struct { - name string mockRunResult any mockRunError error - mockSingle *neo4j.Record mockSingleErr error - expectedErr bool expectedRes any + mockSingle *neo4j.Record + name string + expectedErr bool }{ { name: "Success", @@ -31,7 +32,7 @@ func TestGetPersonByGoogleId(t *testing.T) { }, mockSingleErr: nil, expectedErr: false, - expectedRes: "value", + expectedRes: map[string]any{"key": "value"}, }, { name: "RunError", @@ -57,10 +58,10 @@ func TestGetPersonByGoogleId(t *testing.T) { t.Run(tt.name, func(t *testing.T) { ctx := context.Background() mockTx := new(mock.Transaction) - mockResult := tt.mockRunResult.(*mock.Result) - mockTx.On("Run", ctx, GetPersonByGoogleIdCypherQuery).Return(tt.mockRunResult, tt.mockRunError) - if mockResult != nil { + mockTx.On("Run", ctx, GetPersonByGoogleIdCypherQuery, tmock.Anything).Return(tt.mockRunResult, tt.mockRunError) + if tt.mockRunResult != nil { + mockResult := tt.mockRunResult.(*mock.Result) mockResult.On("Single", ctx).Return(tt.mockSingle, tt.mockSingleErr) } @@ -68,17 +69,17 @@ func TestGetPersonByGoogleId(t *testing.T) { result, err := work(mockTx) if tt.expectedErr { - assert.Error(t, err) - assert.Nil(t, result) + require.Error(t, err) + require.Nil(t, result) } else { - assert.NoError(t, err) - assert.NotNil(t, result) - assert.Equal(t, tt.expectedRes, result) + require.NoError(t, err) + require.NotNil(t, result) + require.Equal(t, tt.expectedRes, result) } mockTx.AssertExpectations(t) - if mockResult != nil { - mockResult.AssertExpectations(t) + if tt.mockRunResult != nil { + tt.mockRunResult.(*mock.Result).AssertExpectations(t) } }) } @@ -86,8 +87,8 @@ func TestGetPersonByGoogleId(t *testing.T) { func TestUpdatePersonByGoogleID(t *testing.T) { tests := []struct { - name string mockRunError error + name string expectedErr bool }{ { @@ -114,11 +115,11 @@ func TestUpdatePersonByGoogleID(t *testing.T) { result, err := work(mockTx) if tt.expectedErr { - assert.Error(t, err) - assert.Nil(t, result) + require.Error(t, err) + require.Nil(t, result) } else { - assert.NoError(t, err) - assert.NotNil(t, result) + require.NoError(t, err) + require.NotNil(t, result) } mockTx.AssertExpectations(t) diff --git a/apps/db-adapter/internal/memgraph/person_test.go b/apps/db-adapter/internal/memgraph/person_test.go index 9749c6b..6068238 100644 --- a/apps/db-adapter/internal/memgraph/person_test.go +++ b/apps/db-adapter/internal/memgraph/person_test.go @@ -14,10 +14,10 @@ import ( func TestCreatePerson(t *testing.T) { testCases := []struct { - name string mockTxSetup func() *mock.Transaction expectedResult map[string]any expectedError error + name string }{ { name: "Successful case", @@ -75,11 +75,11 @@ func TestCreatePerson(t *testing.T) { result, err := work(mockTx) if tc.expectedError != nil { - assert.Error(t, err) - assert.Nil(t, result) + require.Error(t, err) + require.Nil(t, result) } else { - assert.NoError(t, err) - assert.Equal(t, tc.expectedResult, result) + require.NoError(t, err) + require.Equal(t, tc.expectedResult, result) } }) } @@ -87,10 +87,10 @@ func TestCreatePerson(t *testing.T) { func TestHardDeletePerson(t *testing.T) { testCases := []struct { - name string mockTxSetup func() *mock.Transaction - expectedResult any + expectedResult map[string]any expectedError error + name string }{ { name: "Successful case", @@ -139,7 +139,7 @@ func TestHardDeletePerson(t *testing.T) { if tc.expectedError != nil { require.Error(t, err) - assert.Nil(t, result) + require.Nil(t, result) } else { require.NoError(t, err) assert.Equal(t, tc.expectedResult, result) @@ -150,10 +150,10 @@ func TestHardDeletePerson(t *testing.T) { func TestUpdatePerson(t *testing.T) { testCases := []struct { - name string mockTxSetup func() *mock.Transaction expectedResult map[string]any expectedError error + name string }{ { name: "Successful case", @@ -215,11 +215,11 @@ func TestUpdatePerson(t *testing.T) { result, err := work(mockTx) if tc.expectedError != nil { - assert.Error(t, err) - assert.Nil(t, result) + require.Error(t, err) + require.Nil(t, result) } else { - assert.NoError(t, err) - assert.Equal(t, tc.expectedResult, result) + require.NoError(t, err) + require.Equal(t, tc.expectedResult, result) } }) } @@ -227,10 +227,10 @@ func TestUpdatePerson(t *testing.T) { func TestSoftDeletePerson(t *testing.T) { testCases := []struct { - name string mockTxSetup func() *mock.Transaction expectedResult map[string]any expectedError error + name string }{ { name: "Successful case", @@ -288,11 +288,11 @@ func TestSoftDeletePerson(t *testing.T) { result, err := work(mockTx) if tc.expectedError != nil { - assert.Error(t, err) - assert.Nil(t, result) + require.Error(t, err) + require.Nil(t, result) } else { - assert.NoError(t, err) - assert.Equal(t, tc.expectedResult, result) + require.NoError(t, err) + require.Equal(t, tc.expectedResult, result) } }) } diff --git a/apps/db-adapter/internal/memgraph/relationship.go b/apps/db-adapter/internal/memgraph/relationship.go index 45ec077..9716d24 100644 --- a/apps/db-adapter/internal/memgraph/relationship.go +++ b/apps/db-adapter/internal/memgraph/relationship.go @@ -40,7 +40,9 @@ func DeleteRelationship(ctx context.Context, id1, id2 int) neo4j.ManagedTransact } } -func UpdateRelationship(ctx context.Context, id1, id2 int, relationship api.FamilyRelationship) neo4j.ManagedTransactionWork { +func UpdateRelationship( + ctx context.Context, id1, id2 int, relationship api.FamilyRelationship, +) neo4j.ManagedTransactionWork { return func(tx neo4j.ManagedTransaction) (any, error) { result, err := tx.Run(ctx, UpdateRelationshipCypherQuery, map[string]any{ "id1": id1, @@ -60,7 +62,9 @@ func UpdateRelationship(ctx context.Context, id1, id2 int, relationship api.Fami } } -func CreateChildParentRelationship(ctx context.Context, childId, parentId int, relationship api.FamilyRelationship) neo4j.ManagedTransactionWork { +func CreateChildParentRelationship( + ctx context.Context, childId, parentId int, relationship api.FamilyRelationship, +) neo4j.ManagedTransactionWork { return func(tx neo4j.ManagedTransaction) (any, error) { result, err := tx.Run(ctx, CreateChildParentRelationshipCypherQuery, map[string]any{ "childId": childId, @@ -76,7 +80,9 @@ func CreateChildParentRelationship(ctx context.Context, childId, parentId int, r } } -func CreateSiblingRelationship(ctx context.Context, siblingId1, siblingId2 int, relationship api.FamilyRelationship) neo4j.ManagedTransactionWork { +func CreateSiblingRelationship( + ctx context.Context, siblingId1, siblingId2 int, relationship api.FamilyRelationship, +) neo4j.ManagedTransactionWork { return func(tx neo4j.ManagedTransaction) (any, error) { result, err := tx.Run(ctx, CreateSiblingRelationshipCypherQuery, map[string]any{ "id1": siblingId1, @@ -92,7 +98,9 @@ func CreateSiblingRelationship(ctx context.Context, siblingId1, siblingId2 int, } } -func CreateSpouseRelationship(ctx context.Context, spouseId1, spouseId2 int, relationship api.FamilyRelationship) neo4j.ManagedTransactionWork { +func CreateSpouseRelationship( + ctx context.Context, spouseId1, spouseId2 int, relationship api.FamilyRelationship, +) neo4j.ManagedTransactionWork { return func(tx neo4j.ManagedTransaction) (any, error) { result, err := tx.Run(ctx, CreateSpouseRelationshipCypherQuery, map[string]any{ "id1": spouseId1, diff --git a/apps/db-adapter/internal/memgraph/relationship_test.go b/apps/db-adapter/internal/memgraph/relationship_test.go index ffc4159..f4320a5 100644 --- a/apps/db-adapter/internal/memgraph/relationship_test.go +++ b/apps/db-adapter/internal/memgraph/relationship_test.go @@ -6,17 +6,17 @@ import ( "testing" "github.com/neo4j/neo4j-go-driver/v5/neo4j" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/internal/memgraph/mock" "github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/pkg/api" ) func TestGetRelationship(t *testing.T) { testCases := []struct { - name string mockTxSetup func() *mock.Transaction expectedResult map[string]any expectedError error + name string }{ { name: "Successful case", @@ -68,11 +68,11 @@ func TestGetRelationship(t *testing.T) { result, err := work(mockTx) if tc.expectedError != nil { - assert.Error(t, err) - assert.Nil(t, result) + require.Error(t, err) + require.Nil(t, result) } else { - assert.NoError(t, err) - assert.Equal(t, tc.expectedResult, result) + require.NoError(t, err) + require.Equal(t, tc.expectedResult, result) } }) } @@ -80,10 +80,10 @@ func TestGetRelationship(t *testing.T) { func TestDeleteRelationship(t *testing.T) { testCases := []struct { - name string mockTxSetup func() *mock.Transaction - expectedResult bool expectedError error + name string + expectedResult bool }{ { name: "Successful case", @@ -119,11 +119,11 @@ func TestDeleteRelationship(t *testing.T) { result, err := work(mockTx) if tc.expectedError != nil { - assert.Error(t, err) - assert.False(t, result.(bool)) + require.Error(t, err) + require.Nil(t, result) } else { - assert.NoError(t, err) - assert.Equal(t, tc.expectedResult, result) + require.NoError(t, err) + require.Equal(t, tc.expectedResult, result) } }) } @@ -131,10 +131,10 @@ func TestDeleteRelationship(t *testing.T) { func TestUpdateRelationship(t *testing.T) { testCases := []struct { - name string mockTxSetup func() *mock.Transaction expectedResult map[string]any expectedError error + name string }{ { name: "Successful case", @@ -183,11 +183,11 @@ func TestUpdateRelationship(t *testing.T) { result, err := work(mockTx) if tc.expectedError != nil { - assert.Error(t, err) - assert.Nil(t, result) + require.Error(t, err) + require.Nil(t, result) } else { - assert.NoError(t, err) - assert.Equal(t, tc.expectedResult, result) + require.NoError(t, err) + require.Equal(t, tc.expectedResult, result) } }) } diff --git a/apps/db-adapter/main.go b/apps/db-adapter/main.go index 6b7d376..907bc15 100644 --- a/apps/db-adapter/main.go +++ b/apps/db-adapter/main.go @@ -41,7 +41,7 @@ var ( dbOpTimeout time.Duration ) -func init() { +func init() { //nolint:gochecknoinits // this is a main package, init is ok viper.AutomaticEnv() viper.SetDefault("HTTP_PORT", defaultHTTPPort) diff --git a/apps/db-adapter/main_test.go b/apps/db-adapter/main_test.go index 04d9910..f3e4fa1 100644 --- a/apps/db-adapter/main_test.go +++ b/apps/db-adapter/main_test.go @@ -3,5 +3,5 @@ package main import "testing" func TestIntegration(t *testing.T) { - + t.Skip("Integration tests are not implemented") } diff --git a/apps/db-adapter/pkg/gin/healthcheck/health_check_test.go b/apps/db-adapter/pkg/gin/healthcheck/health_check_test.go index 3eea4fc..7432209 100644 --- a/apps/db-adapter/pkg/gin/healthcheck/health_check_test.go +++ b/apps/db-adapter/pkg/gin/healthcheck/health_check_test.go @@ -120,7 +120,7 @@ func TestHealthCheck_HealthCheckHandler(t *testing.T) { hc.SetStatus(tt.args.status) w := httptest.NewRecorder() - req, _ := http.NewRequest("GET", "/health", nil) + req, _ := http.NewRequestWithContext(t.Context(), "GET", "/health", http.NoBody) r.ServeHTTP(w, req) if got := w.Code; got != tt.statusCode {