Skip to content

Commit

Permalink
test: Add relation substitute mechanic to tests (#2682)
Browse files Browse the repository at this point in the history
## Relevant issue(s)

Resolves #2681

## Description

Adds a relation substitute mechanic to tests, allowing us to not worry
about doc ids in tests that don't need to care about the exact string.

Only converts a handful of tests to the new system, I don't think we
should actively spend large chunks of time migrating to the new system -
we can just write new tests using this where appropriate, and passively
convert existing when convenient.
  • Loading branch information
AndrewSisley authored Jun 4, 2024
1 parent cbb3f23 commit da3d057
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 70 deletions.
64 changes: 32 additions & 32 deletions tests/integration/index/query_with_compound_filter_relation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,17 +144,17 @@ func TestIndex_QueryWithIndexOnOneToManyRelationAndFilter_Data(t *testing.T) {
},
testUtils.CreateDoc{
CollectionID: 0,
Doc: `{
"certificationBodyOrg": "bae-2b020aba-0681-5896-91d6-e3224938c32e",
"name": "DefraDB"
}`,
DocMap: map[string]any{
"name": "DefraDB",
"certificationBodyOrg": testUtils.NewDocIndex(1, 0),
},
},
testUtils.CreateDoc{
CollectionID: 0,
Doc: `{
"certificationBodyOrg": "bae-2b020aba-0681-5896-91d6-e3224938c32e",
"name": "LensVM"
}`,
DocMap: map[string]any{
"name": "LensVM",
"certificationBodyOrg": testUtils.NewDocIndex(1, 0),
},
},
testUtils.CreateDoc{
CollectionID: 1,
Expand All @@ -164,10 +164,10 @@ func TestIndex_QueryWithIndexOnOneToManyRelationAndFilter_Data(t *testing.T) {
},
testUtils.CreateDoc{
CollectionID: 0,
Doc: `{
"certificationBodyOrg": "bae-5e7a0a2c-40a0-572c-93b6-79930cab3317",
"name": "Horizon"
}`,
DocMap: map[string]any{
"name": "Horizon",
"certificationBodyOrg": testUtils.NewDocIndex(1, 1),
},
},
testUtils.CreateDoc{
CollectionID: 0,
Expand Down Expand Up @@ -225,17 +225,17 @@ func TestIndex_QueryWithIndexOnOneToManyRelationOrFilter_Data(t *testing.T) {
},
testUtils.CreateDoc{
CollectionID: 0,
Doc: `{
"certificationBodyOrg": "bae-2b020aba-0681-5896-91d6-e3224938c32e",
"name": "DefraDB"
}`,
DocMap: map[string]any{
"name": "DefraDB",
"certificationBodyOrg": testUtils.NewDocIndex(1, 0),
},
},
testUtils.CreateDoc{
CollectionID: 0,
Doc: `{
"certificationBodyOrg": "bae-2b020aba-0681-5896-91d6-e3224938c32e",
"name": "LensVM"
}`,
DocMap: map[string]any{
"name": "LensVM",
"certificationBodyOrg": testUtils.NewDocIndex(1, 0),
},
},
testUtils.CreateDoc{
CollectionID: 1,
Expand All @@ -245,10 +245,10 @@ func TestIndex_QueryWithIndexOnOneToManyRelationOrFilter_Data(t *testing.T) {
},
testUtils.CreateDoc{
CollectionID: 0,
Doc: `{
"certificationBodyOrg": "bae-5e7a0a2c-40a0-572c-93b6-79930cab3317",
"name": "Horizon"
}`,
DocMap: map[string]any{
"name": "Horizon",
"certificationBodyOrg": testUtils.NewDocIndex(1, 1),
},
},
testUtils.CreateDoc{
CollectionID: 0,
Expand Down Expand Up @@ -310,10 +310,10 @@ func TestIndex_QueryWithIndexOnOneToManyRelationNotFilter_Data(t *testing.T) {
},
testUtils.CreateDoc{
CollectionID: 0,
Doc: `{
"certificationBodyOrg": "bae-2b020aba-0681-5896-91d6-e3224938c32e",
"name": "DefraDB"
}`,
DocMap: map[string]any{
"name": "DefraDB",
"certificationBodyOrg": testUtils.NewDocIndex(1, 0),
},
},
testUtils.CreateDoc{
CollectionID: 1,
Expand All @@ -323,10 +323,10 @@ func TestIndex_QueryWithIndexOnOneToManyRelationNotFilter_Data(t *testing.T) {
},
testUtils.CreateDoc{
CollectionID: 0,
Doc: `{
"certificationBodyOrg": "bae-5e7a0a2c-40a0-572c-93b6-79930cab3317",
"name": "Horizon"
}`,
DocMap: map[string]any{
"name": "Horizon",
"certificationBodyOrg": testUtils.NewDocIndex(1, 1),
},
},
testUtils.CreateDoc{
CollectionID: 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
package one_to_many

import (
"fmt"
"testing"

"github.com/sourcenetwork/immutable"
Expand Down Expand Up @@ -122,8 +121,6 @@ func TestMutationCreateOneToMany_AliasedRelationNameInvalidIDManySide_CreatedDoc
}

func TestMutationCreateOneToMany_AliasedRelationNameToLinkFromManySide(t *testing.T) {
authorID := "bae-2edb7fdd-cad7-5ad4-9c7d-6920245a96ed"

test := testUtils.TestCase{
Description: "One to many create mutation using relation id from many side, with alias.",
Actions: []any{
Expand All @@ -135,13 +132,10 @@ func TestMutationCreateOneToMany_AliasedRelationNameToLinkFromManySide(t *testin
},
testUtils.CreateDoc{
CollectionID: 0,
Doc: fmt.Sprintf(
`{
"name": "Painted House",
"author": "%s"
}`,
authorID,
),
DocMap: map[string]any{
"name": "Painted House",
"author": testUtils.NewDocIndex(1, 0),
},
},
testUtils.Request{
Request: `query {
Expand Down Expand Up @@ -189,7 +183,6 @@ func TestMutationCreateOneToMany_AliasedRelationNameToLinkFromManySide(t *testin

func TestMutationUpdateOneToMany_AliasRelationNameAndInternalIDBothProduceSameDocID(t *testing.T) {
// These IDs MUST be shared by both tests below.
authorID := "bae-2edb7fdd-cad7-5ad4-9c7d-6920245a96ed"
bookID := "bae-22e0a1c2-d12b-5bfd-b039-0cf72f963991"

nonAliasedTest := testUtils.TestCase{
Expand All @@ -203,13 +196,10 @@ func TestMutationUpdateOneToMany_AliasRelationNameAndInternalIDBothProduceSameDo
},
testUtils.CreateDoc{
CollectionID: 0,
Doc: fmt.Sprintf(
`{
"name": "Painted House",
"author_id": "%s"
}`,
authorID,
),
DocMap: map[string]any{
"name": "Painted House",
"author": testUtils.NewDocIndex(1, 0),
},
},
testUtils.Request{
Request: `query {
Expand Down Expand Up @@ -241,13 +231,10 @@ func TestMutationUpdateOneToMany_AliasRelationNameAndInternalIDBothProduceSameDo
},
testUtils.CreateDoc{
CollectionID: 0,
Doc: fmt.Sprintf(
`{
"name": "Painted House",
"author": "%s"
}`,
authorID,
),
DocMap: map[string]any{
"name": "Painted House",
"author": testUtils.NewDocIndex(1, 0),
},
},
testUtils.Request{
Request: `query {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
package one_to_many

import (
"fmt"
"testing"

testUtils "github.com/sourcenetwork/defradb/tests/integration"
Expand Down Expand Up @@ -95,8 +94,6 @@ func TestMutationCreateOneToMany_NonExistingRelationManySide_CreatedDoc(t *testi
}

func TestMutationCreateOneToMany_RelationIDToLinkFromManySide(t *testing.T) {
authorKey := "bae-2edb7fdd-cad7-5ad4-9c7d-6920245a96ed"

test := testUtils.TestCase{
Description: "One to many create mutation using relation id from many side",
Actions: []any{
Expand All @@ -108,13 +105,10 @@ func TestMutationCreateOneToMany_RelationIDToLinkFromManySide(t *testing.T) {
},
testUtils.CreateDoc{
CollectionID: 0,
Doc: fmt.Sprintf(
`{
"name": "Painted House",
"author_id": "%s"
}`,
authorKey,
),
DocMap: map[string]any{
"name": "Painted House",
"author_id": testUtils.NewDocIndex(1, 0),
},
},
testUtils.Request{
Request: `query {
Expand Down
34 changes: 34 additions & 0 deletions tests/integration/test_case.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,15 +225,49 @@ type CreateDoc struct {
CollectionID int

// The document to create, in JSON string format.
//
// If [DocMap] is provided this value will be ignored.
Doc string

// The document to create, in map format.
//
// If this is provided [Doc] will be ignored.
DocMap map[string]any

// Any error expected from the action. Optional.
//
// String can be a partial, and the test will pass if an error is returned that
// contains this string.
ExpectedError string
}

// DocIndex represents a relation field value, it allows relation fields to be set without worrying
// about the specific document id.
//
// The test harness will substitute this struct for the document at the given index before
// performing the host action.
//
// The targeted document must have been defined in an action prior to the action that this index
// is hosted upon.
type DocIndex struct {
// CollectionIndex is the index of the collection holding the document to target.
CollectionIndex int

// Index is the index within the target collection at which the document exists.
//
// This is dependent on the order in which test [CreateDoc] actions were defined.
Index int
}

// NewDocIndex creates a new [DocIndex] instance allowing relation fields to be set without worrying
// about the specific document id.
func NewDocIndex(collectionIndex int, index int) DocIndex {
return DocIndex{
CollectionIndex: collectionIndex,
Index: index,
}
}

// DeleteDoc will attempt to delete the given document in the given collection
// using the collection api.
type DeleteDoc struct {
Expand Down
45 changes: 42 additions & 3 deletions tests/integration/utils2.go
Original file line number Diff line number Diff line change
Expand Up @@ -1152,6 +1152,10 @@ func createDoc(
s *state,
action CreateDoc,
) {
if action.DocMap != nil {
substituteRelations(s, action)
}

var mutation func(*state, CreateDoc, client.P2P, []client.Collection) (*client.Document, error)

switch mutationType {
Expand Down Expand Up @@ -1197,7 +1201,12 @@ func createDocViaColSave(
collections []client.Collection,
) (*client.Document, error) {
var err error
doc, err := client.NewDocFromJSON([]byte(action.Doc), collections[action.CollectionID].Definition())
var doc *client.Document
if action.DocMap != nil {
doc, err = client.NewDocFromMap(action.DocMap, collections[action.CollectionID].Definition())
} else {
doc, err = client.NewDocFromJSON([]byte(action.Doc), collections[action.CollectionID].Definition())
}
if err != nil {
return nil, err
}
Expand All @@ -1217,7 +1226,12 @@ func createDocViaColCreate(
collections []client.Collection,
) (*client.Document, error) {
var err error
doc, err := client.NewDocFromJSON([]byte(action.Doc), collections[action.CollectionID].Definition())
var doc *client.Document
if action.DocMap != nil {
doc, err = client.NewDocFromMap(action.DocMap, collections[action.CollectionID].Definition())
} else {
doc, err = client.NewDocFromJSON([]byte(action.Doc), collections[action.CollectionID].Definition())
}
if err != nil {
return nil, err
}
Expand All @@ -1237,8 +1251,14 @@ func createDocViaGQL(
collections []client.Collection,
) (*client.Document, error) {
collection := collections[action.CollectionID]
var err error
var input string

input, err := jsonToGQL(action.Doc)
if action.DocMap != nil {
input, err = valueToGQL(action.DocMap)
} else {
input, err = jsonToGQL(action.Doc)
}
require.NoError(s.t, err)

request := fmt.Sprintf(
Expand Down Expand Up @@ -1279,6 +1299,25 @@ func createDocViaGQL(
return doc, nil
}

// substituteRelations scans the fields defined in [action.DocMap], if any are of type [DocIndex]
// it will substitute the [DocIndex] for the the corresponding document ID found in the state.
//
// If a document at that index is not found it will panic.
func substituteRelations(
s *state,
action CreateDoc,
) {
for k, v := range action.DocMap {
index, isIndex := v.(DocIndex)
if !isIndex {
continue
}

doc := s.documents[index.CollectionIndex][index.Index]
action.DocMap[k] = doc.ID().String()
}
}

// deleteDoc deletes a document using the collection api and caches it in the
// given documents slice.
func deleteDoc(
Expand Down

0 comments on commit da3d057

Please sign in to comment.