implement leftover transaction tests

This commit is contained in:
2025-04-13 20:18:21 +02:00
parent b97d51a19c
commit 29f8f539c8
5 changed files with 548 additions and 10 deletions

View File

@@ -2,8 +2,11 @@ package auth
import (
"context"
"fmt"
"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 CouldSeePersonsProfile(ctx context.Context, session neo4j.SessionWithContext, userId, XUserID int) error {
@@ -11,4 +14,27 @@ func CouldSeePersonsProfile(ctx context.Context, session neo4j.SessionWithContex
return nil
}
res, err := session.ExecuteRead(ctx, memgraph.GetFamilyTreeById(ctx, XUserID))
if err != nil {
return err
}
resMap, ok := res.(map[string]any)
if !ok {
return fmt.Errorf("could not convert result to map[string]any")
}
people, ok := resMap["people"].([]api.OptimizedPersonNode)
if !ok {
return fmt.Errorf("could not convert people to []api.PersonProperties")
}
for _, person := range people {
if *person.Id == userId {
return nil
}
}
return fmt.Errorf("user %d does not have permission to see user %d", XUserID, userId)
}

View File

@@ -84,7 +84,7 @@ func TestGetPersonByGoogleId(t *testing.T) {
}
}
func TestUpdatePerson(t *testing.T) {
func TestUpdatePersonByGoogleID(t *testing.T) {
tests := []struct {
name string
mockRunError error

View File

@@ -0,0 +1,298 @@
package memgraph
import (
"context"
"errors"
"testing"
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
"github.com/stretchr/testify/assert"
"github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/internal/memgraph/mock"
"github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/pkg/api"
)
func TestCreatePerson(t *testing.T) {
testCases := []struct {
name string
mockTxSetup func() *mock.Transaction
expectedResult map[string]any
expectedError error
}{
{
name: "Successful case",
mockTxSetup: func() *mock.Transaction {
mockTx := new(mock.Transaction)
mockResult := new(mock.Result)
mockRecord := &neo4j.Record{
Values: []any{"value"},
Keys: []string{"key"},
}
mockResult.On("Single", context.Background()).Return(mockRecord, nil)
mockTx.On("Run", context.Background(), CreatePersonCypherQuery, map[string]any{
"Person": api.PersonProperties{},
}).Return(mockResult, nil)
return mockTx
},
expectedResult: map[string]any{"key": "value"},
expectedError: nil,
},
{
name: "Error during Run",
mockTxSetup: func() *mock.Transaction {
mockTx := new(mock.Transaction)
mockTx.On("Run", context.Background(), CreatePersonCypherQuery, map[string]any{
"Person": api.PersonProperties{},
}).Return(nil, errors.New("run error"))
return mockTx
},
expectedResult: nil,
expectedError: errors.New("run error"),
},
{
name: "Error during Single",
mockTxSetup: func() *mock.Transaction {
mockTx := new(mock.Transaction)
mockResult := new(mock.Result)
mockResult.On("Single", context.Background()).Return(nil, errors.New("single error"))
mockTx.On("Run", context.Background(), CreatePersonCypherQuery, map[string]any{
"Person": api.PersonProperties{},
}).Return(mockResult, nil)
return mockTx
},
expectedResult: nil,
expectedError: errors.New("single error"),
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
ctx := context.Background()
person := &api.PersonProperties{}
mockTx := tc.mockTxSetup()
work := CreatePerson(ctx, person)
result, err := work(mockTx)
if tc.expectedError != nil {
assert.Error(t, err)
assert.Nil(t, result)
} else {
assert.NoError(t, err)
assert.Equal(t, tc.expectedResult, result)
}
})
}
}
func TestHardDeletePerson(t *testing.T) {
testCases := []struct {
name string
mockTxSetup func() *mock.Transaction
expectedResult any
expectedError error
}{
{
name: "Successful case",
mockTxSetup: func() *mock.Transaction {
mockTx := new(mock.Transaction)
mockResult := new(mock.Result)
mockResult.On("Peek", context.Background()).Return(false, nil)
mockTx.On("Run", context.Background(), HardDeletePersonCypherQuery, map[string]any{"id": 123}).Return(mockResult, nil)
return mockTx
},
expectedResult: nil,
expectedError: nil,
},
{
name: "Error during Run",
mockTxSetup: func() *mock.Transaction {
mockTx := new(mock.Transaction)
mockTx.On("Run", context.Background(), HardDeletePersonCypherQuery, map[string]any{"id": 123}).Return(nil, errors.New("run error"))
return mockTx
},
expectedResult: nil,
expectedError: errors.New("run error"),
},
{
name: "Unexpected record returned",
mockTxSetup: func() *mock.Transaction {
mockTx := new(mock.Transaction)
mockResult := new(mock.Result)
mockResult.On("Peek", context.Background()).Return(true, nil)
mockTx.On("Run", context.Background(), HardDeletePersonCypherQuery, map[string]any{"id": 123}).Return(mockResult, nil)
return mockTx
},
expectedResult: nil,
expectedError: errors.New("record was returned when it wasn't supposed to happen"),
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
ctx := context.Background()
id := 123
mockTx := tc.mockTxSetup()
work := HardDeletePerson(ctx, id)
result, err := work(mockTx)
if tc.expectedError != nil {
assert.Error(t, err)
assert.Nil(t, result)
} else {
assert.NoError(t, err)
assert.Equal(t, tc.expectedResult, result)
}
})
}
}
func TestUpdatePerson(t *testing.T) {
testCases := []struct {
name string
mockTxSetup func() *mock.Transaction
expectedResult map[string]any
expectedError error
}{
{
name: "Successful case",
mockTxSetup: func() *mock.Transaction {
mockTx := new(mock.Transaction)
mockResult := new(mock.Result)
mockRecord := &neo4j.Record{
Values: []any{"updatedValue"},
Keys: []string{"updatedKey"},
}
mockResult.On("Single", context.Background()).Return(mockRecord, nil)
mockTx.On("Run", context.Background(), UpdatePersonCypherQuery, map[string]any{
"id": 123,
"props": api.PersonProperties{},
}).Return(mockResult, nil)
return mockTx
},
expectedResult: map[string]any{"updatedKey": "updatedValue"},
expectedError: nil,
},
{
name: "Error during Run",
mockTxSetup: func() *mock.Transaction {
mockTx := new(mock.Transaction)
mockTx.On("Run", context.Background(), UpdatePersonCypherQuery, map[string]any{
"id": 123,
"props": api.PersonProperties{},
}).Return(nil, errors.New("run error"))
return mockTx
},
expectedResult: nil,
expectedError: errors.New("run error"),
},
{
name: "Error during Single",
mockTxSetup: func() *mock.Transaction {
mockTx := new(mock.Transaction)
mockResult := new(mock.Result)
mockResult.On("Single", context.Background()).Return(nil, errors.New("single error"))
mockTx.On("Run", context.Background(), UpdatePersonCypherQuery, map[string]any{
"id": 123,
"props": api.PersonProperties{},
}).Return(mockResult, nil)
return mockTx
},
expectedResult: nil,
expectedError: errors.New("single error"),
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
ctx := context.Background()
id := 123
person := &api.PersonProperties{}
mockTx := tc.mockTxSetup()
work := UpdatePerson(ctx, id, person)
result, err := work(mockTx)
if tc.expectedError != nil {
assert.Error(t, err)
assert.Nil(t, result)
} else {
assert.NoError(t, err)
assert.Equal(t, tc.expectedResult, result)
}
})
}
}
func TestSoftDeletePerson(t *testing.T) {
testCases := []struct {
name string
mockTxSetup func() *mock.Transaction
expectedResult map[string]any
expectedError error
}{
{
name: "Successful case",
mockTxSetup: func() *mock.Transaction {
mockTx := new(mock.Transaction)
mockResult := new(mock.Result)
mockRecord := &neo4j.Record{
Values: []any{"deletedValue"},
Keys: []string{"deletedKey"},
}
mockResult.On("Single", context.Background()).Return(mockRecord, nil)
mockTx.On("Run", context.Background(), SoftDeletePersonCypherQuery, map[string]any{
"id": 123,
}).Return(mockResult, nil)
return mockTx
},
expectedResult: map[string]any{"deletedKey": "deletedValue"},
expectedError: nil,
},
{
name: "Error during Run",
mockTxSetup: func() *mock.Transaction {
mockTx := new(mock.Transaction)
mockTx.On("Run", context.Background(), SoftDeletePersonCypherQuery, map[string]any{
"id": 123,
}).Return(nil, errors.New("run error"))
return mockTx
},
expectedResult: nil,
expectedError: errors.New("run error"),
},
{
name: "Error during Single",
mockTxSetup: func() *mock.Transaction {
mockTx := new(mock.Transaction)
mockResult := new(mock.Result)
mockResult.On("Single", context.Background()).Return(nil, errors.New("single error"))
mockTx.On("Run", context.Background(), SoftDeletePersonCypherQuery, map[string]any{
"id": 123,
}).Return(mockResult, nil)
return mockTx
},
expectedResult: nil,
expectedError: errors.New("single error"),
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
ctx := context.Background()
id := 123
mockTx := tc.mockTxSetup()
work := SoftDeletePerson(ctx, id)
result, err := work(mockTx)
if tc.expectedError != nil {
assert.Error(t, err)
assert.Nil(t, result)
} else {
assert.NoError(t, err)
assert.Equal(t, tc.expectedResult, result)
}
})
}
}

View File

@@ -40,13 +40,33 @@ func DeleteRelationship(ctx context.Context, id1, id2 int) neo4j.ManagedTransact
}
}
func CreateChildParentRelationship(ctx context.Context, childId, parentId int) 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,
"id2": id2,
"relationship": relationship,
})
if err != nil {
return nil, err
}
record, err := result.Single(ctx)
if err != nil {
return nil, err
}
return record.AsMap(), nil
}
}
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,
"parentId": parentId,
"childRelationship": api.FamilyRelationship{},
"parentRelationship": api.FamilyRelationship{},
"childRelationship": relationship,
"parentRelationship": relationship,
})
if err != nil {
return nil, err
@@ -56,13 +76,13 @@ func CreateChildParentRelationship(ctx context.Context, childId, parentId int) n
}
}
func CreateSiblingRelationship(ctx context.Context, siblingId1, siblingId2 int) 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,
"id2": siblingId2,
"Relationship1": api.FamilyRelationship{},
"Relationship2": api.FamilyRelationship{},
"Relationship1": relationship,
"Relationship2": relationship,
})
if err != nil {
return nil, err
@@ -72,13 +92,13 @@ func CreateSiblingRelationship(ctx context.Context, siblingId1, siblingId2 int)
}
}
func CreateSpouseRelationship(ctx context.Context, spouseId1, spouseId2 int) 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,
"id2": spouseId2,
"Relationship1": api.FamilyRelationship{},
"Relationship2": api.FamilyRelationship{},
"Relationship1": relationship,
"Relationship2": relationship,
})
if err != nil {
return nil, err

View File

@@ -0,0 +1,194 @@
package memgraph
import (
"context"
"errors"
"testing"
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
"github.com/stretchr/testify/assert"
"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: "Successful case",
mockTxSetup: func() *mock.Transaction {
mockTx := new(mock.Transaction)
mockResult := new(mock.Result)
mockRecord := &neo4j.Record{
Values: []any{"value"},
Keys: []string{"key"},
}
mockResult.On("Single", context.Background()).Return(mockRecord, nil)
mockTx.On("Run", context.Background(), GetRelationshipCypherQuery, map[string]any{"id1": 1, "id2": 2}).Return(mockResult, nil)
return mockTx
},
expectedResult: map[string]any{"key": "value"},
expectedError: nil,
},
{
name: "Error during Run",
mockTxSetup: func() *mock.Transaction {
mockTx := new(mock.Transaction)
mockTx.On("Run", context.Background(), GetRelationshipCypherQuery, map[string]any{"id1": 1, "id2": 2}).Return(nil, errors.New("run error"))
return mockTx
},
expectedResult: nil,
expectedError: errors.New("run error"),
},
{
name: "Error during Single",
mockTxSetup: func() *mock.Transaction {
mockTx := new(mock.Transaction)
mockResult := new(mock.Result)
mockResult.On("Single", context.Background()).Return(nil, errors.New("single error"))
mockTx.On("Run", context.Background(), GetRelationshipCypherQuery, map[string]any{"id1": 1, "id2": 2}).Return(mockResult, nil)
return mockTx
},
expectedResult: nil,
expectedError: errors.New("single error"),
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
ctx := context.Background()
id1, id2 := 1, 2
mockTx := tc.mockTxSetup()
work := GetRelationship(ctx, id1, id2)
result, err := work(mockTx)
if tc.expectedError != nil {
assert.Error(t, err)
assert.Nil(t, result)
} else {
assert.NoError(t, err)
assert.Equal(t, tc.expectedResult, result)
}
})
}
}
func TestDeleteRelationship(t *testing.T) {
testCases := []struct {
name string
mockTxSetup func() *mock.Transaction
expectedResult bool
expectedError error
}{
{
name: "Successful case",
mockTxSetup: func() *mock.Transaction {
mockTx := new(mock.Transaction)
mockResult := new(mock.Result)
mockResult.On("Peek", context.Background()).Return(false, nil)
mockTx.On("Run", context.Background(), DeleteRelationshipCypherQuery, map[string]any{"id1": 1, "id2": 2}).Return(mockResult, nil)
return mockTx
},
expectedResult: true,
expectedError: nil,
},
{
name: "Error during Run",
mockTxSetup: func() *mock.Transaction {
mockTx := new(mock.Transaction)
mockTx.On("Run", context.Background(), DeleteRelationshipCypherQuery, map[string]any{"id1": 1, "id2": 2}).Return(nil, errors.New("run error"))
return mockTx
},
expectedResult: false,
expectedError: errors.New("run error"),
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
ctx := context.Background()
id1, id2 := 1, 2
mockTx := tc.mockTxSetup()
work := DeleteRelationship(ctx, id1, id2)
result, err := work(mockTx)
if tc.expectedError != nil {
assert.Error(t, err)
assert.False(t, result.(bool))
} else {
assert.NoError(t, err)
assert.Equal(t, tc.expectedResult, result)
}
})
}
}
func TestUpdateRelationship(t *testing.T) {
testCases := []struct {
name string
mockTxSetup func() *mock.Transaction
expectedResult map[string]any
expectedError error
}{
{
name: "Successful case",
mockTxSetup: func() *mock.Transaction {
mockTx := new(mock.Transaction)
mockResult := new(mock.Result)
mockRecord := &neo4j.Record{
Values: []any{"value"},
Keys: []string{"key"},
}
mockResult.On("Single", context.Background()).Return(mockRecord, nil)
mockTx.On("Run", context.Background(), UpdateRelationshipCypherQuery, map[string]any{
"id1": 1,
"id2": 2,
"relationship": api.FamilyRelationship{},
}).Return(mockResult, nil)
return mockTx
},
expectedResult: map[string]any{"key": "value"},
expectedError: nil,
},
{
name: "Error during Run",
mockTxSetup: func() *mock.Transaction {
mockTx := new(mock.Transaction)
mockTx.On("Run", context.Background(), UpdateRelationshipCypherQuery, map[string]any{
"id1": 1,
"id2": 2,
"relationship": api.FamilyRelationship{},
}).Return(nil, errors.New("run error"))
return mockTx
},
expectedResult: nil,
expectedError: errors.New("run error"),
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
ctx := context.Background()
id1, id2 := 1, 2
relationship := api.FamilyRelationship{}
mockTx := tc.mockTxSetup()
work := UpdateRelationship(ctx, id1, id2, relationship)
result, err := work(mockTx)
if tc.expectedError != nil {
assert.Error(t, err)
assert.Nil(t, result)
} else {
assert.NoError(t, err)
assert.Equal(t, tc.expectedResult, result)
}
})
}
}