Spaces:
Sleeping
Sleeping
| // _ _ | |
| // __ _____ __ ___ ___ __ _| |_ ___ | |
| // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ | |
| // \ V V / __/ (_| |\ V /| | (_| | || __/ | |
| // \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| | |
| // | |
| // Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. | |
| // | |
| // CONTACT: [email protected] | |
| // | |
| package acceptance_with_go_client | |
| import ( | |
| "context" | |
| "testing" | |
| "github.com/weaviate/weaviate-go-client/v4/weaviate/filters" | |
| "github.com/weaviate/weaviate-go-client/v4/weaviate/graphql" | |
| "github.com/stretchr/testify/require" | |
| client "github.com/weaviate/weaviate-go-client/v4/weaviate" | |
| "github.com/weaviate/weaviate/entities/models" | |
| "github.com/weaviate/weaviate/entities/schema" | |
| ) | |
| func TestUpdatingPropertiesWithNil(t *testing.T) { | |
| ctx := context.Background() | |
| c, err := client.NewClient(client.Config{Scheme: "http", Host: "localhost:8080"}) | |
| require.Nil(t, err) | |
| className := "RandomPinkFlower" | |
| upperPropName := "SomeProp" | |
| lowerPropName := "someProp" | |
| cases := []struct { | |
| prop1 string | |
| prop2 string | |
| }{ | |
| {prop1: upperPropName, prop2: upperPropName}, | |
| {prop1: lowerPropName, prop2: lowerPropName}, | |
| {prop1: upperPropName, prop2: lowerPropName}, | |
| {prop1: lowerPropName, prop2: upperPropName}, | |
| } | |
| for _, tt := range cases { | |
| t.Run(tt.prop1+" "+tt.prop2, func(t *testing.T) { | |
| c.Schema().ClassDeleter().WithClassName(className).Do(ctx) | |
| defer c.Schema().ClassDeleter().WithClassName(className).Do(ctx) | |
| classCreator := c.Schema().ClassCreator() | |
| class := models.Class{ | |
| Class: className, | |
| Properties: []*models.Property{{ | |
| Name: tt.prop1, | |
| // TODO change to method call | |
| DataType: []string{string(schema.DataTypeText)}, | |
| // TODO change to constant | |
| Tokenization: "whitespace", | |
| }}, | |
| InvertedIndexConfig: &models.InvertedIndexConfig{IndexNullState: true}, | |
| } | |
| require.Nil(t, classCreator.WithClass(&class).Do(ctx)) | |
| obj, err := c.Data().Creator().WithClassName(className).WithProperties( | |
| map[string]interface{}{tt.prop1: "SomeText"}, | |
| ).WithID("0a21ae23-3f22-4f34-b04a-199e701886ef").Do(ctx) | |
| require.Nil(t, err) | |
| require.Nil(t, c.Data().Updater().WithClassName(className).WithProperties(map[string]interface{}{tt.prop2: nil}).WithID(string(obj.Object.ID)).WithMerge().Do(ctx)) | |
| // update should have cleared the object | |
| getter := c.Data().ObjectsGetter() | |
| objAfterUpdate, err := getter.WithID(string(obj.Object.ID)).WithClassName(className).Do(ctx) | |
| require.Nil(t, err) | |
| require.Len(t, objAfterUpdate[0].Properties, 0) | |
| // test that II has been updated: | |
| // a) no results for when filtering for old value | |
| // b) one result when filtering for null values | |
| filter := filters.Where() | |
| filter.WithValueString("SomeText") | |
| filter.WithOperator(filters.Equal) | |
| filter.WithPath([]string{lowerPropName}) | |
| resultFilter, err := c.GraphQL().Get().WithClassName(className).WithWhere(filter).WithFields(graphql.Field{Name: "_additional", Fields: []graphql.Field{{Name: "id"}}}).Do(ctx) | |
| require.Nil(t, err) | |
| require.Len(t, resultFilter.Data["Get"].(map[string]interface{})[className], 0) | |
| filter = filters.Where() | |
| filter.WithValueBoolean(true) | |
| filter.WithOperator("IsNull") // replace with real operator after updating go client | |
| filter.WithPath([]string{lowerPropName}) | |
| resultFilter, err = c.GraphQL().Get().WithClassName(className).WithWhere(filter).WithFields(graphql.Field{Name: "_additional", Fields: []graphql.Field{{Name: "id"}}}).Do(ctx) | |
| require.Nil(t, err) | |
| require.Len(t, resultFilter.Data["Get"].(map[string]interface{})[className], 1) | |
| // Property is still part of the class | |
| schemaClass, err := c.Schema().ClassGetter().WithClassName(className).Do(ctx) | |
| require.Nil(t, err) | |
| require.Len(t, schemaClass.Properties, 1) | |
| }) | |
| } | |
| } | |