mirror of
https://github.com/vcscsvcscs/GenerationsHeritage.git
synced 2025-08-14 14:59:07 +02:00
implement integration tests for person operations
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
|
||||
"github.com/neo4j/neo4j-go-driver/v5/neo4j/dbtype"
|
||||
"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"
|
||||
@@ -38,8 +39,9 @@ func (srv *server) CreatePerson(c *gin.Context, params api.CreatePersonParams) {
|
||||
|
||||
qctx, qCancel := context.WithTimeout(c.Request.Context(), srv.dbOpTimeout)
|
||||
defer qCancel()
|
||||
convertedPerson := memgraph.StructToMap(person)
|
||||
res, err := trs.Run(qctx, memgraph.CreatePersonCypherQuery, map[string]any{
|
||||
"Person": *person,
|
||||
"Person": convertedPerson,
|
||||
})
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()})
|
||||
@@ -54,17 +56,19 @@ func (srv *server) CreatePerson(c *gin.Context, params api.CreatePersonParams) {
|
||||
return
|
||||
}
|
||||
|
||||
personId, ok := singleRes.Get("id")
|
||||
createdPerson, ok := singleRes.Get("person")
|
||||
if !ok {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"msg": "Person ID not found in response"})
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"msg": "Person not found in db response"})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
personId := createdPerson.(dbtype.Node).Id //nolint:staticcheck // this is a difference in neo4j and memgraph
|
||||
|
||||
actx, acancel := context.WithTimeout(c.Request.Context(), srv.dbOpTimeout)
|
||||
defer acancel()
|
||||
_, aErr := trs.Run(actx, memgraph.CreateAdminRelationshipCypherQuery, map[string]any{
|
||||
"id2": personId.(int),
|
||||
"id2": personId,
|
||||
"id1": params.XUserID,
|
||||
})
|
||||
if aErr != nil {
|
||||
@@ -80,10 +84,10 @@ func (srv *server) CreatePerson(c *gin.Context, params api.CreatePersonParams) {
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, singleRes.AsMap())
|
||||
c.JSON(http.StatusOK, createdPerson)
|
||||
}
|
||||
|
||||
func (srv *server) GetPersonById(c *gin.Context, id int, params api.GetPersonByIdParams) { //nolint:dupl // not worth abstracting more
|
||||
func (srv *server) GetPersonById(c *gin.Context, id int, params api.GetPersonByIdParams) {
|
||||
session := srv.createSessionWithTimeout(c.Request.Context())
|
||||
defer closeSession(c.Request.Context(), srv.logger, session, srv.dbOpTimeout)
|
||||
|
||||
@@ -107,7 +111,7 @@ 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) {
|
||||
func (srv *server) SoftDeletePerson(c *gin.Context, id int, params api.SoftDeletePersonParams) { //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)
|
||||
|
||||
@@ -128,7 +132,7 @@ func (srv *server) SoftDeletePerson(c *gin.Context, id int, params api.SoftDelet
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, map[string]string{"description": "Person soft deleted"})
|
||||
c.JSON(http.StatusOK, gin.H{"description": "Person soft deleted"})
|
||||
}
|
||||
|
||||
func (srv *server) UpdatePerson(c *gin.Context, id int, params api.UpdatePersonParams) {
|
||||
@@ -176,12 +180,14 @@ func (srv *server) HardDeletePerson(c *gin.Context, id int, params api.HardDelet
|
||||
|
||||
qctx, qCancel := context.WithTimeout(c.Request.Context(), srv.dbOpTimeout)
|
||||
defer qCancel()
|
||||
res, err := session.ExecuteWrite(qctx, memgraph.HardDeletePerson(qctx, id))
|
||||
_, err := session.ExecuteWrite(qctx, memgraph.HardDeletePerson(qctx, id))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, res)
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"description": "Person hard deleted",
|
||||
})
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
|
||||
"github.com/neo4j/neo4j-go-driver/v5/neo4j/dbtype"
|
||||
"github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/internal/memgraph"
|
||||
"github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/pkg/api"
|
||||
"go.uber.org/zap"
|
||||
@@ -36,8 +37,9 @@ func (srv *server) CreatePersonAndRelationship(c *gin.Context, id int, params ap
|
||||
|
||||
qctx, qCancel := context.WithTimeout(context.Background(), srv.dbOpTimeout)
|
||||
defer qCancel()
|
||||
convertedPerson := memgraph.StructToMap(requestBody.Person)
|
||||
res, err := trs.Run(qctx, memgraph.CreatePersonCypherQuery, map[string]any{
|
||||
"Person": requestBody.Person,
|
||||
"Person": convertedPerson,
|
||||
})
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()})
|
||||
@@ -51,17 +53,19 @@ func (srv *server) CreatePersonAndRelationship(c *gin.Context, id int, params ap
|
||||
|
||||
return
|
||||
}
|
||||
personID, ok := singleRes.Get("id")
|
||||
createdPerson, ok := singleRes.Get("person")
|
||||
if !ok {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"msg": "Person ID not found in response"})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
personID := createdPerson.(dbtype.Node).Id //nolint:staticcheck // this is a difference in neo4j and memgraph
|
||||
|
||||
actx, acancel := context.WithTimeout(c.Request.Context(), srv.dbOpTimeout)
|
||||
defer acancel()
|
||||
_, aErr := trs.Run(actx, memgraph.CreateAdminRelationshipCypherQuery, map[string]any{
|
||||
"id2": personID.(int),
|
||||
"id2": personID,
|
||||
"id1": params.XUserID,
|
||||
})
|
||||
if aErr != nil {
|
||||
@@ -73,36 +77,38 @@ func (srv *server) CreatePersonAndRelationship(c *gin.Context, id int, params ap
|
||||
relCtx, relCCancel := context.WithTimeout(c.Request.Context(), srv.dbOpTimeout)
|
||||
defer relCCancel()
|
||||
|
||||
convertedRelationship := memgraph.StructToMap(requestBody.Relationship)
|
||||
|
||||
var relationShipResultRaw any
|
||||
var relationshipError error
|
||||
switch *requestBody.Type {
|
||||
case api.CreatePersonAndRelationshipJSONBodyTypeChild:
|
||||
relationShipResultRaw, relationshipError = trs.Run(relCtx, memgraph.CreateChildParentRelationshipCypherQuery, map[string]any{
|
||||
"childId": personID.(int),
|
||||
"childId": personID,
|
||||
"parentId": id,
|
||||
"childRelationship": requestBody.Relationship,
|
||||
"parentRelationship": requestBody.Relationship,
|
||||
"childRelationship": convertedRelationship,
|
||||
"parentRelationship": convertedRelationship,
|
||||
})
|
||||
case api.CreatePersonAndRelationshipJSONBodyTypeParent:
|
||||
relationShipResultRaw, relationshipError = trs.Run(relCtx, memgraph.CreateChildParentRelationshipCypherQuery, map[string]any{
|
||||
"childId": id,
|
||||
"parentId": personID.(int),
|
||||
"childRelationship": requestBody.Relationship,
|
||||
"parentRelationship": requestBody.Relationship,
|
||||
"parentId": personID,
|
||||
"childRelationship": convertedRelationship,
|
||||
"parentRelationship": convertedRelationship,
|
||||
})
|
||||
case api.CreatePersonAndRelationshipJSONBodyTypeSibling:
|
||||
relationShipResultRaw, relationshipError = trs.Run(relCtx, memgraph.CreateSiblingRelationshipCypherQuery, map[string]any{
|
||||
"id1": id,
|
||||
"id2": personID.(int),
|
||||
"Relationship1": requestBody.Relationship,
|
||||
"Relationship2": requestBody.Relationship,
|
||||
"id2": personID,
|
||||
"Relationship1": convertedRelationship,
|
||||
"Relationship2": convertedRelationship,
|
||||
})
|
||||
case api.CreatePersonAndRelationshipJSONBodyTypeSpouse:
|
||||
relationShipResultRaw, relationshipError = trs.Run(relCtx, memgraph.CreateSpouseRelationshipCypherQuery, map[string]any{
|
||||
"id1": personID.(int),
|
||||
"id1": personID,
|
||||
"id2": id,
|
||||
"Relationship1": requestBody.Relationship,
|
||||
"Relationship2": requestBody.Relationship,
|
||||
"Relationship1": convertedRelationship,
|
||||
"Relationship2": convertedRelationship,
|
||||
})
|
||||
default:
|
||||
c.JSON(http.StatusBadRequest, gin.H{"msg": "invalid relationship type"})
|
||||
|
@@ -41,7 +41,12 @@ func GetPersonById(ctx context.Context, id int) neo4j.ManagedTransactionWork {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return record.AsMap(), nil
|
||||
person, ok := record.Get("person")
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("person not found")
|
||||
}
|
||||
|
||||
return person, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +66,12 @@ func UpdatePerson(ctx context.Context, id int, person *api.PersonProperties) neo
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return record.AsMap(), nil
|
||||
person, ok := record.Get("person")
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("person not found")
|
||||
}
|
||||
|
||||
return person, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,4 +1,5 @@
|
||||
MATCH (n:Person {id: $id})
|
||||
MATCH (n:Person)
|
||||
WHERE id(n)=$id
|
||||
SET n:DeletedPerson
|
||||
REMOVE n:Person
|
||||
RETURN labels(n) AS labels, n AS person
|
@@ -71,6 +71,8 @@ func StructToMap(input any) map[string]any {
|
||||
switch val.Kind() {
|
||||
case reflect.Struct:
|
||||
result[jsonKey] = StructToMap(val.Interface())
|
||||
case reflect.Slice, reflect.Array:
|
||||
result[jsonKey] = processSlice(val)
|
||||
default:
|
||||
result[jsonKey] = val.Interface()
|
||||
}
|
||||
@@ -104,3 +106,19 @@ func isPreservedType(v any) bool {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func processSlice(val reflect.Value) []any {
|
||||
slice := make([]any, val.Len())
|
||||
for i := range val.Len() {
|
||||
item := val.Index(i).Interface()
|
||||
if isPreservedType(item) {
|
||||
slice[i] = item
|
||||
} else if reflect.ValueOf(item).Kind() == reflect.Struct {
|
||||
slice[i] = StructToMap(item)
|
||||
} else {
|
||||
slice[i] = item
|
||||
}
|
||||
}
|
||||
|
||||
return slice
|
||||
}
|
||||
|
Reference in New Issue
Block a user