github.com/weaviate/weaviate@v1.24.6/adapters/handlers/rest/handlers_objects_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 rest
    13  
    14  import (
    15  	"context"
    16  	stderrors "errors"
    17  	"net/http/httptest"
    18  	"testing"
    19  
    20  	"github.com/go-openapi/strfmt"
    21  	"github.com/sirupsen/logrus"
    22  	"github.com/weaviate/weaviate/adapters/handlers/rest/operations/objects"
    23  	"github.com/weaviate/weaviate/entities/additional"
    24  	"github.com/weaviate/weaviate/entities/models"
    25  	"github.com/weaviate/weaviate/usecases/auth/authorization/errors"
    26  	"github.com/weaviate/weaviate/usecases/config"
    27  	uco "github.com/weaviate/weaviate/usecases/objects"
    28  
    29  	"github.com/stretchr/testify/assert"
    30  	"github.com/stretchr/testify/require"
    31  )
    32  
    33  func TestEnrichObjectsWithLinks(t *testing.T) {
    34  	t.Run("add object", func(t *testing.T) {
    35  		type test struct {
    36  			name           string
    37  			object         *models.Object
    38  			expectedResult *models.Object
    39  		}
    40  
    41  		tests := []test{
    42  			{
    43  				name:           "without props - nothing changes",
    44  				object:         &models.Object{Class: "Foo", Properties: nil},
    45  				expectedResult: &models.Object{Class: "Foo", Properties: nil},
    46  			},
    47  			{
    48  				name: "without ref props - nothing changes",
    49  				object: &models.Object{Class: "Foo", Properties: map[string]interface{}{
    50  					"name":           "hello world",
    51  					"numericalField": 134,
    52  				}},
    53  				expectedResult: &models.Object{Class: "Foo", Properties: map[string]interface{}{
    54  					"name":           "hello world",
    55  					"numericalField": 134,
    56  				}},
    57  			},
    58  			{
    59  				name: "with a ref prop - no origin configured",
    60  				object: &models.Object{Class: "Foo", Properties: map[string]interface{}{
    61  					"name":           "hello world",
    62  					"numericalField": 134,
    63  					"someRef": models.MultipleRef{
    64  						&models.SingleRef{
    65  							Beacon: "weaviate://localhost/85f78e29-5937-4390-a121-5379f262b4e5",
    66  						},
    67  					},
    68  				}},
    69  				expectedResult: &models.Object{Class: "Foo", Properties: map[string]interface{}{
    70  					"name":           "hello world",
    71  					"numericalField": 134,
    72  					"someRef": models.MultipleRef{
    73  						&models.SingleRef{
    74  							Beacon: "weaviate://localhost/85f78e29-5937-4390-a121-5379f262b4e5",
    75  							Href:   "/v1/objects/85f78e29-5937-4390-a121-5379f262b4e5",
    76  						},
    77  					},
    78  				}},
    79  			},
    80  		}
    81  
    82  		for _, test := range tests {
    83  			t.Run(test.name, func(t *testing.T) {
    84  				fakeManager := &fakeManager{
    85  					addObjectReturn: test.object,
    86  				}
    87  				h := &objectHandlers{manager: fakeManager, metricRequestsTotal: &fakeMetricRequestsTotal{}}
    88  				res := h.addObject(objects.ObjectsCreateParams{
    89  					HTTPRequest: httptest.NewRequest("POST", "/v1/objects", nil),
    90  					Body:        test.object,
    91  				}, nil)
    92  				parsed, ok := res.(*objects.ObjectsCreateOK)
    93  				require.True(t, ok)
    94  				assert.Equal(t, test.expectedResult, parsed.Payload)
    95  			})
    96  		}
    97  	})
    98  
    99  	// This test "with an origin configured" is not repeated for every handler,
   100  	// as testing this feature once was deemed sufficient
   101  	t.Run("add object - with an origin configured", func(t *testing.T) {
   102  		type test struct {
   103  			name           string
   104  			object         *models.Object
   105  			expectedResult *models.Object
   106  		}
   107  
   108  		tests := []test{
   109  			{
   110  				name:           "without props - nothing changes",
   111  				object:         &models.Object{Class: "Foo", Properties: nil},
   112  				expectedResult: &models.Object{Class: "Foo", Properties: nil},
   113  			},
   114  			{
   115  				name: "without ref props - nothing changes",
   116  				object: &models.Object{Class: "Foo", Properties: map[string]interface{}{
   117  					"name":           "hello world",
   118  					"numericalField": 134,
   119  				}},
   120  				expectedResult: &models.Object{Class: "Foo", Properties: map[string]interface{}{
   121  					"name":           "hello world",
   122  					"numericalField": 134,
   123  				}},
   124  			},
   125  			{
   126  				name: "with a ref prop - no origin configured",
   127  				object: &models.Object{Class: "Foo", Properties: map[string]interface{}{
   128  					"name":           "hello world",
   129  					"numericalField": 134,
   130  					"someRef": models.MultipleRef{
   131  						&models.SingleRef{
   132  							Beacon: "weaviate://localhost/85f78e29-5937-4390-a121-5379f262b4e5",
   133  						},
   134  					},
   135  				}},
   136  				expectedResult: &models.Object{Class: "Foo", Properties: map[string]interface{}{
   137  					"name":           "hello world",
   138  					"numericalField": 134,
   139  					"someRef": models.MultipleRef{
   140  						&models.SingleRef{
   141  							Beacon: "weaviate://localhost/85f78e29-5937-4390-a121-5379f262b4e5",
   142  							Href:   "https://awesomehost.com/v1/objects/85f78e29-5937-4390-a121-5379f262b4e5",
   143  						},
   144  					},
   145  				}},
   146  			},
   147  		}
   148  
   149  		for _, test := range tests {
   150  			t.Run(test.name, func(t *testing.T) {
   151  				fakeManager := &fakeManager{
   152  					addObjectReturn: test.object,
   153  				}
   154  				config := config.Config{Origin: "https://awesomehost.com"}
   155  				h := &objectHandlers{manager: fakeManager, config: config, metricRequestsTotal: &fakeMetricRequestsTotal{}}
   156  				res := h.addObject(objects.ObjectsCreateParams{
   157  					HTTPRequest: httptest.NewRequest("POST", "/v1/objects", nil),
   158  					Body:        test.object,
   159  				}, nil)
   160  				parsed, ok := res.(*objects.ObjectsCreateOK)
   161  				require.True(t, ok)
   162  				assert.Equal(t, test.expectedResult, parsed.Payload)
   163  			})
   164  		}
   165  	})
   166  
   167  	t.Run("get object deprecated", func(t *testing.T) {
   168  		type test struct {
   169  			name           string
   170  			object         *models.Object
   171  			expectedResult *models.Object
   172  		}
   173  
   174  		tests := []test{
   175  			{
   176  				name:           "without props - nothing changes",
   177  				object:         &models.Object{Class: "Foo", Properties: nil},
   178  				expectedResult: &models.Object{Class: "Foo", Properties: nil},
   179  			},
   180  			{
   181  				name: "without ref props - nothing changes",
   182  				object: &models.Object{Class: "Foo", Properties: map[string]interface{}{
   183  					"name":           "hello world",
   184  					"numericalField": 134,
   185  				}},
   186  				expectedResult: &models.Object{Class: "Foo", Properties: map[string]interface{}{
   187  					"name":           "hello world",
   188  					"numericalField": 134,
   189  				}},
   190  			},
   191  			{
   192  				name: "with a ref prop - no origin configured",
   193  				object: &models.Object{Class: "Foo", Properties: map[string]interface{}{
   194  					"name":           "hello world",
   195  					"numericalField": 134,
   196  					"someRef": models.MultipleRef{
   197  						&models.SingleRef{
   198  							Beacon: "weaviate://localhost/85f78e29-5937-4390-a121-5379f262b4e5",
   199  						},
   200  					},
   201  				}},
   202  				expectedResult: &models.Object{Class: "Foo", Properties: map[string]interface{}{
   203  					"name":           "hello world",
   204  					"numericalField": 134,
   205  					"someRef": models.MultipleRef{
   206  						&models.SingleRef{
   207  							Beacon: "weaviate://localhost/85f78e29-5937-4390-a121-5379f262b4e5",
   208  							Href:   "/v1/objects/85f78e29-5937-4390-a121-5379f262b4e5",
   209  						},
   210  					},
   211  				}},
   212  			},
   213  		}
   214  
   215  		for _, test := range tests {
   216  			t.Run(test.name, func(t *testing.T) {
   217  				fakeManager := &fakeManager{
   218  					getObjectReturn: test.object,
   219  				}
   220  				h := &objectHandlers{manager: fakeManager, logger: &logrus.Logger{}, metricRequestsTotal: &fakeMetricRequestsTotal{}}
   221  				res := h.getObjectDeprecated(objects.ObjectsGetParams{HTTPRequest: httptest.NewRequest("GET", "/v1/objects", nil)}, nil)
   222  				parsed, ok := res.(*objects.ObjectsClassGetOK)
   223  				require.True(t, ok)
   224  				assert.Equal(t, test.expectedResult, parsed.Payload)
   225  			})
   226  		}
   227  	})
   228  
   229  	t.Run("get objects", func(t *testing.T) {
   230  		type test struct {
   231  			name           string
   232  			object         []*models.Object
   233  			expectedResult []*models.Object
   234  		}
   235  
   236  		tests := []test{
   237  			{
   238  				name:           "without props - nothing changes",
   239  				object:         []*models.Object{{Class: "Foo", Properties: nil}},
   240  				expectedResult: []*models.Object{{Class: "Foo", Properties: nil}},
   241  			},
   242  			{
   243  				name: "without ref props - nothing changes",
   244  				object: []*models.Object{
   245  					{Class: "Foo", Properties: map[string]interface{}{
   246  						"name":           "hello world",
   247  						"numericalField": 134,
   248  					}},
   249  					{Class: "Bar", Properties: map[string]interface{}{
   250  						"name":           "hello world",
   251  						"numericalField": 234,
   252  					}},
   253  				},
   254  				expectedResult: []*models.Object{
   255  					{Class: "Foo", Properties: map[string]interface{}{
   256  						"name":           "hello world",
   257  						"numericalField": 134,
   258  					}},
   259  					{Class: "Bar", Properties: map[string]interface{}{
   260  						"name":           "hello world",
   261  						"numericalField": 234,
   262  					}},
   263  				},
   264  			},
   265  			{
   266  				name: "with a ref prop - no origin configured",
   267  				object: []*models.Object{
   268  					{Class: "Foo", Properties: map[string]interface{}{
   269  						"name":           "hello world",
   270  						"numericalField": 134,
   271  					}},
   272  					{Class: "Bar", Properties: map[string]interface{}{
   273  						"name":           "hello world",
   274  						"numericalField": 234,
   275  						"someRef": models.MultipleRef{
   276  							&models.SingleRef{
   277  								Beacon: "weaviate://localhost/85f78e29-5937-4390-a121-5379f262b4e5",
   278  							},
   279  						},
   280  					}},
   281  				},
   282  				expectedResult: []*models.Object{
   283  					{Class: "Foo", Properties: map[string]interface{}{
   284  						"name":           "hello world",
   285  						"numericalField": 134,
   286  					}},
   287  					{Class: "Bar", Properties: map[string]interface{}{
   288  						"name":           "hello world",
   289  						"numericalField": 234,
   290  						"someRef": models.MultipleRef{
   291  							&models.SingleRef{
   292  								Beacon: "weaviate://localhost/85f78e29-5937-4390-a121-5379f262b4e5",
   293  								Href:   "/v1/objects/85f78e29-5937-4390-a121-5379f262b4e5",
   294  							},
   295  						},
   296  					}},
   297  				},
   298  			},
   299  		}
   300  
   301  		for _, test := range tests {
   302  			t.Run(test.name, func(t *testing.T) {
   303  				fakeManager := &fakeManager{
   304  					queryResult: test.object,
   305  				}
   306  				h := &objectHandlers{manager: fakeManager, metricRequestsTotal: &fakeMetricRequestsTotal{}}
   307  				res := h.getObjects(objects.ObjectsListParams{HTTPRequest: httptest.NewRequest("GET", "/v1/objects", nil)}, nil)
   308  				parsed, ok := res.(*objects.ObjectsListOK)
   309  				require.True(t, ok)
   310  				assert.Equal(t, test.expectedResult, parsed.Payload.Objects)
   311  			})
   312  		}
   313  	})
   314  
   315  	t.Run("update object deprecated", func(t *testing.T) {
   316  		type test struct {
   317  			name           string
   318  			object         *models.Object
   319  			expectedResult *models.Object
   320  		}
   321  
   322  		tests := []test{
   323  			{
   324  				name:           "without props - nothing changes",
   325  				object:         &models.Object{Class: "Foo", Properties: nil},
   326  				expectedResult: &models.Object{Class: "Foo", Properties: nil},
   327  			},
   328  			{
   329  				name: "without ref props - nothing changes",
   330  				object: &models.Object{Class: "Foo", Properties: map[string]interface{}{
   331  					"name":           "hello world",
   332  					"numericalField": 134,
   333  				}},
   334  				expectedResult: &models.Object{Class: "Foo", Properties: map[string]interface{}{
   335  					"name":           "hello world",
   336  					"numericalField": 134,
   337  				}},
   338  			},
   339  			{
   340  				name: "with a ref prop - no origin configured",
   341  				object: &models.Object{Class: "Foo", Properties: map[string]interface{}{
   342  					"name":           "hello world",
   343  					"numericalField": 134,
   344  					"someRef": models.MultipleRef{
   345  						&models.SingleRef{
   346  							Beacon: "weaviate://localhost/85f78e29-5937-4390-a121-5379f262b4e5",
   347  						},
   348  					},
   349  				}},
   350  				expectedResult: &models.Object{Class: "Foo", Properties: map[string]interface{}{
   351  					"name":           "hello world",
   352  					"numericalField": 134,
   353  					"someRef": models.MultipleRef{
   354  						&models.SingleRef{
   355  							Beacon: "weaviate://localhost/85f78e29-5937-4390-a121-5379f262b4e5",
   356  							Href:   "/v1/objects/85f78e29-5937-4390-a121-5379f262b4e5",
   357  						},
   358  					},
   359  				}},
   360  			},
   361  		}
   362  
   363  		for _, test := range tests {
   364  			t.Run(test.name, func(t *testing.T) {
   365  				fakeManager := &fakeManager{
   366  					updateObjectReturn: test.object,
   367  				}
   368  				h := &objectHandlers{manager: fakeManager, logger: &logrus.Logger{}, metricRequestsTotal: &fakeMetricRequestsTotal{}}
   369  				res := h.updateObjectDeprecated(objects.ObjectsUpdateParams{
   370  					HTTPRequest: httptest.NewRequest("POST", "/v1/objects", nil),
   371  					Body:        test.object,
   372  				}, nil)
   373  				parsed, ok := res.(*objects.ObjectsClassPutOK)
   374  				require.True(t, ok)
   375  				assert.Equal(t, test.expectedResult, parsed.Payload)
   376  			})
   377  		}
   378  	})
   379  
   380  	t.Run("add object", func(t *testing.T) {
   381  		type test struct {
   382  			name           string
   383  			object         *models.Object
   384  			expectedResult *models.Object
   385  		}
   386  
   387  		tests := []test{
   388  			{
   389  				name:           "without props - noaction changes",
   390  				object:         &models.Object{Class: "Foo", Properties: nil},
   391  				expectedResult: &models.Object{Class: "Foo", Properties: nil},
   392  			},
   393  			{
   394  				name: "without ref props - noaction changes",
   395  				object: &models.Object{Class: "Foo", Properties: map[string]interface{}{
   396  					"name":           "hello world",
   397  					"numericalField": 134,
   398  				}},
   399  				expectedResult: &models.Object{Class: "Foo", Properties: map[string]interface{}{
   400  					"name":           "hello world",
   401  					"numericalField": 134,
   402  				}},
   403  			},
   404  			{
   405  				name: "with a ref prop - no origin configured",
   406  				object: &models.Object{Class: "Foo", Properties: map[string]interface{}{
   407  					"name":           "hello world",
   408  					"numericalField": 134,
   409  					"someRef": models.MultipleRef{
   410  						&models.SingleRef{
   411  							Beacon: "weaviate://localhost/85f78e29-5937-4390-a121-5379f262b4e5",
   412  						},
   413  					},
   414  				}},
   415  				expectedResult: &models.Object{Class: "Foo", Properties: map[string]interface{}{
   416  					"name":           "hello world",
   417  					"numericalField": 134,
   418  					"someRef": models.MultipleRef{
   419  						&models.SingleRef{
   420  							Beacon: "weaviate://localhost/85f78e29-5937-4390-a121-5379f262b4e5",
   421  							Href:   "/v1/objects/85f78e29-5937-4390-a121-5379f262b4e5",
   422  						},
   423  					},
   424  				}},
   425  			},
   426  		}
   427  
   428  		for _, test := range tests {
   429  			t.Run(test.name, func(t *testing.T) {
   430  				fakeManager := &fakeManager{
   431  					addObjectReturn: test.object,
   432  				}
   433  				h := &objectHandlers{manager: fakeManager, metricRequestsTotal: &fakeMetricRequestsTotal{}}
   434  				res := h.addObject(objects.ObjectsCreateParams{
   435  					HTTPRequest: httptest.NewRequest("POST", "/v1/objects", nil),
   436  					Body:        test.object,
   437  				}, nil)
   438  				parsed, ok := res.(*objects.ObjectsCreateOK)
   439  				require.True(t, ok)
   440  				assert.Equal(t, test.expectedResult, parsed.Payload)
   441  			})
   442  		}
   443  	})
   444  
   445  	t.Run("get objects", func(t *testing.T) {
   446  		type test struct {
   447  			name           string
   448  			object         []*models.Object
   449  			expectedResult []*models.Object
   450  		}
   451  
   452  		tests := []test{
   453  			{
   454  				name:           "without props - noaction changes",
   455  				object:         []*models.Object{{Class: "Foo", Properties: nil}},
   456  				expectedResult: []*models.Object{{Class: "Foo", Properties: nil}},
   457  			},
   458  			{
   459  				name: "without ref props - noaction changes",
   460  				object: []*models.Object{
   461  					{Class: "Foo", Properties: map[string]interface{}{
   462  						"name":           "hello world",
   463  						"numericalField": 134,
   464  					}},
   465  					{Class: "Bar", Properties: map[string]interface{}{
   466  						"name":           "hello world",
   467  						"numericalField": 234,
   468  					}},
   469  				},
   470  				expectedResult: []*models.Object{
   471  					{Class: "Foo", Properties: map[string]interface{}{
   472  						"name":           "hello world",
   473  						"numericalField": 134,
   474  					}},
   475  					{Class: "Bar", Properties: map[string]interface{}{
   476  						"name":           "hello world",
   477  						"numericalField": 234,
   478  					}},
   479  				},
   480  			},
   481  			{
   482  				name: "with a ref prop - no origin configured",
   483  				object: []*models.Object{
   484  					{Class: "Foo", Properties: map[string]interface{}{
   485  						"name":           "hello world",
   486  						"numericalField": 134,
   487  					}},
   488  					{Class: "Bar", Properties: map[string]interface{}{
   489  						"name":           "hello world",
   490  						"numericalField": 234,
   491  						"someRef": models.MultipleRef{
   492  							&models.SingleRef{
   493  								Beacon: "weaviate://localhost/85f78e29-5937-4390-a121-5379f262b4e5",
   494  							},
   495  						},
   496  					}},
   497  				},
   498  				expectedResult: []*models.Object{
   499  					{Class: "Foo", Properties: map[string]interface{}{
   500  						"name":           "hello world",
   501  						"numericalField": 134,
   502  					}},
   503  					{Class: "Bar", Properties: map[string]interface{}{
   504  						"name":           "hello world",
   505  						"numericalField": 234,
   506  						"someRef": models.MultipleRef{
   507  							&models.SingleRef{
   508  								Beacon: "weaviate://localhost/85f78e29-5937-4390-a121-5379f262b4e5",
   509  								Href:   "/v1/objects/85f78e29-5937-4390-a121-5379f262b4e5",
   510  							},
   511  						},
   512  					}},
   513  				},
   514  			},
   515  		}
   516  
   517  		for _, test := range tests {
   518  			t.Run(test.name, func(t *testing.T) {
   519  				fakeManager := &fakeManager{
   520  					queryResult: test.object,
   521  				}
   522  				h := &objectHandlers{manager: fakeManager, metricRequestsTotal: &fakeMetricRequestsTotal{}}
   523  				res := h.getObjects(objects.ObjectsListParams{HTTPRequest: httptest.NewRequest("GET", "/v1/objects", nil)}, nil)
   524  				parsed, ok := res.(*objects.ObjectsListOK)
   525  				require.True(t, ok)
   526  				assert.Equal(t, test.expectedResult, parsed.Payload.Objects)
   527  			})
   528  		}
   529  	})
   530  
   531  	// New endpoints which uniquely identify objects of a class
   532  	t.Run("UpdateObject", func(t *testing.T) {
   533  		cls := "MyClass"
   534  		type test struct {
   535  			name           string
   536  			object         *models.Object
   537  			expectedResult *models.Object
   538  			err            error
   539  		}
   540  
   541  		tests := []test{
   542  			{
   543  				name:           "without props - noaction changes",
   544  				object:         &models.Object{Class: cls, Properties: nil},
   545  				expectedResult: &models.Object{Class: cls, Properties: nil},
   546  			},
   547  			{
   548  				name: "without ref props - noaction changes",
   549  				object: &models.Object{Class: cls, Properties: map[string]interface{}{
   550  					"name":           "hello world",
   551  					"numericalField": 134,
   552  				}},
   553  				expectedResult: &models.Object{Class: cls, Properties: map[string]interface{}{
   554  					"name":           "hello world",
   555  					"numericalField": 134,
   556  				}},
   557  			},
   558  			{
   559  				name: "with a ref prop - no origin configured",
   560  				object: &models.Object{Class: cls, Properties: map[string]interface{}{
   561  					"name":           "hello world",
   562  					"numericalField": 134,
   563  					"someRef": models.MultipleRef{
   564  						&models.SingleRef{
   565  							Beacon: "weaviate://localhost/85f78e29-5937-4390-a121-5379f262b4e5",
   566  						},
   567  					},
   568  				}},
   569  				expectedResult: &models.Object{Class: cls, Properties: map[string]interface{}{
   570  					"name":           "hello world",
   571  					"numericalField": 134,
   572  					"someRef": models.MultipleRef{
   573  						&models.SingleRef{
   574  							Beacon: "weaviate://localhost/85f78e29-5937-4390-a121-5379f262b4e5",
   575  							Href:   "/v1/objects/85f78e29-5937-4390-a121-5379f262b4e5",
   576  						},
   577  					},
   578  				}},
   579  			},
   580  			{
   581  				name: "forbidden",
   582  				err:  errors.NewForbidden(&models.Principal{}, "get", "Myclass/123"),
   583  			},
   584  			{
   585  				name: "validation",
   586  				err:  uco.ErrInvalidUserInput{},
   587  			},
   588  			{
   589  				name: "not found",
   590  				err:  uco.ErrNotFound{},
   591  			},
   592  			{
   593  				name: "unknown error",
   594  				err:  stderrors.New("any error"),
   595  			},
   596  		}
   597  
   598  		for _, test := range tests {
   599  			t.Run(test.name, func(t *testing.T) {
   600  				fakeManager := &fakeManager{
   601  					updateObjectReturn: test.object,
   602  					updateObjectErr:    test.err,
   603  				}
   604  				h := &objectHandlers{manager: fakeManager, metricRequestsTotal: &fakeMetricRequestsTotal{}}
   605  				res := h.updateObject(objects.ObjectsClassPutParams{
   606  					HTTPRequest: httptest.NewRequest("POST", "/v1/objects/123", nil),
   607  					Body:        test.object,
   608  					ID:          "123",
   609  					ClassName:   cls,
   610  				}, nil)
   611  				parsed, ok := res.(*objects.ObjectsClassPutOK)
   612  				if test.err != nil {
   613  					require.False(t, ok)
   614  					return
   615  				}
   616  				require.True(t, ok)
   617  				assert.Equal(t, test.expectedResult, parsed.Payload)
   618  			})
   619  		}
   620  	})
   621  
   622  	t.Run("PatchObject", func(t *testing.T) {
   623  		var (
   624  			fakeManager             = &fakeManager{}
   625  			fakeMetricRequestsTotal = &fakeMetricRequestsTotal{}
   626  			h                       = &objectHandlers{
   627  				manager:             fakeManager,
   628  				logger:              &logrus.Logger{},
   629  				metricRequestsTotal: fakeMetricRequestsTotal,
   630  			}
   631  			req = objects.ObjectsClassPatchParams{
   632  				HTTPRequest: httptest.NewRequest("PATCH", "/v1/objects/MyClass/123", nil),
   633  				ClassName:   "MyClass",
   634  				ID:          "123",
   635  				Body:        &models.Object{Properties: map[string]interface{}{"name": "hello world"}},
   636  			}
   637  		)
   638  		res := h.patchObject(req, nil)
   639  		if _, ok := res.(*objects.ObjectsClassPatchNoContent); !ok {
   640  			t.Errorf("unexpected result %v", res)
   641  		}
   642  		fakeManager.patchObjectReturn = &uco.Error{Code: uco.StatusBadRequest}
   643  		res = h.patchObject(req, nil)
   644  		if _, ok := res.(*objects.ObjectsClassPatchUnprocessableEntity); !ok {
   645  			t.Errorf("expected: %T got: %T", objects.ObjectsClassPatchUnprocessableEntity{}, res)
   646  		}
   647  		fakeManager.patchObjectReturn = &uco.Error{Code: uco.StatusNotFound}
   648  		res = h.patchObject(req, nil)
   649  		if _, ok := res.(*objects.ObjectsClassPatchNotFound); !ok {
   650  			t.Errorf("expected: %T got: %T", objects.ObjectsClassPatchNotFound{}, res)
   651  		}
   652  		fakeManager.patchObjectReturn = &uco.Error{Code: uco.StatusForbidden}
   653  		res = h.patchObject(req, nil)
   654  		if _, ok := res.(*objects.ObjectsClassPatchForbidden); !ok {
   655  			t.Errorf("expected: %T got: %T", objects.ObjectsClassPatchForbidden{}, res)
   656  		}
   657  		fakeManager.patchObjectReturn = &uco.Error{Code: uco.StatusInternalServerError}
   658  		res = h.patchObject(req, nil)
   659  		if _, ok := res.(*objects.ObjectsClassPatchInternalServerError); !ok {
   660  			t.Errorf("expected: %T got: %T", objects.ObjectsClassPatchInternalServerError{}, res)
   661  		}
   662  
   663  		// test deprecated function
   664  		fakeManager.patchObjectReturn = nil
   665  		res = h.patchObjectDeprecated(objects.ObjectsPatchParams{
   666  			HTTPRequest: httptest.NewRequest("PATCH", "/v1/objects/123", nil),
   667  			ID:          "123",
   668  			Body: &models.Object{
   669  				Class:      "MyClass",
   670  				Properties: map[string]interface{}{"name": "hello world"},
   671  			},
   672  		}, nil)
   673  		if _, ok := res.(*objects.ObjectsClassPatchNoContent); !ok {
   674  			t.Errorf("unexpected result %v", res)
   675  		}
   676  	})
   677  
   678  	t.Run("GetObject", func(t *testing.T) {
   679  		cls := "MyClass"
   680  		type test struct {
   681  			name           string
   682  			object         *models.Object
   683  			err            error
   684  			expectedResult *models.Object
   685  		}
   686  
   687  		tests := []test{
   688  			{
   689  				name:           "without props - noaction changes",
   690  				object:         &models.Object{Class: cls, Properties: nil},
   691  				expectedResult: &models.Object{Class: cls, Properties: nil},
   692  			},
   693  			{
   694  				name: "without ref props - noaction changes",
   695  				object: &models.Object{Class: cls, Properties: map[string]interface{}{
   696  					"name":           "hello world",
   697  					"numericalField": 134,
   698  				}},
   699  				expectedResult: &models.Object{Class: cls, Properties: map[string]interface{}{
   700  					"name":           "hello world",
   701  					"numericalField": 134,
   702  				}},
   703  			},
   704  			{
   705  				name: "with a ref prop - no origin configured",
   706  				object: &models.Object{Class: cls, Properties: map[string]interface{}{
   707  					"name":           "hello world",
   708  					"numericalField": 134,
   709  					"someRef": models.MultipleRef{
   710  						&models.SingleRef{
   711  							Beacon: "weaviate://localhost/85f78e29-5937-4390-a121-5379f262b4e5",
   712  						},
   713  					},
   714  				}},
   715  				expectedResult: &models.Object{Class: cls, Properties: map[string]interface{}{
   716  					"name":           "hello world",
   717  					"numericalField": 134,
   718  					"someRef": models.MultipleRef{
   719  						&models.SingleRef{
   720  							Beacon: "weaviate://localhost/85f78e29-5937-4390-a121-5379f262b4e5",
   721  							Href:   "/v1/objects/85f78e29-5937-4390-a121-5379f262b4e5",
   722  						},
   723  					},
   724  				}},
   725  			},
   726  			{
   727  				name: "error forbidden",
   728  				err:  errors.NewForbidden(&models.Principal{}, "get", "Myclass/123"),
   729  			},
   730  			{
   731  				name: "use case err not found",
   732  				err:  uco.ErrNotFound{},
   733  			},
   734  			{
   735  				name: "any other error",
   736  				err:  stderrors.New("unknown error"),
   737  			},
   738  		}
   739  
   740  		for _, test := range tests {
   741  			t.Run(test.name, func(t *testing.T) {
   742  				fakeManager := &fakeManager{
   743  					getObjectReturn: test.object,
   744  					getObjectErr:    test.err,
   745  				}
   746  				h := &objectHandlers{manager: fakeManager, metricRequestsTotal: &fakeMetricRequestsTotal{}}
   747  				req := objects.ObjectsClassGetParams{
   748  					HTTPRequest: httptest.NewRequest("GET", "/v1/objects/MyClass/123", nil),
   749  					ClassName:   cls,
   750  					ID:          "123",
   751  				}
   752  				res := h.getObject(req, nil)
   753  				parsed, ok := res.(*objects.ObjectsClassGetOK)
   754  				if test.err != nil {
   755  					require.False(t, ok)
   756  					return
   757  				}
   758  				require.True(t, ok)
   759  				assert.Equal(t, test.expectedResult, parsed.Payload)
   760  			})
   761  		}
   762  	})
   763  
   764  	t.Run("DeleteObject", func(t *testing.T) {
   765  		cls := "MyClass"
   766  		type test struct {
   767  			name string
   768  			err  error
   769  		}
   770  
   771  		tests := []test{
   772  			{
   773  				name: "without props - noaction changes",
   774  			},
   775  			{
   776  				name: "error forbidden",
   777  				err:  errors.NewForbidden(&models.Principal{}, "get", "Myclass/123"),
   778  			},
   779  			{
   780  				name: "use case err not found",
   781  				err:  uco.ErrNotFound{},
   782  			},
   783  			{
   784  				name: "unknown error",
   785  				err:  stderrors.New("any error"),
   786  			},
   787  		}
   788  
   789  		for _, test := range tests {
   790  			t.Run(test.name, func(t *testing.T) {
   791  				fakeManager := &fakeManager{
   792  					deleteObjectReturn: test.err,
   793  				}
   794  				h := &objectHandlers{manager: fakeManager, metricRequestsTotal: &fakeMetricRequestsTotal{}}
   795  				req := objects.ObjectsClassDeleteParams{
   796  					HTTPRequest: httptest.NewRequest("GET", "/v1/objects/MyClass/123", nil),
   797  					ClassName:   cls,
   798  					ID:          "123",
   799  				}
   800  				res := h.deleteObject(req, nil)
   801  				_, ok := res.(*objects.ObjectsClassDeleteNoContent)
   802  				if test.err != nil {
   803  					require.False(t, ok)
   804  					return
   805  				}
   806  				require.True(t, ok)
   807  			})
   808  		}
   809  	})
   810  
   811  	t.Run("HeadObject", func(t *testing.T) {
   812  		m := &fakeManager{
   813  			headObjectReturn: true,
   814  		}
   815  		h := &objectHandlers{manager: m, logger: &logrus.Logger{}, metricRequestsTotal: &fakeMetricRequestsTotal{}}
   816  		req := objects.ObjectsClassHeadParams{
   817  			HTTPRequest: httptest.NewRequest("HEAD", "/v1/objects/MyClass/123", nil),
   818  			ClassName:   "MyClass",
   819  			ID:          "123",
   820  		}
   821  		res := h.headObject(req, nil)
   822  		if _, ok := res.(*objects.ObjectsClassHeadNoContent); !ok {
   823  			t.Errorf("unexpected result %v", res)
   824  		}
   825  
   826  		m.headObjectErr = &uco.Error{Code: uco.StatusForbidden}
   827  		res = h.headObject(req, nil)
   828  		if _, ok := res.(*objects.ObjectsClassHeadForbidden); !ok {
   829  			t.Errorf("expected: %T got: %T", objects.ObjectsClassHeadForbidden{}, res)
   830  		}
   831  		m.headObjectErr = &uco.Error{Code: uco.StatusInternalServerError}
   832  		res = h.headObject(req, nil)
   833  		if _, ok := res.(*objects.ObjectsClassHeadInternalServerError); !ok {
   834  			t.Errorf("expected: %T got: %T", objects.ObjectsClassHeadInternalServerError{}, res)
   835  		}
   836  		m.headObjectErr = nil
   837  		m.headObjectReturn = false
   838  		res = h.headObject(req, nil)
   839  		if _, ok := res.(*objects.ObjectsClassHeadNotFound); !ok {
   840  			t.Errorf("expected: %T got: %T", objects.ObjectsClassHeadNotFound{}, res)
   841  		}
   842  		// same test as before but using old request
   843  		oldRequest := objects.ObjectsHeadParams{HTTPRequest: req.HTTPRequest}
   844  		res = h.headObjectDeprecated(oldRequest, nil)
   845  		if _, ok := res.(*objects.ObjectsClassHeadNotFound); !ok {
   846  			t.Errorf("expected: %T got: %T", objects.ObjectsClassHeadNotFound{}, res)
   847  		}
   848  	})
   849  
   850  	t.Run("PostReference", func(t *testing.T) {
   851  		m := &fakeManager{}
   852  		h := &objectHandlers{manager: m, logger: &logrus.Logger{}, metricRequestsTotal: &fakeMetricRequestsTotal{}}
   853  		req := objects.ObjectsClassReferencesCreateParams{
   854  			HTTPRequest:  httptest.NewRequest("HEAD", "/v1/objects/MyClass/123/references/prop", nil),
   855  			ClassName:    "MyClass",
   856  			ID:           "123",
   857  			Body:         new(models.SingleRef),
   858  			PropertyName: "prop",
   859  		}
   860  		res := h.addObjectReference(req, nil)
   861  		if _, ok := res.(*objects.ObjectsClassReferencesCreateOK); !ok {
   862  			t.Errorf("unexpected result %v", res)
   863  		}
   864  
   865  		m.addRefErr = &uco.Error{Code: uco.StatusForbidden}
   866  		res = h.addObjectReference(req, nil)
   867  		if _, ok := res.(*objects.ObjectsClassReferencesCreateForbidden); !ok {
   868  			t.Errorf("expected: %T got: %T", objects.ObjectsClassReferencesCreateForbidden{}, res)
   869  		}
   870  		// source object not found
   871  		m.addRefErr = &uco.Error{Code: uco.StatusNotFound}
   872  		res = h.addObjectReference(req, nil)
   873  		if _, ok := res.(*objects.ObjectsClassReferencesCreateNotFound); !ok {
   874  			t.Errorf("expected: %T got: %T", objects.ObjectsClassReferencesCreateNotFound{}, res)
   875  		}
   876  
   877  		m.addRefErr = &uco.Error{Code: uco.StatusInternalServerError}
   878  		res = h.addObjectReference(req, nil)
   879  		if _, ok := res.(*objects.ObjectsClassReferencesCreateInternalServerError); !ok {
   880  			t.Errorf("expected: %T got: %T", objects.ObjectsClassReferencesCreateInternalServerError{}, res)
   881  		}
   882  		m.addRefErr = &uco.Error{Code: uco.StatusBadRequest}
   883  		res = h.addObjectReference(req, nil)
   884  		if _, ok := res.(*objects.ObjectsClassReferencesCreateUnprocessableEntity); !ok {
   885  			t.Errorf("expected: %T got: %T", objects.ObjectsClassReferencesCreateUnprocessableEntity{}, res)
   886  		}
   887  		// same test as before but using old request
   888  		oldRequest := objects.ObjectsReferencesCreateParams{
   889  			HTTPRequest:  req.HTTPRequest,
   890  			Body:         req.Body,
   891  			ID:           req.ID,
   892  			PropertyName: req.ClassName,
   893  		}
   894  		res = h.addObjectReferenceDeprecated(oldRequest, nil)
   895  		if _, ok := res.(*objects.ObjectsClassReferencesCreateUnprocessableEntity); !ok {
   896  			t.Errorf("expected: %T got: %T", objects.ObjectsClassReferencesCreateUnprocessableEntity{}, res)
   897  		}
   898  	})
   899  
   900  	t.Run("PutReferences", func(t *testing.T) {
   901  		m := &fakeManager{}
   902  		h := &objectHandlers{manager: m, logger: &logrus.Logger{}, metricRequestsTotal: &fakeMetricRequestsTotal{}}
   903  		req := objects.ObjectsClassReferencesPutParams{
   904  			HTTPRequest:  httptest.NewRequest("HEAD", "/v1/objects/MyClass/123/references/prop", nil),
   905  			ClassName:    "MyClass",
   906  			ID:           "123",
   907  			Body:         models.MultipleRef{},
   908  			PropertyName: "prop",
   909  		}
   910  		res := h.putObjectReferences(req, nil)
   911  		if _, ok := res.(*objects.ObjectsClassReferencesPutOK); !ok {
   912  			t.Errorf("unexpected result %v", res)
   913  		}
   914  
   915  		m.putRefErr = &uco.Error{Code: uco.StatusForbidden}
   916  		res = h.putObjectReferences(req, nil)
   917  		if _, ok := res.(*objects.ObjectsClassReferencesPutForbidden); !ok {
   918  			t.Errorf("expected: %T got: %T", objects.ObjectsClassReferencesPutForbidden{}, res)
   919  		}
   920  		m.putRefErr = &uco.Error{Code: uco.StatusInternalServerError}
   921  		res = h.putObjectReferences(req, nil)
   922  		if _, ok := res.(*objects.ObjectsClassReferencesPutInternalServerError); !ok {
   923  			t.Errorf("expected: %T got: %T", objects.ObjectsClassReferencesPutInternalServerError{}, res)
   924  		}
   925  		m.putRefErr = &uco.Error{Code: uco.StatusBadRequest}
   926  		res = h.putObjectReferences(req, nil)
   927  		if _, ok := res.(*objects.ObjectsClassReferencesPutUnprocessableEntity); !ok {
   928  			t.Errorf("expected: %T got: %T", objects.ObjectsClassReferencesPutUnprocessableEntity{}, res)
   929  		}
   930  		// same test as before but using old request
   931  		oldRequest := objects.ObjectsReferencesUpdateParams{
   932  			HTTPRequest:  req.HTTPRequest,
   933  			Body:         req.Body,
   934  			ID:           req.ID,
   935  			PropertyName: req.ClassName,
   936  		}
   937  		res = h.updateObjectReferencesDeprecated(oldRequest, nil)
   938  		if _, ok := res.(*objects.ObjectsClassReferencesPutUnprocessableEntity); !ok {
   939  			t.Errorf("expected: %T got: %T", objects.ObjectsClassReferencesPutUnprocessableEntity{}, res)
   940  		}
   941  	})
   942  
   943  	t.Run("DeleteReference", func(t *testing.T) {
   944  		m := &fakeManager{}
   945  		h := &objectHandlers{manager: m, logger: &logrus.Logger{}, metricRequestsTotal: &fakeMetricRequestsTotal{}}
   946  		req := objects.ObjectsClassReferencesDeleteParams{
   947  			HTTPRequest:  httptest.NewRequest("HEAD", "/v1/objects/MyClass/123/references/prop", nil),
   948  			ClassName:    "MyClass",
   949  			ID:           "123",
   950  			Body:         new(models.SingleRef),
   951  			PropertyName: "prop",
   952  		}
   953  		res := h.deleteObjectReference(req, nil)
   954  		if _, ok := res.(*objects.ObjectsClassReferencesDeleteNoContent); !ok {
   955  			t.Errorf("unexpected result %v", res)
   956  		}
   957  
   958  		m.deleteRefErr = &uco.Error{Code: uco.StatusForbidden}
   959  		res = h.deleteObjectReference(req, nil)
   960  		if _, ok := res.(*objects.ObjectsClassReferencesDeleteForbidden); !ok {
   961  			t.Errorf("expected: %T got: %T", objects.ObjectsClassReferencesDeleteForbidden{}, res)
   962  		}
   963  		// source object not found
   964  		m.deleteRefErr = &uco.Error{Code: uco.StatusNotFound}
   965  		res = h.deleteObjectReference(req, nil)
   966  		if _, ok := res.(*objects.ObjectsClassReferencesDeleteNotFound); !ok {
   967  			t.Errorf("expected: %T got: %T", objects.ObjectsClassReferencesDeleteNotFound{}, res)
   968  		}
   969  
   970  		m.deleteRefErr = &uco.Error{Code: uco.StatusInternalServerError}
   971  		res = h.deleteObjectReference(req, nil)
   972  		if _, ok := res.(*objects.ObjectsClassReferencesDeleteInternalServerError); !ok {
   973  			t.Errorf("expected: %T got: %T", objects.ObjectsClassReferencesDeleteInternalServerError{}, res)
   974  		}
   975  		m.deleteRefErr = &uco.Error{Code: uco.StatusBadRequest}
   976  		res = h.deleteObjectReference(req, nil)
   977  		if _, ok := res.(*objects.ObjectsClassReferencesDeleteUnprocessableEntity); !ok {
   978  			t.Errorf("expected: %T got: %T", objects.ObjectsClassReferencesDeleteUnprocessableEntity{}, res)
   979  		}
   980  		// same test as before but using old request
   981  		oldRequest := objects.ObjectsReferencesDeleteParams{
   982  			HTTPRequest:  req.HTTPRequest,
   983  			Body:         req.Body,
   984  			ID:           req.ID,
   985  			PropertyName: req.ClassName,
   986  		}
   987  		res = h.deleteObjectReferenceDeprecated(oldRequest, nil)
   988  		if _, ok := res.(*objects.ObjectsClassReferencesDeleteUnprocessableEntity); !ok {
   989  			t.Errorf("expected: %T got: %T", objects.ObjectsClassReferencesDeleteUnprocessableEntity{}, res)
   990  		}
   991  	})
   992  
   993  	t.Run("Query", func(t *testing.T) {
   994  		var (
   995  			cls = "MyClass"
   996  			m   = &fakeManager{
   997  				queryErr: nil,
   998  				queryResult: []*models.Object{{
   999  					Properties: map[string]interface{}{"name": "John"},
  1000  				}},
  1001  			}
  1002  			fakeMetricRequestsTotal = &fakeMetricRequestsTotal{}
  1003  			h                       = &objectHandlers{
  1004  				manager:             m,
  1005  				logger:              &logrus.Logger{},
  1006  				metricRequestsTotal: fakeMetricRequestsTotal,
  1007  			}
  1008  			req = objects.ObjectsListParams{
  1009  				HTTPRequest: httptest.NewRequest("HEAD", "/v1/objects/", nil),
  1010  				Class:       &cls,
  1011  			}
  1012  		)
  1013  
  1014  		res := h.query(req, nil)
  1015  		if _, ok := res.(*objects.ObjectsListOK); !ok {
  1016  			t.Errorf("unexpected result %v", res)
  1017  		}
  1018  
  1019  		m.queryErr = &uco.Error{Code: uco.StatusForbidden}
  1020  		res = h.query(req, nil)
  1021  		if _, ok := res.(*objects.ObjectsListForbidden); !ok {
  1022  			t.Errorf("expected: %T got: %T", objects.ObjectsListForbidden{}, res)
  1023  		}
  1024  		m.queryErr = &uco.Error{Code: uco.StatusNotFound}
  1025  		res = h.query(req, nil)
  1026  		if _, ok := res.(*objects.ObjectsListNotFound); !ok {
  1027  			t.Errorf("expected: %T got: %T", objects.ObjectsListNotFound{}, res)
  1028  		}
  1029  		m.queryErr = &uco.Error{Code: uco.StatusBadRequest}
  1030  		res = h.query(req, nil)
  1031  		if _, ok := res.(*objects.ObjectsListUnprocessableEntity); !ok {
  1032  			t.Errorf("expected: %T got: %T", objects.ObjectsListUnprocessableEntity{}, res)
  1033  		}
  1034  		m.queryErr = &uco.Error{Code: uco.StatusInternalServerError}
  1035  		res = h.query(req, nil)
  1036  		if _, ok := res.(*objects.ObjectsListInternalServerError); !ok {
  1037  			t.Errorf("expected: %T got: %T", objects.ObjectsListInternalServerError{}, res)
  1038  		}
  1039  	})
  1040  }
  1041  
  1042  type fakeManager struct {
  1043  	getObjectReturn *models.Object
  1044  	getObjectErr    error
  1045  
  1046  	addObjectReturn    *models.Object
  1047  	queryResult        []*models.Object
  1048  	queryErr           *uco.Error
  1049  	updateObjectReturn *models.Object
  1050  	updateObjectErr    error
  1051  	deleteObjectReturn error
  1052  	patchObjectReturn  *uco.Error
  1053  	headObjectReturn   bool
  1054  	headObjectErr      *uco.Error
  1055  	addRefErr          *uco.Error
  1056  	putRefErr          *uco.Error
  1057  	deleteRefErr       *uco.Error
  1058  }
  1059  
  1060  func (f *fakeManager) HeadObject(context.Context, *models.Principal,
  1061  	string, strfmt.UUID, *additional.ReplicationProperties, string,
  1062  ) (bool, *uco.Error) {
  1063  	return f.headObjectReturn, f.headObjectErr
  1064  }
  1065  
  1066  func (f *fakeManager) AddObject(_ context.Context, _ *models.Principal,
  1067  	object *models.Object, _ *additional.ReplicationProperties,
  1068  ) (*models.Object, error) {
  1069  	return object, nil
  1070  }
  1071  
  1072  func (f *fakeManager) ValidateObject(_ context.Context, _ *models.Principal,
  1073  	_ *models.Object, _ *additional.ReplicationProperties,
  1074  ) error {
  1075  	panic("not implemented") // TODO: Implement
  1076  }
  1077  
  1078  func (f *fakeManager) GetObject(_ context.Context, _ *models.Principal, class string,
  1079  	_ strfmt.UUID, _ additional.Properties, _ *additional.ReplicationProperties, _ string,
  1080  ) (*models.Object, error) {
  1081  	return f.getObjectReturn, f.getObjectErr
  1082  }
  1083  
  1084  func (f *fakeManager) GetObjectsClass(ctx context.Context,
  1085  	principal *models.Principal, id strfmt.UUID,
  1086  ) (*models.Class, error) {
  1087  	class := &models.Class{
  1088  		Class:      f.getObjectReturn.Class,
  1089  		Vectorizer: "text2vec-contextionary",
  1090  	}
  1091  	return class, nil
  1092  }
  1093  
  1094  func (f *fakeManager) GetObjectClassFromName(ctx context.Context, principal *models.Principal,
  1095  	className string,
  1096  ) (*models.Class, error) {
  1097  	class := &models.Class{
  1098  		Class:      f.getObjectReturn.Class,
  1099  		Vectorizer: "text2vec-contextionary",
  1100  	}
  1101  	return class, nil
  1102  }
  1103  
  1104  func (f *fakeManager) GetObjects(ctx context.Context, principal *models.Principal, offset *int64, limit *int64, sort *string, order *string, after *string, addl additional.Properties, tenant string) ([]*models.Object, error) {
  1105  	return f.queryResult, nil
  1106  }
  1107  
  1108  func (f *fakeManager) Query(_ context.Context,
  1109  	_ *models.Principal, _ *uco.QueryParams,
  1110  ) ([]*models.Object, *uco.Error) {
  1111  	return f.queryResult, f.queryErr
  1112  }
  1113  
  1114  func (f *fakeManager) UpdateObject(_ context.Context, _ *models.Principal, _ string,
  1115  	_ strfmt.UUID, updates *models.Object, _ *additional.ReplicationProperties,
  1116  ) (*models.Object, error) {
  1117  	return updates, f.updateObjectErr
  1118  }
  1119  
  1120  func (f *fakeManager) MergeObject(_ context.Context, _ *models.Principal,
  1121  	_ *models.Object, _ *additional.ReplicationProperties,
  1122  ) *uco.Error {
  1123  	return f.patchObjectReturn
  1124  }
  1125  
  1126  func (f *fakeManager) DeleteObject(_ context.Context, _ *models.Principal,
  1127  	class string, _ strfmt.UUID, _ *additional.ReplicationProperties, _ string,
  1128  ) error {
  1129  	return f.deleteObjectReturn
  1130  }
  1131  
  1132  func (f *fakeManager) AddObjectReference(context.Context, *models.Principal,
  1133  	*uco.AddReferenceInput, *additional.ReplicationProperties, string,
  1134  ) *uco.Error {
  1135  	return f.addRefErr
  1136  }
  1137  
  1138  func (f *fakeManager) UpdateObjectReferences(context.Context, *models.Principal,
  1139  	*uco.PutReferenceInput, *additional.ReplicationProperties, string,
  1140  ) *uco.Error {
  1141  	return f.putRefErr
  1142  }
  1143  
  1144  func (f *fakeManager) DeleteObjectReference(context.Context, *models.Principal,
  1145  	*uco.DeleteReferenceInput, *additional.ReplicationProperties, string,
  1146  ) *uco.Error {
  1147  	return f.deleteRefErr
  1148  }
  1149  
  1150  type fakeMetricRequestsTotal struct{}
  1151  
  1152  func (f *fakeMetricRequestsTotal) logError(className string, err error)       {}
  1153  func (f *fakeMetricRequestsTotal) logOk(className string)                     {}
  1154  func (f *fakeMetricRequestsTotal) logUserError(className string)              {}
  1155  func (f *fakeMetricRequestsTotal) logServerError(className string, err error) {}