// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Code generated by gapic-generator. DO NOT EDIT.

package vision

import (
	"context"
	"flag"
	"fmt"
	"io"
	"log"
	"net"
	"os"
	"strings"
	"testing"

	"github.com/golang/protobuf/proto"
	"github.com/golang/protobuf/ptypes"
	emptypb "github.com/golang/protobuf/ptypes/empty"
	"google.golang.org/api/option"
	visionpb "google.golang.org/genproto/googleapis/cloud/vision/v1"
	longrunningpb "google.golang.org/genproto/googleapis/longrunning"

	status "google.golang.org/genproto/googleapis/rpc/status"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/metadata"

	gstatus "google.golang.org/grpc/status"
)

var _ = io.EOF
var _ = ptypes.MarshalAny
var _ status.Status

type mockImageAnnotatorServer struct {
	// Embed for forward compatibility.
	// Tests will keep working if more methods are added
	// in the future.
	visionpb.ImageAnnotatorServer

	reqs []proto.Message

	// If set, all calls return this error.
	err error

	// responses to return if err == nil
	resps []proto.Message
}

func (s *mockImageAnnotatorServer) BatchAnnotateImages(ctx context.Context, req *visionpb.BatchAnnotateImagesRequest) (*visionpb.BatchAnnotateImagesResponse, error) {
	md, _ := metadata.FromIncomingContext(ctx)
	if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
		return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
	}
	s.reqs = append(s.reqs, req)
	if s.err != nil {
		return nil, s.err
	}
	return s.resps[0].(*visionpb.BatchAnnotateImagesResponse), nil
}

func (s *mockImageAnnotatorServer) BatchAnnotateFiles(ctx context.Context, req *visionpb.BatchAnnotateFilesRequest) (*visionpb.BatchAnnotateFilesResponse, error) {
	md, _ := metadata.FromIncomingContext(ctx)
	if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
		return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
	}
	s.reqs = append(s.reqs, req)
	if s.err != nil {
		return nil, s.err
	}
	return s.resps[0].(*visionpb.BatchAnnotateFilesResponse), nil
}

func (s *mockImageAnnotatorServer) AsyncBatchAnnotateImages(ctx context.Context, req *visionpb.AsyncBatchAnnotateImagesRequest) (*longrunningpb.Operation, error) {
	md, _ := metadata.FromIncomingContext(ctx)
	if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
		return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
	}
	s.reqs = append(s.reqs, req)
	if s.err != nil {
		return nil, s.err
	}
	return s.resps[0].(*longrunningpb.Operation), nil
}

func (s *mockImageAnnotatorServer) AsyncBatchAnnotateFiles(ctx context.Context, req *visionpb.AsyncBatchAnnotateFilesRequest) (*longrunningpb.Operation, error) {
	md, _ := metadata.FromIncomingContext(ctx)
	if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
		return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
	}
	s.reqs = append(s.reqs, req)
	if s.err != nil {
		return nil, s.err
	}
	return s.resps[0].(*longrunningpb.Operation), nil
}

type mockProductSearchServer struct {
	// Embed for forward compatibility.
	// Tests will keep working if more methods are added
	// in the future.
	visionpb.ProductSearchServer

	reqs []proto.Message

	// If set, all calls return this error.
	err error

	// responses to return if err == nil
	resps []proto.Message
}

func (s *mockProductSearchServer) CreateProductSet(ctx context.Context, req *visionpb.CreateProductSetRequest) (*visionpb.ProductSet, error) {
	md, _ := metadata.FromIncomingContext(ctx)
	if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
		return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
	}
	s.reqs = append(s.reqs, req)
	if s.err != nil {
		return nil, s.err
	}
	return s.resps[0].(*visionpb.ProductSet), nil
}

func (s *mockProductSearchServer) ListProductSets(ctx context.Context, req *visionpb.ListProductSetsRequest) (*visionpb.ListProductSetsResponse, error) {
	md, _ := metadata.FromIncomingContext(ctx)
	if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
		return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
	}
	s.reqs = append(s.reqs, req)
	if s.err != nil {
		return nil, s.err
	}
	return s.resps[0].(*visionpb.ListProductSetsResponse), nil
}

func (s *mockProductSearchServer) GetProductSet(ctx context.Context, req *visionpb.GetProductSetRequest) (*visionpb.ProductSet, error) {
	md, _ := metadata.FromIncomingContext(ctx)
	if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
		return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
	}
	s.reqs = append(s.reqs, req)
	if s.err != nil {
		return nil, s.err
	}
	return s.resps[0].(*visionpb.ProductSet), nil
}

func (s *mockProductSearchServer) UpdateProductSet(ctx context.Context, req *visionpb.UpdateProductSetRequest) (*visionpb.ProductSet, error) {
	md, _ := metadata.FromIncomingContext(ctx)
	if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
		return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
	}
	s.reqs = append(s.reqs, req)
	if s.err != nil {
		return nil, s.err
	}
	return s.resps[0].(*visionpb.ProductSet), nil
}

func (s *mockProductSearchServer) DeleteProductSet(ctx context.Context, req *visionpb.DeleteProductSetRequest) (*emptypb.Empty, error) {
	md, _ := metadata.FromIncomingContext(ctx)
	if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
		return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
	}
	s.reqs = append(s.reqs, req)
	if s.err != nil {
		return nil, s.err
	}
	return s.resps[0].(*emptypb.Empty), nil
}

func (s *mockProductSearchServer) CreateProduct(ctx context.Context, req *visionpb.CreateProductRequest) (*visionpb.Product, error) {
	md, _ := metadata.FromIncomingContext(ctx)
	if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
		return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
	}
	s.reqs = append(s.reqs, req)
	if s.err != nil {
		return nil, s.err
	}
	return s.resps[0].(*visionpb.Product), nil
}

func (s *mockProductSearchServer) ListProducts(ctx context.Context, req *visionpb.ListProductsRequest) (*visionpb.ListProductsResponse, error) {
	md, _ := metadata.FromIncomingContext(ctx)
	if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
		return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
	}
	s.reqs = append(s.reqs, req)
	if s.err != nil {
		return nil, s.err
	}
	return s.resps[0].(*visionpb.ListProductsResponse), nil
}

func (s *mockProductSearchServer) GetProduct(ctx context.Context, req *visionpb.GetProductRequest) (*visionpb.Product, error) {
	md, _ := metadata.FromIncomingContext(ctx)
	if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
		return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
	}
	s.reqs = append(s.reqs, req)
	if s.err != nil {
		return nil, s.err
	}
	return s.resps[0].(*visionpb.Product), nil
}

func (s *mockProductSearchServer) UpdateProduct(ctx context.Context, req *visionpb.UpdateProductRequest) (*visionpb.Product, error) {
	md, _ := metadata.FromIncomingContext(ctx)
	if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
		return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
	}
	s.reqs = append(s.reqs, req)
	if s.err != nil {
		return nil, s.err
	}
	return s.resps[0].(*visionpb.Product), nil
}

func (s *mockProductSearchServer) DeleteProduct(ctx context.Context, req *visionpb.DeleteProductRequest) (*emptypb.Empty, error) {
	md, _ := metadata.FromIncomingContext(ctx)
	if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
		return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
	}
	s.reqs = append(s.reqs, req)
	if s.err != nil {
		return nil, s.err
	}
	return s.resps[0].(*emptypb.Empty), nil
}

func (s *mockProductSearchServer) CreateReferenceImage(ctx context.Context, req *visionpb.CreateReferenceImageRequest) (*visionpb.ReferenceImage, error) {
	md, _ := metadata.FromIncomingContext(ctx)
	if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
		return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
	}
	s.reqs = append(s.reqs, req)
	if s.err != nil {
		return nil, s.err
	}
	return s.resps[0].(*visionpb.ReferenceImage), nil
}

func (s *mockProductSearchServer) DeleteReferenceImage(ctx context.Context, req *visionpb.DeleteReferenceImageRequest) (*emptypb.Empty, error) {
	md, _ := metadata.FromIncomingContext(ctx)
	if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
		return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
	}
	s.reqs = append(s.reqs, req)
	if s.err != nil {
		return nil, s.err
	}
	return s.resps[0].(*emptypb.Empty), nil
}

func (s *mockProductSearchServer) ListReferenceImages(ctx context.Context, req *visionpb.ListReferenceImagesRequest) (*visionpb.ListReferenceImagesResponse, error) {
	md, _ := metadata.FromIncomingContext(ctx)
	if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
		return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
	}
	s.reqs = append(s.reqs, req)
	if s.err != nil {
		return nil, s.err
	}
	return s.resps[0].(*visionpb.ListReferenceImagesResponse), nil
}

func (s *mockProductSearchServer) GetReferenceImage(ctx context.Context, req *visionpb.GetReferenceImageRequest) (*visionpb.ReferenceImage, error) {
	md, _ := metadata.FromIncomingContext(ctx)
	if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
		return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
	}
	s.reqs = append(s.reqs, req)
	if s.err != nil {
		return nil, s.err
	}
	return s.resps[0].(*visionpb.ReferenceImage), nil
}

func (s *mockProductSearchServer) AddProductToProductSet(ctx context.Context, req *visionpb.AddProductToProductSetRequest) (*emptypb.Empty, error) {
	md, _ := metadata.FromIncomingContext(ctx)
	if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
		return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
	}
	s.reqs = append(s.reqs, req)
	if s.err != nil {
		return nil, s.err
	}
	return s.resps[0].(*emptypb.Empty), nil
}

func (s *mockProductSearchServer) RemoveProductFromProductSet(ctx context.Context, req *visionpb.RemoveProductFromProductSetRequest) (*emptypb.Empty, error) {
	md, _ := metadata.FromIncomingContext(ctx)
	if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
		return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
	}
	s.reqs = append(s.reqs, req)
	if s.err != nil {
		return nil, s.err
	}
	return s.resps[0].(*emptypb.Empty), nil
}

func (s *mockProductSearchServer) ListProductsInProductSet(ctx context.Context, req *visionpb.ListProductsInProductSetRequest) (*visionpb.ListProductsInProductSetResponse, error) {
	md, _ := metadata.FromIncomingContext(ctx)
	if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
		return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
	}
	s.reqs = append(s.reqs, req)
	if s.err != nil {
		return nil, s.err
	}
	return s.resps[0].(*visionpb.ListProductsInProductSetResponse), nil
}

func (s *mockProductSearchServer) ImportProductSets(ctx context.Context, req *visionpb.ImportProductSetsRequest) (*longrunningpb.Operation, error) {
	md, _ := metadata.FromIncomingContext(ctx)
	if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
		return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
	}
	s.reqs = append(s.reqs, req)
	if s.err != nil {
		return nil, s.err
	}
	return s.resps[0].(*longrunningpb.Operation), nil
}

func (s *mockProductSearchServer) PurgeProducts(ctx context.Context, req *visionpb.PurgeProductsRequest) (*longrunningpb.Operation, error) {
	md, _ := metadata.FromIncomingContext(ctx)
	if xg := md["x-goog-api-client"]; len(xg) == 0 || !strings.Contains(xg[0], "gl-go/") {
		return nil, fmt.Errorf("x-goog-api-client = %v, expected gl-go key", xg)
	}
	s.reqs = append(s.reqs, req)
	if s.err != nil {
		return nil, s.err
	}
	return s.resps[0].(*longrunningpb.Operation), nil
}

// clientOpt is the option tests should use to connect to the test server.
// It is initialized by TestMain.
var clientOpt option.ClientOption

var (
	mockImageAnnotator mockImageAnnotatorServer
	mockProductSearch  mockProductSearchServer
)

func TestMain(m *testing.M) {
	flag.Parse()

	serv := grpc.NewServer()
	visionpb.RegisterImageAnnotatorServer(serv, &mockImageAnnotator)
	visionpb.RegisterProductSearchServer(serv, &mockProductSearch)

	lis, err := net.Listen("tcp", "localhost:0")
	if err != nil {
		log.Fatal(err)
	}
	go serv.Serve(lis)

	conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure())
	if err != nil {
		log.Fatal(err)
	}
	clientOpt = option.WithGRPCConn(conn)

	os.Exit(m.Run())
}

func TestImageAnnotatorBatchAnnotateImages(t *testing.T) {
	var expectedResponse *visionpb.BatchAnnotateImagesResponse = &visionpb.BatchAnnotateImagesResponse{}

	mockImageAnnotator.err = nil
	mockImageAnnotator.reqs = nil

	mockImageAnnotator.resps = append(mockImageAnnotator.resps[:0], expectedResponse)

	var requests []*visionpb.AnnotateImageRequest = nil
	var request = &visionpb.BatchAnnotateImagesRequest{
		Requests: requests,
	}

	c, err := NewImageAnnotatorClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := c.BatchAnnotateImages(context.Background(), request)

	if err != nil {
		t.Fatal(err)
	}

	if want, got := request, mockImageAnnotator.reqs[0]; !proto.Equal(want, got) {
		t.Errorf("wrong request %q, want %q", got, want)
	}

	if want, got := expectedResponse, resp; !proto.Equal(want, got) {
		t.Errorf("wrong response %q, want %q)", got, want)
	}
}

func TestImageAnnotatorBatchAnnotateImagesError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockImageAnnotator.err = gstatus.Error(errCode, "test error")

	var requests []*visionpb.AnnotateImageRequest = nil
	var request = &visionpb.BatchAnnotateImagesRequest{
		Requests: requests,
	}

	c, err := NewImageAnnotatorClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := c.BatchAnnotateImages(context.Background(), request)

	if st, ok := gstatus.FromError(err); !ok {
		t.Errorf("got error %v, expected grpc error", err)
	} else if c := st.Code(); c != errCode {
		t.Errorf("got error code %q, want %q", c, errCode)
	}
	_ = resp
}
func TestImageAnnotatorBatchAnnotateFiles(t *testing.T) {
	var expectedResponse *visionpb.BatchAnnotateFilesResponse = &visionpb.BatchAnnotateFilesResponse{}

	mockImageAnnotator.err = nil
	mockImageAnnotator.reqs = nil

	mockImageAnnotator.resps = append(mockImageAnnotator.resps[:0], expectedResponse)

	var requests []*visionpb.AnnotateFileRequest = nil
	var request = &visionpb.BatchAnnotateFilesRequest{
		Requests: requests,
	}

	c, err := NewImageAnnotatorClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := c.BatchAnnotateFiles(context.Background(), request)

	if err != nil {
		t.Fatal(err)
	}

	if want, got := request, mockImageAnnotator.reqs[0]; !proto.Equal(want, got) {
		t.Errorf("wrong request %q, want %q", got, want)
	}

	if want, got := expectedResponse, resp; !proto.Equal(want, got) {
		t.Errorf("wrong response %q, want %q)", got, want)
	}
}

func TestImageAnnotatorBatchAnnotateFilesError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockImageAnnotator.err = gstatus.Error(errCode, "test error")

	var requests []*visionpb.AnnotateFileRequest = nil
	var request = &visionpb.BatchAnnotateFilesRequest{
		Requests: requests,
	}

	c, err := NewImageAnnotatorClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := c.BatchAnnotateFiles(context.Background(), request)

	if st, ok := gstatus.FromError(err); !ok {
		t.Errorf("got error %v, expected grpc error", err)
	} else if c := st.Code(); c != errCode {
		t.Errorf("got error code %q, want %q", c, errCode)
	}
	_ = resp
}
func TestImageAnnotatorAsyncBatchAnnotateImages(t *testing.T) {
	var expectedResponse *visionpb.AsyncBatchAnnotateImagesResponse = &visionpb.AsyncBatchAnnotateImagesResponse{}

	mockImageAnnotator.err = nil
	mockImageAnnotator.reqs = nil

	any, err := ptypes.MarshalAny(expectedResponse)
	if err != nil {
		t.Fatal(err)
	}
	mockImageAnnotator.resps = append(mockImageAnnotator.resps[:0], &longrunningpb.Operation{
		Name:   "longrunning-test",
		Done:   true,
		Result: &longrunningpb.Operation_Response{Response: any},
	})

	var requests []*visionpb.AnnotateImageRequest = nil
	var outputConfig *visionpb.OutputConfig = &visionpb.OutputConfig{}
	var request = &visionpb.AsyncBatchAnnotateImagesRequest{
		Requests:     requests,
		OutputConfig: outputConfig,
	}

	c, err := NewImageAnnotatorClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	respLRO, err := c.AsyncBatchAnnotateImages(context.Background(), request)
	if err != nil {
		t.Fatal(err)
	}
	resp, err := respLRO.Wait(context.Background())

	if err != nil {
		t.Fatal(err)
	}

	if want, got := request, mockImageAnnotator.reqs[0]; !proto.Equal(want, got) {
		t.Errorf("wrong request %q, want %q", got, want)
	}

	if want, got := expectedResponse, resp; !proto.Equal(want, got) {
		t.Errorf("wrong response %q, want %q)", got, want)
	}
}

func TestImageAnnotatorAsyncBatchAnnotateImagesError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockImageAnnotator.err = nil
	mockImageAnnotator.resps = append(mockImageAnnotator.resps[:0], &longrunningpb.Operation{
		Name: "longrunning-test",
		Done: true,
		Result: &longrunningpb.Operation_Error{
			Error: &status.Status{
				Code:    int32(errCode),
				Message: "test error",
			},
		},
	})

	var requests []*visionpb.AnnotateImageRequest = nil
	var outputConfig *visionpb.OutputConfig = &visionpb.OutputConfig{}
	var request = &visionpb.AsyncBatchAnnotateImagesRequest{
		Requests:     requests,
		OutputConfig: outputConfig,
	}

	c, err := NewImageAnnotatorClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	respLRO, err := c.AsyncBatchAnnotateImages(context.Background(), request)
	if err != nil {
		t.Fatal(err)
	}
	resp, err := respLRO.Wait(context.Background())

	if st, ok := gstatus.FromError(err); !ok {
		t.Errorf("got error %v, expected grpc error", err)
	} else if c := st.Code(); c != errCode {
		t.Errorf("got error code %q, want %q", c, errCode)
	}
	_ = resp
}
func TestImageAnnotatorAsyncBatchAnnotateFiles(t *testing.T) {
	var expectedResponse *visionpb.AsyncBatchAnnotateFilesResponse = &visionpb.AsyncBatchAnnotateFilesResponse{}

	mockImageAnnotator.err = nil
	mockImageAnnotator.reqs = nil

	any, err := ptypes.MarshalAny(expectedResponse)
	if err != nil {
		t.Fatal(err)
	}
	mockImageAnnotator.resps = append(mockImageAnnotator.resps[:0], &longrunningpb.Operation{
		Name:   "longrunning-test",
		Done:   true,
		Result: &longrunningpb.Operation_Response{Response: any},
	})

	var requests []*visionpb.AsyncAnnotateFileRequest = nil
	var request = &visionpb.AsyncBatchAnnotateFilesRequest{
		Requests: requests,
	}

	c, err := NewImageAnnotatorClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	respLRO, err := c.AsyncBatchAnnotateFiles(context.Background(), request)
	if err != nil {
		t.Fatal(err)
	}
	resp, err := respLRO.Wait(context.Background())

	if err != nil {
		t.Fatal(err)
	}

	if want, got := request, mockImageAnnotator.reqs[0]; !proto.Equal(want, got) {
		t.Errorf("wrong request %q, want %q", got, want)
	}

	if want, got := expectedResponse, resp; !proto.Equal(want, got) {
		t.Errorf("wrong response %q, want %q)", got, want)
	}
}

func TestImageAnnotatorAsyncBatchAnnotateFilesError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockImageAnnotator.err = nil
	mockImageAnnotator.resps = append(mockImageAnnotator.resps[:0], &longrunningpb.Operation{
		Name: "longrunning-test",
		Done: true,
		Result: &longrunningpb.Operation_Error{
			Error: &status.Status{
				Code:    int32(errCode),
				Message: "test error",
			},
		},
	})

	var requests []*visionpb.AsyncAnnotateFileRequest = nil
	var request = &visionpb.AsyncBatchAnnotateFilesRequest{
		Requests: requests,
	}

	c, err := NewImageAnnotatorClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	respLRO, err := c.AsyncBatchAnnotateFiles(context.Background(), request)
	if err != nil {
		t.Fatal(err)
	}
	resp, err := respLRO.Wait(context.Background())

	if st, ok := gstatus.FromError(err); !ok {
		t.Errorf("got error %v, expected grpc error", err)
	} else if c := st.Code(); c != errCode {
		t.Errorf("got error code %q, want %q", c, errCode)
	}
	_ = resp
}
func TestProductSearchCreateProductSet(t *testing.T) {
	var name string = "name3373707"
	var displayName string = "displayName1615086568"
	var expectedResponse = &visionpb.ProductSet{
		Name:        name,
		DisplayName: displayName,
	}

	mockProductSearch.err = nil
	mockProductSearch.reqs = nil

	mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse)

	var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]")
	var productSet *visionpb.ProductSet = &visionpb.ProductSet{}
	var request = &visionpb.CreateProductSetRequest{
		Parent:     formattedParent,
		ProductSet: productSet,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := c.CreateProductSet(context.Background(), request)

	if err != nil {
		t.Fatal(err)
	}

	if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) {
		t.Errorf("wrong request %q, want %q", got, want)
	}

	if want, got := expectedResponse, resp; !proto.Equal(want, got) {
		t.Errorf("wrong response %q, want %q)", got, want)
	}
}

func TestProductSearchCreateProductSetError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockProductSearch.err = gstatus.Error(errCode, "test error")

	var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]")
	var productSet *visionpb.ProductSet = &visionpb.ProductSet{}
	var request = &visionpb.CreateProductSetRequest{
		Parent:     formattedParent,
		ProductSet: productSet,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := c.CreateProductSet(context.Background(), request)

	if st, ok := gstatus.FromError(err); !ok {
		t.Errorf("got error %v, expected grpc error", err)
	} else if c := st.Code(); c != errCode {
		t.Errorf("got error code %q, want %q", c, errCode)
	}
	_ = resp
}
func TestProductSearchListProductSets(t *testing.T) {
	var nextPageToken string = ""
	var productSetsElement *visionpb.ProductSet = &visionpb.ProductSet{}
	var productSets = []*visionpb.ProductSet{productSetsElement}
	var expectedResponse = &visionpb.ListProductSetsResponse{
		NextPageToken: nextPageToken,
		ProductSets:   productSets,
	}

	mockProductSearch.err = nil
	mockProductSearch.reqs = nil

	mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse)

	var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]")
	var request = &visionpb.ListProductSetsRequest{
		Parent: formattedParent,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := c.ListProductSets(context.Background(), request).Next()

	if err != nil {
		t.Fatal(err)
	}

	if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) {
		t.Errorf("wrong request %q, want %q", got, want)
	}

	want := (interface{})(expectedResponse.ProductSets[0])
	got := (interface{})(resp)
	var ok bool

	switch want := (want).(type) {
	case proto.Message:
		ok = proto.Equal(want, got.(proto.Message))
	default:
		ok = want == got
	}
	if !ok {
		t.Errorf("wrong response %q, want %q)", got, want)
	}
}

func TestProductSearchListProductSetsError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockProductSearch.err = gstatus.Error(errCode, "test error")

	var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]")
	var request = &visionpb.ListProductSetsRequest{
		Parent: formattedParent,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := c.ListProductSets(context.Background(), request).Next()

	if st, ok := gstatus.FromError(err); !ok {
		t.Errorf("got error %v, expected grpc error", err)
	} else if c := st.Code(); c != errCode {
		t.Errorf("got error code %q, want %q", c, errCode)
	}
	_ = resp
}
func TestProductSearchGetProductSet(t *testing.T) {
	var name2 string = "name2-1052831874"
	var displayName string = "displayName1615086568"
	var expectedResponse = &visionpb.ProductSet{
		Name:        name2,
		DisplayName: displayName,
	}

	mockProductSearch.err = nil
	mockProductSearch.reqs = nil

	mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse)

	var formattedName string = fmt.Sprintf("projects/%s/locations/%s/productSets/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT_SET]")
	var request = &visionpb.GetProductSetRequest{
		Name: formattedName,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := c.GetProductSet(context.Background(), request)

	if err != nil {
		t.Fatal(err)
	}

	if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) {
		t.Errorf("wrong request %q, want %q", got, want)
	}

	if want, got := expectedResponse, resp; !proto.Equal(want, got) {
		t.Errorf("wrong response %q, want %q)", got, want)
	}
}

func TestProductSearchGetProductSetError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockProductSearch.err = gstatus.Error(errCode, "test error")

	var formattedName string = fmt.Sprintf("projects/%s/locations/%s/productSets/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT_SET]")
	var request = &visionpb.GetProductSetRequest{
		Name: formattedName,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := c.GetProductSet(context.Background(), request)

	if st, ok := gstatus.FromError(err); !ok {
		t.Errorf("got error %v, expected grpc error", err)
	} else if c := st.Code(); c != errCode {
		t.Errorf("got error code %q, want %q", c, errCode)
	}
	_ = resp
}
func TestProductSearchUpdateProductSet(t *testing.T) {
	var name string = "name3373707"
	var displayName string = "displayName1615086568"
	var expectedResponse = &visionpb.ProductSet{
		Name:        name,
		DisplayName: displayName,
	}

	mockProductSearch.err = nil
	mockProductSearch.reqs = nil

	mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse)

	var productSet *visionpb.ProductSet = &visionpb.ProductSet{}
	var request = &visionpb.UpdateProductSetRequest{
		ProductSet: productSet,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := c.UpdateProductSet(context.Background(), request)

	if err != nil {
		t.Fatal(err)
	}

	if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) {
		t.Errorf("wrong request %q, want %q", got, want)
	}

	if want, got := expectedResponse, resp; !proto.Equal(want, got) {
		t.Errorf("wrong response %q, want %q)", got, want)
	}
}

func TestProductSearchUpdateProductSetError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockProductSearch.err = gstatus.Error(errCode, "test error")

	var productSet *visionpb.ProductSet = &visionpb.ProductSet{}
	var request = &visionpb.UpdateProductSetRequest{
		ProductSet: productSet,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := c.UpdateProductSet(context.Background(), request)

	if st, ok := gstatus.FromError(err); !ok {
		t.Errorf("got error %v, expected grpc error", err)
	} else if c := st.Code(); c != errCode {
		t.Errorf("got error code %q, want %q", c, errCode)
	}
	_ = resp
}
func TestProductSearchDeleteProductSet(t *testing.T) {
	var expectedResponse *emptypb.Empty = &emptypb.Empty{}

	mockProductSearch.err = nil
	mockProductSearch.reqs = nil

	mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse)

	var formattedName string = fmt.Sprintf("projects/%s/locations/%s/productSets/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT_SET]")
	var request = &visionpb.DeleteProductSetRequest{
		Name: formattedName,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	err = c.DeleteProductSet(context.Background(), request)

	if err != nil {
		t.Fatal(err)
	}

	if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) {
		t.Errorf("wrong request %q, want %q", got, want)
	}

}

func TestProductSearchDeleteProductSetError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockProductSearch.err = gstatus.Error(errCode, "test error")

	var formattedName string = fmt.Sprintf("projects/%s/locations/%s/productSets/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT_SET]")
	var request = &visionpb.DeleteProductSetRequest{
		Name: formattedName,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	err = c.DeleteProductSet(context.Background(), request)

	if st, ok := gstatus.FromError(err); !ok {
		t.Errorf("got error %v, expected grpc error", err)
	} else if c := st.Code(); c != errCode {
		t.Errorf("got error code %q, want %q", c, errCode)
	}
}
func TestProductSearchCreateProduct(t *testing.T) {
	var name string = "name3373707"
	var displayName string = "displayName1615086568"
	var description string = "description-1724546052"
	var productCategory string = "productCategory-1607451058"
	var expectedResponse = &visionpb.Product{
		Name:            name,
		DisplayName:     displayName,
		Description:     description,
		ProductCategory: productCategory,
	}

	mockProductSearch.err = nil
	mockProductSearch.reqs = nil

	mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse)

	var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]")
	var product *visionpb.Product = &visionpb.Product{}
	var request = &visionpb.CreateProductRequest{
		Parent:  formattedParent,
		Product: product,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := c.CreateProduct(context.Background(), request)

	if err != nil {
		t.Fatal(err)
	}

	if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) {
		t.Errorf("wrong request %q, want %q", got, want)
	}

	if want, got := expectedResponse, resp; !proto.Equal(want, got) {
		t.Errorf("wrong response %q, want %q)", got, want)
	}
}

func TestProductSearchCreateProductError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockProductSearch.err = gstatus.Error(errCode, "test error")

	var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]")
	var product *visionpb.Product = &visionpb.Product{}
	var request = &visionpb.CreateProductRequest{
		Parent:  formattedParent,
		Product: product,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := c.CreateProduct(context.Background(), request)

	if st, ok := gstatus.FromError(err); !ok {
		t.Errorf("got error %v, expected grpc error", err)
	} else if c := st.Code(); c != errCode {
		t.Errorf("got error code %q, want %q", c, errCode)
	}
	_ = resp
}
func TestProductSearchListProducts(t *testing.T) {
	var nextPageToken string = ""
	var productsElement *visionpb.Product = &visionpb.Product{}
	var products = []*visionpb.Product{productsElement}
	var expectedResponse = &visionpb.ListProductsResponse{
		NextPageToken: nextPageToken,
		Products:      products,
	}

	mockProductSearch.err = nil
	mockProductSearch.reqs = nil

	mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse)

	var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]")
	var request = &visionpb.ListProductsRequest{
		Parent: formattedParent,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := c.ListProducts(context.Background(), request).Next()

	if err != nil {
		t.Fatal(err)
	}

	if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) {
		t.Errorf("wrong request %q, want %q", got, want)
	}

	want := (interface{})(expectedResponse.Products[0])
	got := (interface{})(resp)
	var ok bool

	switch want := (want).(type) {
	case proto.Message:
		ok = proto.Equal(want, got.(proto.Message))
	default:
		ok = want == got
	}
	if !ok {
		t.Errorf("wrong response %q, want %q)", got, want)
	}
}

func TestProductSearchListProductsError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockProductSearch.err = gstatus.Error(errCode, "test error")

	var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]")
	var request = &visionpb.ListProductsRequest{
		Parent: formattedParent,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := c.ListProducts(context.Background(), request).Next()

	if st, ok := gstatus.FromError(err); !ok {
		t.Errorf("got error %v, expected grpc error", err)
	} else if c := st.Code(); c != errCode {
		t.Errorf("got error code %q, want %q", c, errCode)
	}
	_ = resp
}
func TestProductSearchGetProduct(t *testing.T) {
	var name2 string = "name2-1052831874"
	var displayName string = "displayName1615086568"
	var description string = "description-1724546052"
	var productCategory string = "productCategory-1607451058"
	var expectedResponse = &visionpb.Product{
		Name:            name2,
		DisplayName:     displayName,
		Description:     description,
		ProductCategory: productCategory,
	}

	mockProductSearch.err = nil
	mockProductSearch.reqs = nil

	mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse)

	var formattedName string = fmt.Sprintf("projects/%s/locations/%s/products/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]")
	var request = &visionpb.GetProductRequest{
		Name: formattedName,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := c.GetProduct(context.Background(), request)

	if err != nil {
		t.Fatal(err)
	}

	if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) {
		t.Errorf("wrong request %q, want %q", got, want)
	}

	if want, got := expectedResponse, resp; !proto.Equal(want, got) {
		t.Errorf("wrong response %q, want %q)", got, want)
	}
}

func TestProductSearchGetProductError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockProductSearch.err = gstatus.Error(errCode, "test error")

	var formattedName string = fmt.Sprintf("projects/%s/locations/%s/products/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]")
	var request = &visionpb.GetProductRequest{
		Name: formattedName,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := c.GetProduct(context.Background(), request)

	if st, ok := gstatus.FromError(err); !ok {
		t.Errorf("got error %v, expected grpc error", err)
	} else if c := st.Code(); c != errCode {
		t.Errorf("got error code %q, want %q", c, errCode)
	}
	_ = resp
}
func TestProductSearchUpdateProduct(t *testing.T) {
	var name string = "name3373707"
	var displayName string = "displayName1615086568"
	var description string = "description-1724546052"
	var productCategory string = "productCategory-1607451058"
	var expectedResponse = &visionpb.Product{
		Name:            name,
		DisplayName:     displayName,
		Description:     description,
		ProductCategory: productCategory,
	}

	mockProductSearch.err = nil
	mockProductSearch.reqs = nil

	mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse)

	var product *visionpb.Product = &visionpb.Product{}
	var request = &visionpb.UpdateProductRequest{
		Product: product,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := c.UpdateProduct(context.Background(), request)

	if err != nil {
		t.Fatal(err)
	}

	if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) {
		t.Errorf("wrong request %q, want %q", got, want)
	}

	if want, got := expectedResponse, resp; !proto.Equal(want, got) {
		t.Errorf("wrong response %q, want %q)", got, want)
	}
}

func TestProductSearchUpdateProductError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockProductSearch.err = gstatus.Error(errCode, "test error")

	var product *visionpb.Product = &visionpb.Product{}
	var request = &visionpb.UpdateProductRequest{
		Product: product,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := c.UpdateProduct(context.Background(), request)

	if st, ok := gstatus.FromError(err); !ok {
		t.Errorf("got error %v, expected grpc error", err)
	} else if c := st.Code(); c != errCode {
		t.Errorf("got error code %q, want %q", c, errCode)
	}
	_ = resp
}
func TestProductSearchDeleteProduct(t *testing.T) {
	var expectedResponse *emptypb.Empty = &emptypb.Empty{}

	mockProductSearch.err = nil
	mockProductSearch.reqs = nil

	mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse)

	var formattedName string = fmt.Sprintf("projects/%s/locations/%s/products/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]")
	var request = &visionpb.DeleteProductRequest{
		Name: formattedName,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	err = c.DeleteProduct(context.Background(), request)

	if err != nil {
		t.Fatal(err)
	}

	if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) {
		t.Errorf("wrong request %q, want %q", got, want)
	}

}

func TestProductSearchDeleteProductError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockProductSearch.err = gstatus.Error(errCode, "test error")

	var formattedName string = fmt.Sprintf("projects/%s/locations/%s/products/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]")
	var request = &visionpb.DeleteProductRequest{
		Name: formattedName,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	err = c.DeleteProduct(context.Background(), request)

	if st, ok := gstatus.FromError(err); !ok {
		t.Errorf("got error %v, expected grpc error", err)
	} else if c := st.Code(); c != errCode {
		t.Errorf("got error code %q, want %q", c, errCode)
	}
}
func TestProductSearchCreateReferenceImage(t *testing.T) {
	var name string = "name3373707"
	var uri string = "uri116076"
	var expectedResponse = &visionpb.ReferenceImage{
		Name: name,
		Uri:  uri,
	}

	mockProductSearch.err = nil
	mockProductSearch.reqs = nil

	mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse)

	var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/products/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]")
	var referenceImage *visionpb.ReferenceImage = &visionpb.ReferenceImage{}
	var request = &visionpb.CreateReferenceImageRequest{
		Parent:         formattedParent,
		ReferenceImage: referenceImage,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := c.CreateReferenceImage(context.Background(), request)

	if err != nil {
		t.Fatal(err)
	}

	if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) {
		t.Errorf("wrong request %q, want %q", got, want)
	}

	if want, got := expectedResponse, resp; !proto.Equal(want, got) {
		t.Errorf("wrong response %q, want %q)", got, want)
	}
}

func TestProductSearchCreateReferenceImageError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockProductSearch.err = gstatus.Error(errCode, "test error")

	var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/products/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]")
	var referenceImage *visionpb.ReferenceImage = &visionpb.ReferenceImage{}
	var request = &visionpb.CreateReferenceImageRequest{
		Parent:         formattedParent,
		ReferenceImage: referenceImage,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := c.CreateReferenceImage(context.Background(), request)

	if st, ok := gstatus.FromError(err); !ok {
		t.Errorf("got error %v, expected grpc error", err)
	} else if c := st.Code(); c != errCode {
		t.Errorf("got error code %q, want %q", c, errCode)
	}
	_ = resp
}
func TestProductSearchDeleteReferenceImage(t *testing.T) {
	var expectedResponse *emptypb.Empty = &emptypb.Empty{}

	mockProductSearch.err = nil
	mockProductSearch.reqs = nil

	mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse)

	var formattedName string = fmt.Sprintf("projects/%s/locations/%s/products/%s/referenceImages/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]", "[REFERENCE_IMAGE]")
	var request = &visionpb.DeleteReferenceImageRequest{
		Name: formattedName,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	err = c.DeleteReferenceImage(context.Background(), request)

	if err != nil {
		t.Fatal(err)
	}

	if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) {
		t.Errorf("wrong request %q, want %q", got, want)
	}

}

func TestProductSearchDeleteReferenceImageError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockProductSearch.err = gstatus.Error(errCode, "test error")

	var formattedName string = fmt.Sprintf("projects/%s/locations/%s/products/%s/referenceImages/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]", "[REFERENCE_IMAGE]")
	var request = &visionpb.DeleteReferenceImageRequest{
		Name: formattedName,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	err = c.DeleteReferenceImage(context.Background(), request)

	if st, ok := gstatus.FromError(err); !ok {
		t.Errorf("got error %v, expected grpc error", err)
	} else if c := st.Code(); c != errCode {
		t.Errorf("got error code %q, want %q", c, errCode)
	}
}
func TestProductSearchListReferenceImages(t *testing.T) {
	var pageSize int32 = 883849137
	var nextPageToken string = ""
	var referenceImagesElement *visionpb.ReferenceImage = &visionpb.ReferenceImage{}
	var referenceImages = []*visionpb.ReferenceImage{referenceImagesElement}
	var expectedResponse = &visionpb.ListReferenceImagesResponse{
		PageSize:        pageSize,
		NextPageToken:   nextPageToken,
		ReferenceImages: referenceImages,
	}

	mockProductSearch.err = nil
	mockProductSearch.reqs = nil

	mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse)

	var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/products/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]")
	var request = &visionpb.ListReferenceImagesRequest{
		Parent: formattedParent,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := c.ListReferenceImages(context.Background(), request).Next()

	if err != nil {
		t.Fatal(err)
	}

	if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) {
		t.Errorf("wrong request %q, want %q", got, want)
	}

	want := (interface{})(expectedResponse.ReferenceImages[0])
	got := (interface{})(resp)
	var ok bool

	switch want := (want).(type) {
	case proto.Message:
		ok = proto.Equal(want, got.(proto.Message))
	default:
		ok = want == got
	}
	if !ok {
		t.Errorf("wrong response %q, want %q)", got, want)
	}
}

func TestProductSearchListReferenceImagesError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockProductSearch.err = gstatus.Error(errCode, "test error")

	var formattedParent string = fmt.Sprintf("projects/%s/locations/%s/products/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]")
	var request = &visionpb.ListReferenceImagesRequest{
		Parent: formattedParent,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := c.ListReferenceImages(context.Background(), request).Next()

	if st, ok := gstatus.FromError(err); !ok {
		t.Errorf("got error %v, expected grpc error", err)
	} else if c := st.Code(); c != errCode {
		t.Errorf("got error code %q, want %q", c, errCode)
	}
	_ = resp
}
func TestProductSearchGetReferenceImage(t *testing.T) {
	var name2 string = "name2-1052831874"
	var uri string = "uri116076"
	var expectedResponse = &visionpb.ReferenceImage{
		Name: name2,
		Uri:  uri,
	}

	mockProductSearch.err = nil
	mockProductSearch.reqs = nil

	mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse)

	var formattedName string = fmt.Sprintf("projects/%s/locations/%s/products/%s/referenceImages/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]", "[REFERENCE_IMAGE]")
	var request = &visionpb.GetReferenceImageRequest{
		Name: formattedName,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := c.GetReferenceImage(context.Background(), request)

	if err != nil {
		t.Fatal(err)
	}

	if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) {
		t.Errorf("wrong request %q, want %q", got, want)
	}

	if want, got := expectedResponse, resp; !proto.Equal(want, got) {
		t.Errorf("wrong response %q, want %q)", got, want)
	}
}

func TestProductSearchGetReferenceImageError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockProductSearch.err = gstatus.Error(errCode, "test error")

	var formattedName string = fmt.Sprintf("projects/%s/locations/%s/products/%s/referenceImages/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]", "[REFERENCE_IMAGE]")
	var request = &visionpb.GetReferenceImageRequest{
		Name: formattedName,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := c.GetReferenceImage(context.Background(), request)

	if st, ok := gstatus.FromError(err); !ok {
		t.Errorf("got error %v, expected grpc error", err)
	} else if c := st.Code(); c != errCode {
		t.Errorf("got error code %q, want %q", c, errCode)
	}
	_ = resp
}
func TestProductSearchAddProductToProductSet(t *testing.T) {
	var expectedResponse *emptypb.Empty = &emptypb.Empty{}

	mockProductSearch.err = nil
	mockProductSearch.reqs = nil

	mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse)

	var formattedName string = fmt.Sprintf("projects/%s/locations/%s/productSets/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT_SET]")
	var formattedProduct string = fmt.Sprintf("projects/%s/locations/%s/products/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]")
	var request = &visionpb.AddProductToProductSetRequest{
		Name:    formattedName,
		Product: formattedProduct,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	err = c.AddProductToProductSet(context.Background(), request)

	if err != nil {
		t.Fatal(err)
	}

	if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) {
		t.Errorf("wrong request %q, want %q", got, want)
	}

}

func TestProductSearchAddProductToProductSetError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockProductSearch.err = gstatus.Error(errCode, "test error")

	var formattedName string = fmt.Sprintf("projects/%s/locations/%s/productSets/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT_SET]")
	var formattedProduct string = fmt.Sprintf("projects/%s/locations/%s/products/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]")
	var request = &visionpb.AddProductToProductSetRequest{
		Name:    formattedName,
		Product: formattedProduct,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	err = c.AddProductToProductSet(context.Background(), request)

	if st, ok := gstatus.FromError(err); !ok {
		t.Errorf("got error %v, expected grpc error", err)
	} else if c := st.Code(); c != errCode {
		t.Errorf("got error code %q, want %q", c, errCode)
	}
}
func TestProductSearchRemoveProductFromProductSet(t *testing.T) {
	var expectedResponse *emptypb.Empty = &emptypb.Empty{}

	mockProductSearch.err = nil
	mockProductSearch.reqs = nil

	mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse)

	var formattedName string = fmt.Sprintf("projects/%s/locations/%s/productSets/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT_SET]")
	var formattedProduct string = fmt.Sprintf("projects/%s/locations/%s/products/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]")
	var request = &visionpb.RemoveProductFromProductSetRequest{
		Name:    formattedName,
		Product: formattedProduct,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	err = c.RemoveProductFromProductSet(context.Background(), request)

	if err != nil {
		t.Fatal(err)
	}

	if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) {
		t.Errorf("wrong request %q, want %q", got, want)
	}

}

func TestProductSearchRemoveProductFromProductSetError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockProductSearch.err = gstatus.Error(errCode, "test error")

	var formattedName string = fmt.Sprintf("projects/%s/locations/%s/productSets/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT_SET]")
	var formattedProduct string = fmt.Sprintf("projects/%s/locations/%s/products/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT]")
	var request = &visionpb.RemoveProductFromProductSetRequest{
		Name:    formattedName,
		Product: formattedProduct,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	err = c.RemoveProductFromProductSet(context.Background(), request)

	if st, ok := gstatus.FromError(err); !ok {
		t.Errorf("got error %v, expected grpc error", err)
	} else if c := st.Code(); c != errCode {
		t.Errorf("got error code %q, want %q", c, errCode)
	}
}
func TestProductSearchListProductsInProductSet(t *testing.T) {
	var nextPageToken string = ""
	var productsElement *visionpb.Product = &visionpb.Product{}
	var products = []*visionpb.Product{productsElement}
	var expectedResponse = &visionpb.ListProductsInProductSetResponse{
		NextPageToken: nextPageToken,
		Products:      products,
	}

	mockProductSearch.err = nil
	mockProductSearch.reqs = nil

	mockProductSearch.resps = append(mockProductSearch.resps[:0], expectedResponse)

	var formattedName string = fmt.Sprintf("projects/%s/locations/%s/productSets/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT_SET]")
	var request = &visionpb.ListProductsInProductSetRequest{
		Name: formattedName,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := c.ListProductsInProductSet(context.Background(), request).Next()

	if err != nil {
		t.Fatal(err)
	}

	if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) {
		t.Errorf("wrong request %q, want %q", got, want)
	}

	want := (interface{})(expectedResponse.Products[0])
	got := (interface{})(resp)
	var ok bool

	switch want := (want).(type) {
	case proto.Message:
		ok = proto.Equal(want, got.(proto.Message))
	default:
		ok = want == got
	}
	if !ok {
		t.Errorf("wrong response %q, want %q)", got, want)
	}
}

func TestProductSearchListProductsInProductSetError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockProductSearch.err = gstatus.Error(errCode, "test error")

	var formattedName string = fmt.Sprintf("projects/%s/locations/%s/productSets/%s", "[PROJECT]", "[LOCATION]", "[PRODUCT_SET]")
	var request = &visionpb.ListProductsInProductSetRequest{
		Name: formattedName,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	resp, err := c.ListProductsInProductSet(context.Background(), request).Next()

	if st, ok := gstatus.FromError(err); !ok {
		t.Errorf("got error %v, expected grpc error", err)
	} else if c := st.Code(); c != errCode {
		t.Errorf("got error code %q, want %q", c, errCode)
	}
	_ = resp
}
func TestProductSearchImportProductSets(t *testing.T) {
	var expectedResponse *visionpb.ImportProductSetsResponse = &visionpb.ImportProductSetsResponse{}

	mockProductSearch.err = nil
	mockProductSearch.reqs = nil

	any, err := ptypes.MarshalAny(expectedResponse)
	if err != nil {
		t.Fatal(err)
	}
	mockProductSearch.resps = append(mockProductSearch.resps[:0], &longrunningpb.Operation{
		Name:   "longrunning-test",
		Done:   true,
		Result: &longrunningpb.Operation_Response{Response: any},
	})

	var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]")
	var inputConfig *visionpb.ImportProductSetsInputConfig = &visionpb.ImportProductSetsInputConfig{}
	var request = &visionpb.ImportProductSetsRequest{
		Parent:      formattedParent,
		InputConfig: inputConfig,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	respLRO, err := c.ImportProductSets(context.Background(), request)
	if err != nil {
		t.Fatal(err)
	}
	resp, err := respLRO.Wait(context.Background())

	if err != nil {
		t.Fatal(err)
	}

	if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) {
		t.Errorf("wrong request %q, want %q", got, want)
	}

	if want, got := expectedResponse, resp; !proto.Equal(want, got) {
		t.Errorf("wrong response %q, want %q)", got, want)
	}
}

func TestProductSearchImportProductSetsError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockProductSearch.err = nil
	mockProductSearch.resps = append(mockProductSearch.resps[:0], &longrunningpb.Operation{
		Name: "longrunning-test",
		Done: true,
		Result: &longrunningpb.Operation_Error{
			Error: &status.Status{
				Code:    int32(errCode),
				Message: "test error",
			},
		},
	})

	var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]")
	var inputConfig *visionpb.ImportProductSetsInputConfig = &visionpb.ImportProductSetsInputConfig{}
	var request = &visionpb.ImportProductSetsRequest{
		Parent:      formattedParent,
		InputConfig: inputConfig,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	respLRO, err := c.ImportProductSets(context.Background(), request)
	if err != nil {
		t.Fatal(err)
	}
	resp, err := respLRO.Wait(context.Background())

	if st, ok := gstatus.FromError(err); !ok {
		t.Errorf("got error %v, expected grpc error", err)
	} else if c := st.Code(); c != errCode {
		t.Errorf("got error code %q, want %q", c, errCode)
	}
	_ = resp
}
func TestProductSearchPurgeProducts(t *testing.T) {
	var expectedResponse *emptypb.Empty = &emptypb.Empty{}

	mockProductSearch.err = nil
	mockProductSearch.reqs = nil

	any, err := ptypes.MarshalAny(expectedResponse)
	if err != nil {
		t.Fatal(err)
	}
	mockProductSearch.resps = append(mockProductSearch.resps[:0], &longrunningpb.Operation{
		Name:   "longrunning-test",
		Done:   true,
		Result: &longrunningpb.Operation_Response{Response: any},
	})

	var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]")
	var request = &visionpb.PurgeProductsRequest{
		Parent: formattedParent,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	respLRO, err := c.PurgeProducts(context.Background(), request)
	if err != nil {
		t.Fatal(err)
	}
	err = respLRO.Wait(context.Background())

	if err != nil {
		t.Fatal(err)
	}

	if want, got := request, mockProductSearch.reqs[0]; !proto.Equal(want, got) {
		t.Errorf("wrong request %q, want %q", got, want)
	}

}

func TestProductSearchPurgeProductsError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockProductSearch.err = nil
	mockProductSearch.resps = append(mockProductSearch.resps[:0], &longrunningpb.Operation{
		Name: "longrunning-test",
		Done: true,
		Result: &longrunningpb.Operation_Error{
			Error: &status.Status{
				Code:    int32(errCode),
				Message: "test error",
			},
		},
	})

	var formattedParent string = fmt.Sprintf("projects/%s/locations/%s", "[PROJECT]", "[LOCATION]")
	var request = &visionpb.PurgeProductsRequest{
		Parent: formattedParent,
	}

	c, err := NewProductSearchClient(context.Background(), clientOpt)
	if err != nil {
		t.Fatal(err)
	}

	respLRO, err := c.PurgeProducts(context.Background(), request)
	if err != nil {
		t.Fatal(err)
	}
	err = respLRO.Wait(context.Background())

	if st, ok := gstatus.FromError(err); !ok {
		t.Errorf("got error %v, expected grpc error", err)
	} else if c := st.Code(); c != errCode {
		t.Errorf("got error code %q, want %q", c, errCode)
	}
}
