Spaces:
Running
Running
// _ _ | |
// __ _____ __ ___ ___ __ _| |_ ___ | |
// \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ | |
// \ V V / __/ (_| |\ V /| | (_| | || __/ | |
// \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| | |
// | |
// Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. | |
// | |
// CONTACT: [email protected] | |
// | |
package v1 | |
import ( | |
"errors" | |
"fmt" | |
"testing" | |
"github.com/stretchr/testify/require" | |
"github.com/weaviate/weaviate/entities/filters" | |
"github.com/weaviate/weaviate/entities/models" | |
"github.com/weaviate/weaviate/entities/schema" | |
pb "github.com/weaviate/weaviate/grpc/generated/protocol/v1" | |
"github.com/weaviate/weaviate/usecases/objects" | |
) | |
func TestBatchDeleteRequest(t *testing.T) { | |
collection := "TestClass" | |
scheme := schema.Schema{ | |
Objects: &models.Schema{ | |
Classes: []*models.Class{ | |
{ | |
Class: collection, | |
Properties: []*models.Property{ | |
{Name: "name", DataType: schema.DataTypeText.PropString()}, | |
}, | |
}, | |
}, | |
}, | |
} | |
simpleFilterOutput := &filters.LocalFilter{ | |
Root: &filters.Clause{ | |
On: &filters.Path{Class: schema.ClassName(collection), Property: "name"}, | |
Operator: filters.OperatorEqual, | |
Value: &filters.Value{Value: "test", Type: schema.DataTypeText}, | |
}, | |
} | |
simpleFilterInput := &pb.Filters{Operator: pb.Filters_OPERATOR_EQUAL, TestValue: &pb.Filters_ValueText{ValueText: "test"}, Target: &pb.FilterTarget{Target: &pb.FilterTarget_Property{Property: "name"}}} | |
tests := []struct { | |
name string | |
req *pb.BatchDeleteRequest | |
out objects.BatchDeleteParams | |
error error | |
}{ | |
{ | |
name: "simple filter", | |
req: &pb.BatchDeleteRequest{ | |
Collection: collection, | |
Filters: simpleFilterInput, | |
}, | |
out: objects.BatchDeleteParams{ | |
ClassName: schema.ClassName(collection), | |
DryRun: false, | |
Output: "minimal", | |
Filters: simpleFilterOutput, | |
}, | |
error: nil, | |
}, | |
{ | |
name: "collection does not exist", | |
req: &pb.BatchDeleteRequest{Collection: "does not exist"}, | |
error: errors.New("no such class with name 'does not exist' found in the schema. Check your schema files for which classes are available"), | |
}, | |
{ | |
name: "no filter", | |
req: &pb.BatchDeleteRequest{Collection: collection}, | |
error: fmt.Errorf("no filters in batch delete request"), | |
}, | |
{ | |
name: "dry run", | |
req: &pb.BatchDeleteRequest{ | |
Collection: collection, | |
Filters: simpleFilterInput, | |
DryRun: true, | |
}, | |
out: objects.BatchDeleteParams{ | |
ClassName: schema.ClassName(collection), | |
DryRun: true, | |
Output: "minimal", | |
Filters: simpleFilterOutput, | |
}, | |
error: nil, | |
}, | |
{ | |
name: "verbose", | |
req: &pb.BatchDeleteRequest{ | |
Collection: collection, | |
Filters: simpleFilterInput, | |
DryRun: false, | |
Verbose: true, | |
}, | |
out: objects.BatchDeleteParams{ | |
ClassName: schema.ClassName(collection), | |
DryRun: false, | |
Output: "verbose", | |
Filters: simpleFilterOutput, | |
}, | |
error: nil, | |
}, | |
} | |
for _, tt := range tests { | |
t.Run(tt.name, func(t *testing.T) { | |
out, err := batchDeleteParamsFromProto(tt.req, scheme) | |
require.Equal(t, tt.error, err) | |
if tt.error == nil { | |
require.Equal(t, tt.out, out) | |
} | |
}) | |
} | |
} | |
var ( | |
errorString = "error" | |
noErrorString = "" | |
) | |
func TestBatchDeleteReply(t *testing.T) { | |
tests := []struct { | |
name string | |
response objects.BatchDeleteResult | |
verbose bool | |
out *pb.BatchDeleteReply | |
}{ | |
{ | |
name: "single object", | |
response: objects.BatchDeleteResult{Matches: 1, Objects: objects.BatchSimpleObjects{{UUID: UUID1, Err: nil}}}, | |
out: &pb.BatchDeleteReply{Matches: 1, Successful: 1, Failed: 0}, | |
}, | |
{ | |
name: "single object with err", | |
response: objects.BatchDeleteResult{Matches: 1, Objects: objects.BatchSimpleObjects{{UUID: UUID1, Err: errors.New("error")}}}, | |
out: &pb.BatchDeleteReply{Matches: 1, Successful: 0, Failed: 1}, | |
}, | |
{ | |
name: "one error, one successful", | |
response: objects.BatchDeleteResult{Matches: 2, Objects: objects.BatchSimpleObjects{{UUID: UUID1, Err: errors.New("error")}, {UUID: UUID2, Err: nil}}}, | |
out: &pb.BatchDeleteReply{Matches: 2, Successful: 1, Failed: 1}, | |
}, | |
{ | |
name: "one error, one successful - with verbosity", | |
response: objects.BatchDeleteResult{Matches: 2, Objects: objects.BatchSimpleObjects{{UUID: UUID1, Err: errors.New("error")}, {UUID: UUID2, Err: nil}}}, | |
verbose: true, | |
out: &pb.BatchDeleteReply{Matches: 2, Successful: 1, Failed: 1, Objects: []*pb.BatchDeleteObject{ | |
{Uuid: idByte(string(UUID1)), Successful: false, Error: &errorString}, | |
{Uuid: idByte(string(UUID2)), Successful: true, Error: &noErrorString}, | |
}}, | |
}, | |
} | |
for _, tt := range tests { | |
t.Run(tt.name, func(t *testing.T) { | |
out, err := batchDeleteReplyFromObjects(tt.response, tt.verbose) | |
require.Nil(t, err) | |
require.Equal(t, tt.out, out) | |
}) | |
} | |
} | |