From e9e044027343f51a73a16de4d159c7ab5f5510b5 Mon Sep 17 00:00:00 2001 From: Andrew Sisley Date: Tue, 4 Jun 2024 09:57:03 -0400 Subject: [PATCH 1/2] Add relation substitute mechanic to tests --- tests/integration/test_case.go | 34 +++++++++++++++++++++++++ tests/integration/utils2.go | 45 +++++++++++++++++++++++++++++++--- 2 files changed, 76 insertions(+), 3 deletions(-) diff --git a/tests/integration/test_case.go b/tests/integration/test_case.go index bea260c773..9b30dd5e35 100644 --- a/tests/integration/test_case.go +++ b/tests/integration/test_case.go @@ -225,8 +225,15 @@ 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 @@ -234,6 +241,33 @@ type CreateDoc struct { 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 { diff --git a/tests/integration/utils2.go b/tests/integration/utils2.go index 708e14450b..00c47fcfc2 100644 --- a/tests/integration/utils2.go +++ b/tests/integration/utils2.go @@ -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 { @@ -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 } @@ -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 } @@ -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( @@ -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( From 55460828cb8bd710e83a9cb7bd82e347bde495d4 Mon Sep 17 00:00:00 2001 From: Andrew Sisley Date: Tue, 4 Jun 2024 10:05:01 -0400 Subject: [PATCH 2/2] Update (some) tests to use doc index --- ...uery_with_compound_filter_relation_test.go | 64 +++++++++---------- .../one_to_many/with_alias_test.go | 37 ++++------- .../one_to_many/with_simple_test.go | 14 ++-- 3 files changed, 48 insertions(+), 67 deletions(-) diff --git a/tests/integration/index/query_with_compound_filter_relation_test.go b/tests/integration/index/query_with_compound_filter_relation_test.go index ff503d6d38..31667d8bc7 100644 --- a/tests/integration/index/query_with_compound_filter_relation_test.go +++ b/tests/integration/index/query_with_compound_filter_relation_test.go @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, diff --git a/tests/integration/mutation/create/field_kinds/one_to_many/with_alias_test.go b/tests/integration/mutation/create/field_kinds/one_to_many/with_alias_test.go index 27ddcf0e68..43275f8404 100644 --- a/tests/integration/mutation/create/field_kinds/one_to_many/with_alias_test.go +++ b/tests/integration/mutation/create/field_kinds/one_to_many/with_alias_test.go @@ -11,7 +11,6 @@ package one_to_many import ( - "fmt" "testing" "github.com/sourcenetwork/immutable" @@ -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{ @@ -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 { @@ -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{ @@ -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 { @@ -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 { diff --git a/tests/integration/mutation/create/field_kinds/one_to_many/with_simple_test.go b/tests/integration/mutation/create/field_kinds/one_to_many/with_simple_test.go index 2a8b64d1b1..3d15e52323 100644 --- a/tests/integration/mutation/create/field_kinds/one_to_many/with_simple_test.go +++ b/tests/integration/mutation/create/field_kinds/one_to_many/with_simple_test.go @@ -11,7 +11,6 @@ package one_to_many import ( - "fmt" "testing" testUtils "github.com/sourcenetwork/defradb/tests/integration" @@ -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{ @@ -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 {