github.com/weaviate/weaviate@v1.24.6/test/acceptance/objects/auto_schema_test.go (about)

     1  //                           _       _
     2  // __      _____  __ ___   ___  __ _| |_ ___
     3  // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
     4  //  \ V  V /  __/ (_| |\ V /| | (_| | ||  __/
     5  //   \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
     6  //
     7  //  Copyright © 2016 - 2024 Weaviate B.V. All rights reserved.
     8  //
     9  //  CONTACT: hello@weaviate.io
    10  //
    11  
    12  package test
    13  
    14  // Acceptance tests for objects.
    15  
    16  import (
    17  	"encoding/json"
    18  	"testing"
    19  
    20  	"github.com/stretchr/testify/assert"
    21  	"github.com/weaviate/weaviate/client/schema"
    22  
    23  	"github.com/weaviate/weaviate/client/objects"
    24  	"github.com/weaviate/weaviate/entities/models"
    25  	"github.com/weaviate/weaviate/test/helper"
    26  )
    27  
    28  func TestAutoSchemaWithDifferentProperties(t *testing.T) {
    29  	// Add two objects with different properties to the same class. With autoschema enabled both should be added and
    30  	// the class should have properties form both classes at the end
    31  	className := "RandomName234234"
    32  
    33  	testCases := []struct {
    34  		name  string
    35  		names []string
    36  	}{
    37  		{name: "UpperCase", names: []string{"NonExistingProperty", "OtherNonExistingProperty"}},
    38  		{name: "LowerCase", names: []string{"nonExistingProperty", "otherNonExistingProperty"}},
    39  	}
    40  
    41  	for _, test := range testCases {
    42  		t.Run(test.name, func(t *testing.T) {
    43  			obj1 := &models.Object{
    44  				Class: className,
    45  				Properties: map[string]interface{}{
    46  					test.names[0]: "test",
    47  				},
    48  			}
    49  			params := objects.NewObjectsCreateParams().WithBody(obj1)
    50  			resp, err := helper.Client(t).Objects.ObjectsCreate(params, nil)
    51  			helper.AssertRequestOk(t, resp, err, nil)
    52  
    53  			obj2 := &models.Object{
    54  				Class: className,
    55  				Properties: map[string]interface{}{
    56  					test.names[1]: "test",
    57  				},
    58  			}
    59  			params2 := objects.NewObjectsCreateParams().WithBody(obj2)
    60  			resp2, err2 := helper.Client(t).Objects.ObjectsCreate(params2, nil)
    61  			helper.AssertRequestOk(t, resp2, err2, nil)
    62  
    63  			SchemaParams := schema.NewSchemaDumpParams()
    64  			resp3, err3 := helper.Client(t).Schema.SchemaDump(SchemaParams, nil)
    65  			helper.AssertRequestOk(t, resp3, err3, nil)
    66  			assert.Len(t, resp3.Payload.Classes, 1)
    67  			class := resp3.Payload.Classes[0]
    68  			assert.Len(t, class.Properties, 2)
    69  			props := class.Properties
    70  			assert.ElementsMatch(t, []string{props[0].Name, props[1].Name}, []string{"nonExistingProperty", "otherNonExistingProperty"})
    71  			deleteObjectClass(t, className)
    72  		})
    73  	}
    74  }
    75  
    76  // run from setup_test.go
    77  func autoSchemaObjects(t *testing.T) {
    78  	autoSchemaObjectTestCases := []struct {
    79  		// the name of the test
    80  		name string
    81  		// the example object, with non existent classes and properties.
    82  		object func() *models.Object
    83  	}{
    84  		{
    85  			name: "non existing class",
    86  			object: func() *models.Object {
    87  				return &models.Object{
    88  					ID:    "8e2997f2-1972-4ee2-ad35-5fc704f2893e",
    89  					Class: "NonExistingClass",
    90  					Properties: map[string]interface{}{
    91  						"testString":  "test",
    92  						"testNumber":  json.Number("1"),
    93  						"testDate":    "2002-10-02T15:00:00Z",
    94  						"testBoolean": true,
    95  						"testGeoCoordinates": map[string]interface{}{
    96  							"latitude":  json.Number("1.01"),
    97  							"longitude": json.Number("1.01"),
    98  						},
    99  						"testPhoneNumber": map[string]interface{}{
   100  							"input":          "020 1234567",
   101  							"defaultCountry": "nl",
   102  						},
   103  						"textArray":   []string{"a", "b", "c"},
   104  						"intArray":    []int{1, 2, 3},
   105  						"numberArray": []int{11.0, 22.0, 33.0},
   106  					},
   107  				}
   108  			},
   109  		},
   110  		{
   111  			name: "non existing property",
   112  			object: func() *models.Object {
   113  				return &models.Object{
   114  					Class: "TestObject",
   115  					Properties: map[string]interface{}{
   116  						"nonExistingProperty": "test",
   117  					},
   118  				}
   119  			},
   120  		},
   121  		{
   122  			name: "non existing property update class",
   123  			object: func() *models.Object {
   124  				return &models.Object{
   125  					ID:    "8e2997f2-1972-4ee2-ad35-5fc704f2893f",
   126  					Class: "TestObject",
   127  					Properties: map[string]interface{}{
   128  						"nonExistingDateProperty":   "2002-10-02T15:00:00Z",
   129  						"nonExistingNumberProperty": json.Number("1"),
   130  					},
   131  				}
   132  			},
   133  		},
   134  	}
   135  
   136  	t.Run("auto schema should create object with missing classes and properties", func(t *testing.T) {
   137  		for _, example_ := range autoSchemaObjectTestCases {
   138  			t.Run(example_.name, func(t *testing.T) {
   139  				example := example_ // Needed; example is updated to point to a new test case.
   140  				t.Parallel()
   141  
   142  				params := objects.NewObjectsCreateParams().WithBody(example.object())
   143  				resp, err := helper.Client(t).Objects.ObjectsCreate(params, nil)
   144  				helper.AssertRequestOk(t, resp, err, nil)
   145  			})
   146  		}
   147  	})
   148  
   149  	autoSchemaCrossRefTestCases := []struct {
   150  		// the name of the test
   151  		name string
   152  		// the example object, with non existent classes and properties.
   153  		object func() *models.Object
   154  	}{
   155  		{
   156  			name: "non existing cross ref property update class",
   157  			object: func() *models.Object {
   158  				return &models.Object{
   159  					Class: "TestObject",
   160  					Properties: map[string]interface{}{
   161  						"hasNonExistingClass": []interface{}{
   162  							map[string]interface{}{
   163  								"beacon": "weaviate://localhost/8e2997f2-1972-4ee2-ad35-5fc704f2893e",
   164  							},
   165  						},
   166  					},
   167  				}
   168  			},
   169  		},
   170  		{
   171  			name: "non existing cross ref property update class",
   172  			object: func() *models.Object {
   173  				return &models.Object{
   174  					Class: "TestObject",
   175  					Properties: map[string]interface{}{
   176  						"hasNonExistingClassAndTestObject": []interface{}{
   177  							map[string]interface{}{
   178  								"beacon": "weaviate://localhost/8e2997f2-1972-4ee2-ad35-5fc704f2893e",
   179  							},
   180  							map[string]interface{}{
   181  								"beacon": "weaviate://localhost/8e2997f2-1972-4ee2-ad35-5fc704f2893f",
   182  							},
   183  						},
   184  					},
   185  				}
   186  			},
   187  		},
   188  	}
   189  
   190  	t.Run("auto schema should create object with missing cross ref properties", func(t *testing.T) {
   191  		for _, example_ := range autoSchemaCrossRefTestCases {
   192  			t.Run(example_.name, func(t *testing.T) {
   193  				example := example_ // Needed; example is updated to point to a new test case.
   194  				params := objects.NewObjectsCreateParams().WithBody(example.object())
   195  				resp, err := helper.Client(t).Objects.ObjectsCreate(params, nil)
   196  				helper.AssertRequestOk(t, resp, err, nil)
   197  			})
   198  		}
   199  	})
   200  }