// 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 talent

import (
	emptypb "github.com/golang/protobuf/ptypes/empty"
	talentpb "google.golang.org/genproto/googleapis/cloud/talent/v4beta1"
	longrunningpb "google.golang.org/genproto/googleapis/longrunning"
)

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

	"github.com/golang/protobuf/proto"
	"github.com/golang/protobuf/ptypes"
	"google.golang.org/api/option"
	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 mockApplicationServer struct {
	// Embed for forward compatibility.
	// Tests will keep working if more methods are added
	// in the future.
	talentpb.ApplicationServiceServer

	reqs []proto.Message

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

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

func (s *mockApplicationServer) CreateApplication(ctx context.Context, req *talentpb.CreateApplicationRequest) (*talentpb.Application, 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].(*talentpb.Application), nil
}

func (s *mockApplicationServer) GetApplication(ctx context.Context, req *talentpb.GetApplicationRequest) (*talentpb.Application, 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].(*talentpb.Application), nil
}

func (s *mockApplicationServer) UpdateApplication(ctx context.Context, req *talentpb.UpdateApplicationRequest) (*talentpb.Application, 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].(*talentpb.Application), nil
}

func (s *mockApplicationServer) DeleteApplication(ctx context.Context, req *talentpb.DeleteApplicationRequest) (*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 *mockApplicationServer) ListApplications(ctx context.Context, req *talentpb.ListApplicationsRequest) (*talentpb.ListApplicationsResponse, 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].(*talentpb.ListApplicationsResponse), nil
}

type mockCompanyServer struct {
	// Embed for forward compatibility.
	// Tests will keep working if more methods are added
	// in the future.
	talentpb.CompanyServiceServer

	reqs []proto.Message

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

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

func (s *mockCompanyServer) CreateCompany(ctx context.Context, req *talentpb.CreateCompanyRequest) (*talentpb.Company, 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].(*talentpb.Company), nil
}

func (s *mockCompanyServer) GetCompany(ctx context.Context, req *talentpb.GetCompanyRequest) (*talentpb.Company, 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].(*talentpb.Company), nil
}

func (s *mockCompanyServer) UpdateCompany(ctx context.Context, req *talentpb.UpdateCompanyRequest) (*talentpb.Company, 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].(*talentpb.Company), nil
}

func (s *mockCompanyServer) DeleteCompany(ctx context.Context, req *talentpb.DeleteCompanyRequest) (*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 *mockCompanyServer) ListCompanies(ctx context.Context, req *talentpb.ListCompaniesRequest) (*talentpb.ListCompaniesResponse, 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].(*talentpb.ListCompaniesResponse), nil
}

type mockCompletionServer struct {
	// Embed for forward compatibility.
	// Tests will keep working if more methods are added
	// in the future.
	talentpb.CompletionServer

	reqs []proto.Message

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

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

func (s *mockCompletionServer) CompleteQuery(ctx context.Context, req *talentpb.CompleteQueryRequest) (*talentpb.CompleteQueryResponse, 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].(*talentpb.CompleteQueryResponse), nil
}

type mockEventServer struct {
	// Embed for forward compatibility.
	// Tests will keep working if more methods are added
	// in the future.
	talentpb.EventServiceServer

	reqs []proto.Message

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

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

func (s *mockEventServer) CreateClientEvent(ctx context.Context, req *talentpb.CreateClientEventRequest) (*talentpb.ClientEvent, 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].(*talentpb.ClientEvent), nil
}

type mockJobServer struct {
	// Embed for forward compatibility.
	// Tests will keep working if more methods are added
	// in the future.
	talentpb.JobServiceServer

	reqs []proto.Message

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

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

func (s *mockJobServer) CreateJob(ctx context.Context, req *talentpb.CreateJobRequest) (*talentpb.Job, 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].(*talentpb.Job), nil
}

func (s *mockJobServer) GetJob(ctx context.Context, req *talentpb.GetJobRequest) (*talentpb.Job, 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].(*talentpb.Job), nil
}

func (s *mockJobServer) UpdateJob(ctx context.Context, req *talentpb.UpdateJobRequest) (*talentpb.Job, 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].(*talentpb.Job), nil
}

func (s *mockJobServer) DeleteJob(ctx context.Context, req *talentpb.DeleteJobRequest) (*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 *mockJobServer) ListJobs(ctx context.Context, req *talentpb.ListJobsRequest) (*talentpb.ListJobsResponse, 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].(*talentpb.ListJobsResponse), nil
}

func (s *mockJobServer) BatchDeleteJobs(ctx context.Context, req *talentpb.BatchDeleteJobsRequest) (*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 *mockJobServer) SearchJobs(ctx context.Context, req *talentpb.SearchJobsRequest) (*talentpb.SearchJobsResponse, 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].(*talentpb.SearchJobsResponse), nil
}

func (s *mockJobServer) SearchJobsForAlert(ctx context.Context, req *talentpb.SearchJobsRequest) (*talentpb.SearchJobsResponse, 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].(*talentpb.SearchJobsResponse), nil
}

func (s *mockJobServer) BatchCreateJobs(ctx context.Context, req *talentpb.BatchCreateJobsRequest) (*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 *mockJobServer) BatchUpdateJobs(ctx context.Context, req *talentpb.BatchUpdateJobsRequest) (*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 mockProfileServer struct {
	// Embed for forward compatibility.
	// Tests will keep working if more methods are added
	// in the future.
	talentpb.ProfileServiceServer

	reqs []proto.Message

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

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

func (s *mockProfileServer) ListProfiles(ctx context.Context, req *talentpb.ListProfilesRequest) (*talentpb.ListProfilesResponse, 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].(*talentpb.ListProfilesResponse), nil
}

func (s *mockProfileServer) CreateProfile(ctx context.Context, req *talentpb.CreateProfileRequest) (*talentpb.Profile, 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].(*talentpb.Profile), nil
}

func (s *mockProfileServer) GetProfile(ctx context.Context, req *talentpb.GetProfileRequest) (*talentpb.Profile, 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].(*talentpb.Profile), nil
}

func (s *mockProfileServer) UpdateProfile(ctx context.Context, req *talentpb.UpdateProfileRequest) (*talentpb.Profile, 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].(*talentpb.Profile), nil
}

func (s *mockProfileServer) DeleteProfile(ctx context.Context, req *talentpb.DeleteProfileRequest) (*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 *mockProfileServer) SearchProfiles(ctx context.Context, req *talentpb.SearchProfilesRequest) (*talentpb.SearchProfilesResponse, 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].(*talentpb.SearchProfilesResponse), nil
}

type mockTenantServer struct {
	// Embed for forward compatibility.
	// Tests will keep working if more methods are added
	// in the future.
	talentpb.TenantServiceServer

	reqs []proto.Message

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

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

func (s *mockTenantServer) CreateTenant(ctx context.Context, req *talentpb.CreateTenantRequest) (*talentpb.Tenant, 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].(*talentpb.Tenant), nil
}

func (s *mockTenantServer) GetTenant(ctx context.Context, req *talentpb.GetTenantRequest) (*talentpb.Tenant, 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].(*talentpb.Tenant), nil
}

func (s *mockTenantServer) UpdateTenant(ctx context.Context, req *talentpb.UpdateTenantRequest) (*talentpb.Tenant, 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].(*talentpb.Tenant), nil
}

func (s *mockTenantServer) DeleteTenant(ctx context.Context, req *talentpb.DeleteTenantRequest) (*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 *mockTenantServer) ListTenants(ctx context.Context, req *talentpb.ListTenantsRequest) (*talentpb.ListTenantsResponse, 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].(*talentpb.ListTenantsResponse), nil
}

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

var (
	mockApplication mockApplicationServer
	mockCompany     mockCompanyServer
	mockCompletion  mockCompletionServer
	mockEvent       mockEventServer
	mockJob         mockJobServer
	mockProfile     mockProfileServer
	mockTenant      mockTenantServer
)

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

	serv := grpc.NewServer()
	talentpb.RegisterApplicationServiceServer(serv, &mockApplication)
	talentpb.RegisterCompanyServiceServer(serv, &mockCompany)
	talentpb.RegisterCompletionServer(serv, &mockCompletion)
	talentpb.RegisterEventServiceServer(serv, &mockEvent)
	talentpb.RegisterJobServiceServer(serv, &mockJob)
	talentpb.RegisterProfileServiceServer(serv, &mockProfile)
	talentpb.RegisterTenantServiceServer(serv, &mockTenant)

	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 TestApplicationServiceCreateApplication(t *testing.T) {
	var name string = "name3373707"
	var externalId string = "externalId-1153075697"
	var profile string = "profile-309425751"
	var job string = "job105405"
	var company string = "company950484093"
	var outcomeNotes string = "outcomeNotes-355961964"
	var jobTitleSnippet string = "jobTitleSnippet-1100512972"
	var expectedResponse = &talentpb.Application{
		Name:            name,
		ExternalId:      externalId,
		Profile:         profile,
		Job:             job,
		Company:         company,
		OutcomeNotes:    outcomeNotes,
		JobTitleSnippet: jobTitleSnippet,
	}

	mockApplication.err = nil
	mockApplication.reqs = nil

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

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s/profiles/%s", "[PROJECT]", "[TENANT]", "[PROFILE]")
	var application *talentpb.Application = &talentpb.Application{}
	var request = &talentpb.CreateApplicationRequest{
		Parent:      formattedParent,
		Application: application,
	}

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

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

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

	if want, got := request, mockApplication.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 TestApplicationServiceCreateApplicationError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockApplication.err = gstatus.Error(errCode, "test error")

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s/profiles/%s", "[PROJECT]", "[TENANT]", "[PROFILE]")
	var application *talentpb.Application = &talentpb.Application{}
	var request = &talentpb.CreateApplicationRequest{
		Parent:      formattedParent,
		Application: application,
	}

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

	resp, err := c.CreateApplication(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 TestApplicationServiceGetApplication(t *testing.T) {
	var name2 string = "name2-1052831874"
	var externalId string = "externalId-1153075697"
	var profile string = "profile-309425751"
	var job string = "job105405"
	var company string = "company950484093"
	var outcomeNotes string = "outcomeNotes-355961964"
	var jobTitleSnippet string = "jobTitleSnippet-1100512972"
	var expectedResponse = &talentpb.Application{
		Name:            name2,
		ExternalId:      externalId,
		Profile:         profile,
		Job:             job,
		Company:         company,
		OutcomeNotes:    outcomeNotes,
		JobTitleSnippet: jobTitleSnippet,
	}

	mockApplication.err = nil
	mockApplication.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/profiles/%s/applications/%s", "[PROJECT]", "[TENANT]", "[PROFILE]", "[APPLICATION]")
	var request = &talentpb.GetApplicationRequest{
		Name: formattedName,
	}

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

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

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

	if want, got := request, mockApplication.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 TestApplicationServiceGetApplicationError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockApplication.err = gstatus.Error(errCode, "test error")

	var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/profiles/%s/applications/%s", "[PROJECT]", "[TENANT]", "[PROFILE]", "[APPLICATION]")
	var request = &talentpb.GetApplicationRequest{
		Name: formattedName,
	}

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

	resp, err := c.GetApplication(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 TestApplicationServiceUpdateApplication(t *testing.T) {
	var name string = "name3373707"
	var externalId string = "externalId-1153075697"
	var profile string = "profile-309425751"
	var job string = "job105405"
	var company string = "company950484093"
	var outcomeNotes string = "outcomeNotes-355961964"
	var jobTitleSnippet string = "jobTitleSnippet-1100512972"
	var expectedResponse = &talentpb.Application{
		Name:            name,
		ExternalId:      externalId,
		Profile:         profile,
		Job:             job,
		Company:         company,
		OutcomeNotes:    outcomeNotes,
		JobTitleSnippet: jobTitleSnippet,
	}

	mockApplication.err = nil
	mockApplication.reqs = nil

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

	var application *talentpb.Application = &talentpb.Application{}
	var request = &talentpb.UpdateApplicationRequest{
		Application: application,
	}

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

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

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

	if want, got := request, mockApplication.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 TestApplicationServiceUpdateApplicationError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockApplication.err = gstatus.Error(errCode, "test error")

	var application *talentpb.Application = &talentpb.Application{}
	var request = &talentpb.UpdateApplicationRequest{
		Application: application,
	}

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

	resp, err := c.UpdateApplication(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 TestApplicationServiceDeleteApplication(t *testing.T) {
	var expectedResponse *emptypb.Empty = &emptypb.Empty{}

	mockApplication.err = nil
	mockApplication.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/profiles/%s/applications/%s", "[PROJECT]", "[TENANT]", "[PROFILE]", "[APPLICATION]")
	var request = &talentpb.DeleteApplicationRequest{
		Name: formattedName,
	}

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

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

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

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

}

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

	var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/profiles/%s/applications/%s", "[PROJECT]", "[TENANT]", "[PROFILE]", "[APPLICATION]")
	var request = &talentpb.DeleteApplicationRequest{
		Name: formattedName,
	}

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

	err = c.DeleteApplication(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 TestApplicationServiceListApplications(t *testing.T) {
	var nextPageToken string = ""
	var applicationsElement *talentpb.Application = &talentpb.Application{}
	var applications = []*talentpb.Application{applicationsElement}
	var expectedResponse = &talentpb.ListApplicationsResponse{
		NextPageToken: nextPageToken,
		Applications:  applications,
	}

	mockApplication.err = nil
	mockApplication.reqs = nil

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

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s/profiles/%s", "[PROJECT]", "[TENANT]", "[PROFILE]")
	var request = &talentpb.ListApplicationsRequest{
		Parent: formattedParent,
	}

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

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

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

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

	want := (interface{})(expectedResponse.Applications[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 TestApplicationServiceListApplicationsError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockApplication.err = gstatus.Error(errCode, "test error")

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s/profiles/%s", "[PROJECT]", "[TENANT]", "[PROFILE]")
	var request = &talentpb.ListApplicationsRequest{
		Parent: formattedParent,
	}

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

	resp, err := c.ListApplications(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 TestCompanyServiceCreateCompany(t *testing.T) {
	var name string = "name3373707"
	var displayName string = "displayName1615086568"
	var externalId string = "externalId-1153075697"
	var headquartersAddress string = "headquartersAddress-1879520036"
	var hiringAgency bool = false
	var eeoText string = "eeoText-1652097123"
	var websiteUri string = "websiteUri-2118185016"
	var careerSiteUri string = "careerSiteUri1223331861"
	var imageUri string = "imageUri-877823864"
	var suspended bool = false
	var expectedResponse = &talentpb.Company{
		Name:                name,
		DisplayName:         displayName,
		ExternalId:          externalId,
		HeadquartersAddress: headquartersAddress,
		HiringAgency:        hiringAgency,
		EeoText:             eeoText,
		WebsiteUri:          websiteUri,
		CareerSiteUri:       careerSiteUri,
		ImageUri:            imageUri,
		Suspended:           suspended,
	}

	mockCompany.err = nil
	mockCompany.reqs = nil

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

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var company *talentpb.Company = &talentpb.Company{}
	var request = &talentpb.CreateCompanyRequest{
		Parent:  formattedParent,
		Company: company,
	}

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

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

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

	if want, got := request, mockCompany.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 TestCompanyServiceCreateCompanyError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockCompany.err = gstatus.Error(errCode, "test error")

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var company *talentpb.Company = &talentpb.Company{}
	var request = &talentpb.CreateCompanyRequest{
		Parent:  formattedParent,
		Company: company,
	}

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

	resp, err := c.CreateCompany(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 TestCompanyServiceGetCompany(t *testing.T) {
	var name2 string = "name2-1052831874"
	var displayName string = "displayName1615086568"
	var externalId string = "externalId-1153075697"
	var headquartersAddress string = "headquartersAddress-1879520036"
	var hiringAgency bool = false
	var eeoText string = "eeoText-1652097123"
	var websiteUri string = "websiteUri-2118185016"
	var careerSiteUri string = "careerSiteUri1223331861"
	var imageUri string = "imageUri-877823864"
	var suspended bool = false
	var expectedResponse = &talentpb.Company{
		Name:                name2,
		DisplayName:         displayName,
		ExternalId:          externalId,
		HeadquartersAddress: headquartersAddress,
		HiringAgency:        hiringAgency,
		EeoText:             eeoText,
		WebsiteUri:          websiteUri,
		CareerSiteUri:       careerSiteUri,
		ImageUri:            imageUri,
		Suspended:           suspended,
	}

	mockCompany.err = nil
	mockCompany.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/companies/%s", "[PROJECT]", "[TENANT]", "[COMPANY]")
	var request = &talentpb.GetCompanyRequest{
		Name: formattedName,
	}

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

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

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

	if want, got := request, mockCompany.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 TestCompanyServiceGetCompanyError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockCompany.err = gstatus.Error(errCode, "test error")

	var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/companies/%s", "[PROJECT]", "[TENANT]", "[COMPANY]")
	var request = &talentpb.GetCompanyRequest{
		Name: formattedName,
	}

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

	resp, err := c.GetCompany(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 TestCompanyServiceUpdateCompany(t *testing.T) {
	var name string = "name3373707"
	var displayName string = "displayName1615086568"
	var externalId string = "externalId-1153075697"
	var headquartersAddress string = "headquartersAddress-1879520036"
	var hiringAgency bool = false
	var eeoText string = "eeoText-1652097123"
	var websiteUri string = "websiteUri-2118185016"
	var careerSiteUri string = "careerSiteUri1223331861"
	var imageUri string = "imageUri-877823864"
	var suspended bool = false
	var expectedResponse = &talentpb.Company{
		Name:                name,
		DisplayName:         displayName,
		ExternalId:          externalId,
		HeadquartersAddress: headquartersAddress,
		HiringAgency:        hiringAgency,
		EeoText:             eeoText,
		WebsiteUri:          websiteUri,
		CareerSiteUri:       careerSiteUri,
		ImageUri:            imageUri,
		Suspended:           suspended,
	}

	mockCompany.err = nil
	mockCompany.reqs = nil

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

	var company *talentpb.Company = &talentpb.Company{}
	var request = &talentpb.UpdateCompanyRequest{
		Company: company,
	}

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

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

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

	if want, got := request, mockCompany.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 TestCompanyServiceUpdateCompanyError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockCompany.err = gstatus.Error(errCode, "test error")

	var company *talentpb.Company = &talentpb.Company{}
	var request = &talentpb.UpdateCompanyRequest{
		Company: company,
	}

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

	resp, err := c.UpdateCompany(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 TestCompanyServiceDeleteCompany(t *testing.T) {
	var expectedResponse *emptypb.Empty = &emptypb.Empty{}

	mockCompany.err = nil
	mockCompany.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/companies/%s", "[PROJECT]", "[TENANT]", "[COMPANY]")
	var request = &talentpb.DeleteCompanyRequest{
		Name: formattedName,
	}

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

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

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

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

}

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

	var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/companies/%s", "[PROJECT]", "[TENANT]", "[COMPANY]")
	var request = &talentpb.DeleteCompanyRequest{
		Name: formattedName,
	}

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

	err = c.DeleteCompany(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 TestCompanyServiceListCompanies(t *testing.T) {
	var nextPageToken string = ""
	var companiesElement *talentpb.Company = &talentpb.Company{}
	var companies = []*talentpb.Company{companiesElement}
	var expectedResponse = &talentpb.ListCompaniesResponse{
		NextPageToken: nextPageToken,
		Companies:     companies,
	}

	mockCompany.err = nil
	mockCompany.reqs = nil

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

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var request = &talentpb.ListCompaniesRequest{
		Parent: formattedParent,
	}

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

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

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

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

	want := (interface{})(expectedResponse.Companies[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 TestCompanyServiceListCompaniesError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockCompany.err = gstatus.Error(errCode, "test error")

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var request = &talentpb.ListCompaniesRequest{
		Parent: formattedParent,
	}

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

	resp, err := c.ListCompanies(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 TestCompletionCompleteQuery(t *testing.T) {
	var expectedResponse *talentpb.CompleteQueryResponse = &talentpb.CompleteQueryResponse{}

	mockCompletion.err = nil
	mockCompletion.reqs = nil

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

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var query string = "query107944136"
	var pageSize int32 = 883849137
	var request = &talentpb.CompleteQueryRequest{
		Parent:   formattedParent,
		Query:    query,
		PageSize: pageSize,
	}

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

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

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

	if want, got := request, mockCompletion.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 TestCompletionCompleteQueryError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockCompletion.err = gstatus.Error(errCode, "test error")

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var query string = "query107944136"
	var pageSize int32 = 883849137
	var request = &talentpb.CompleteQueryRequest{
		Parent:   formattedParent,
		Query:    query,
		PageSize: pageSize,
	}

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

	resp, err := c.CompleteQuery(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 TestEventServiceCreateClientEvent(t *testing.T) {
	var requestId string = "requestId37109963"
	var eventId string = "eventId278118624"
	var eventNotes string = "eventNotes445073628"
	var expectedResponse = &talentpb.ClientEvent{
		RequestId:  requestId,
		EventId:    eventId,
		EventNotes: eventNotes,
	}

	mockEvent.err = nil
	mockEvent.reqs = nil

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

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var clientEvent *talentpb.ClientEvent = &talentpb.ClientEvent{}
	var request = &talentpb.CreateClientEventRequest{
		Parent:      formattedParent,
		ClientEvent: clientEvent,
	}

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

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

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

	if want, got := request, mockEvent.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 TestEventServiceCreateClientEventError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockEvent.err = gstatus.Error(errCode, "test error")

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var clientEvent *talentpb.ClientEvent = &talentpb.ClientEvent{}
	var request = &talentpb.CreateClientEventRequest{
		Parent:      formattedParent,
		ClientEvent: clientEvent,
	}

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

	resp, err := c.CreateClientEvent(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 TestJobServiceCreateJob(t *testing.T) {
	var name string = "name3373707"
	var company string = "company950484093"
	var requisitionId string = "requisitionId980224926"
	var title string = "title110371416"
	var description string = "description-1724546052"
	var department string = "department848184146"
	var incentives string = "incentives-1262874520"
	var languageCode string = "languageCode-412800396"
	var promotionValue int32 = 353413845
	var qualifications string = "qualifications1903501412"
	var responsibilities string = "responsibilities-926952660"
	var companyDisplayName string = "companyDisplayName1982424170"
	var expectedResponse = &talentpb.Job{
		Name:               name,
		Company:            company,
		RequisitionId:      requisitionId,
		Title:              title,
		Description:        description,
		Department:         department,
		Incentives:         incentives,
		LanguageCode:       languageCode,
		PromotionValue:     promotionValue,
		Qualifications:     qualifications,
		Responsibilities:   responsibilities,
		CompanyDisplayName: companyDisplayName,
	}

	mockJob.err = nil
	mockJob.reqs = nil

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

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var job *talentpb.Job = &talentpb.Job{}
	var request = &talentpb.CreateJobRequest{
		Parent: formattedParent,
		Job:    job,
	}

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

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

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

	if want, got := request, mockJob.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 TestJobServiceCreateJobError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockJob.err = gstatus.Error(errCode, "test error")

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var job *talentpb.Job = &talentpb.Job{}
	var request = &talentpb.CreateJobRequest{
		Parent: formattedParent,
		Job:    job,
	}

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

	resp, err := c.CreateJob(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 TestJobServiceGetJob(t *testing.T) {
	var name2 string = "name2-1052831874"
	var company string = "company950484093"
	var requisitionId string = "requisitionId980224926"
	var title string = "title110371416"
	var description string = "description-1724546052"
	var department string = "department848184146"
	var incentives string = "incentives-1262874520"
	var languageCode string = "languageCode-412800396"
	var promotionValue int32 = 353413845
	var qualifications string = "qualifications1903501412"
	var responsibilities string = "responsibilities-926952660"
	var companyDisplayName string = "companyDisplayName1982424170"
	var expectedResponse = &talentpb.Job{
		Name:               name2,
		Company:            company,
		RequisitionId:      requisitionId,
		Title:              title,
		Description:        description,
		Department:         department,
		Incentives:         incentives,
		LanguageCode:       languageCode,
		PromotionValue:     promotionValue,
		Qualifications:     qualifications,
		Responsibilities:   responsibilities,
		CompanyDisplayName: companyDisplayName,
	}

	mockJob.err = nil
	mockJob.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/jobs/%s", "[PROJECT]", "[TENANT]", "[JOBS]")
	var request = &talentpb.GetJobRequest{
		Name: formattedName,
	}

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

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

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

	if want, got := request, mockJob.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 TestJobServiceGetJobError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockJob.err = gstatus.Error(errCode, "test error")

	var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/jobs/%s", "[PROJECT]", "[TENANT]", "[JOBS]")
	var request = &talentpb.GetJobRequest{
		Name: formattedName,
	}

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

	resp, err := c.GetJob(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 TestJobServiceUpdateJob(t *testing.T) {
	var name string = "name3373707"
	var company string = "company950484093"
	var requisitionId string = "requisitionId980224926"
	var title string = "title110371416"
	var description string = "description-1724546052"
	var department string = "department848184146"
	var incentives string = "incentives-1262874520"
	var languageCode string = "languageCode-412800396"
	var promotionValue int32 = 353413845
	var qualifications string = "qualifications1903501412"
	var responsibilities string = "responsibilities-926952660"
	var companyDisplayName string = "companyDisplayName1982424170"
	var expectedResponse = &talentpb.Job{
		Name:               name,
		Company:            company,
		RequisitionId:      requisitionId,
		Title:              title,
		Description:        description,
		Department:         department,
		Incentives:         incentives,
		LanguageCode:       languageCode,
		PromotionValue:     promotionValue,
		Qualifications:     qualifications,
		Responsibilities:   responsibilities,
		CompanyDisplayName: companyDisplayName,
	}

	mockJob.err = nil
	mockJob.reqs = nil

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

	var job *talentpb.Job = &talentpb.Job{}
	var request = &talentpb.UpdateJobRequest{
		Job: job,
	}

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

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

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

	if want, got := request, mockJob.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 TestJobServiceUpdateJobError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockJob.err = gstatus.Error(errCode, "test error")

	var job *talentpb.Job = &talentpb.Job{}
	var request = &talentpb.UpdateJobRequest{
		Job: job,
	}

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

	resp, err := c.UpdateJob(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 TestJobServiceDeleteJob(t *testing.T) {
	var expectedResponse *emptypb.Empty = &emptypb.Empty{}

	mockJob.err = nil
	mockJob.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/jobs/%s", "[PROJECT]", "[TENANT]", "[JOBS]")
	var request = &talentpb.DeleteJobRequest{
		Name: formattedName,
	}

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

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

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

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

}

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

	var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/jobs/%s", "[PROJECT]", "[TENANT]", "[JOBS]")
	var request = &talentpb.DeleteJobRequest{
		Name: formattedName,
	}

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

	err = c.DeleteJob(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 TestJobServiceListJobs(t *testing.T) {
	var nextPageToken string = ""
	var jobsElement *talentpb.Job = &talentpb.Job{}
	var jobs = []*talentpb.Job{jobsElement}
	var expectedResponse = &talentpb.ListJobsResponse{
		NextPageToken: nextPageToken,
		Jobs:          jobs,
	}

	mockJob.err = nil
	mockJob.reqs = nil

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

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var filter string = "filter-1274492040"
	var request = &talentpb.ListJobsRequest{
		Parent: formattedParent,
		Filter: filter,
	}

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

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

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

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

	want := (interface{})(expectedResponse.Jobs[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 TestJobServiceListJobsError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockJob.err = gstatus.Error(errCode, "test error")

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var filter string = "filter-1274492040"
	var request = &talentpb.ListJobsRequest{
		Parent: formattedParent,
		Filter: filter,
	}

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

	resp, err := c.ListJobs(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 TestJobServiceBatchDeleteJobs(t *testing.T) {
	var expectedResponse *emptypb.Empty = &emptypb.Empty{}

	mockJob.err = nil
	mockJob.reqs = nil

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

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var filter string = "filter-1274492040"
	var request = &talentpb.BatchDeleteJobsRequest{
		Parent: formattedParent,
		Filter: filter,
	}

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

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

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

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

}

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

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var filter string = "filter-1274492040"
	var request = &talentpb.BatchDeleteJobsRequest{
		Parent: formattedParent,
		Filter: filter,
	}

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

	err = c.BatchDeleteJobs(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 TestJobServiceSearchJobs(t *testing.T) {
	var nextPageToken string = ""
	var estimatedTotalSize int32 = 1882144769
	var totalSize int32 = 705419236
	var broadenedQueryJobsCount int32 = 1432104658
	var matchingJobsElement *talentpb.SearchJobsResponse_MatchingJob = &talentpb.SearchJobsResponse_MatchingJob{}
	var matchingJobs = []*talentpb.SearchJobsResponse_MatchingJob{matchingJobsElement}
	var expectedResponse = &talentpb.SearchJobsResponse{
		NextPageToken:           nextPageToken,
		EstimatedTotalSize:      estimatedTotalSize,
		TotalSize:               totalSize,
		BroadenedQueryJobsCount: broadenedQueryJobsCount,
		MatchingJobs:            matchingJobs,
	}

	mockJob.err = nil
	mockJob.reqs = nil

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

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var requestMetadata *talentpb.RequestMetadata = &talentpb.RequestMetadata{}
	var request = &talentpb.SearchJobsRequest{
		Parent:          formattedParent,
		RequestMetadata: requestMetadata,
	}

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

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

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

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

	want := (interface{})(expectedResponse.MatchingJobs[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 TestJobServiceSearchJobsError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockJob.err = gstatus.Error(errCode, "test error")

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var requestMetadata *talentpb.RequestMetadata = &talentpb.RequestMetadata{}
	var request = &talentpb.SearchJobsRequest{
		Parent:          formattedParent,
		RequestMetadata: requestMetadata,
	}

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

	resp, err := c.SearchJobs(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 TestJobServiceSearchJobsForAlert(t *testing.T) {
	var nextPageToken string = ""
	var estimatedTotalSize int32 = 1882144769
	var totalSize int32 = 705419236
	var broadenedQueryJobsCount int32 = 1432104658
	var matchingJobsElement *talentpb.SearchJobsResponse_MatchingJob = &talentpb.SearchJobsResponse_MatchingJob{}
	var matchingJobs = []*talentpb.SearchJobsResponse_MatchingJob{matchingJobsElement}
	var expectedResponse = &talentpb.SearchJobsResponse{
		NextPageToken:           nextPageToken,
		EstimatedTotalSize:      estimatedTotalSize,
		TotalSize:               totalSize,
		BroadenedQueryJobsCount: broadenedQueryJobsCount,
		MatchingJobs:            matchingJobs,
	}

	mockJob.err = nil
	mockJob.reqs = nil

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

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var requestMetadata *talentpb.RequestMetadata = &talentpb.RequestMetadata{}
	var request = &talentpb.SearchJobsRequest{
		Parent:          formattedParent,
		RequestMetadata: requestMetadata,
	}

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

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

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

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

	want := (interface{})(expectedResponse.MatchingJobs[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 TestJobServiceSearchJobsForAlertError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockJob.err = gstatus.Error(errCode, "test error")

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var requestMetadata *talentpb.RequestMetadata = &talentpb.RequestMetadata{}
	var request = &talentpb.SearchJobsRequest{
		Parent:          formattedParent,
		RequestMetadata: requestMetadata,
	}

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

	resp, err := c.SearchJobsForAlert(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 TestJobServiceBatchCreateJobs(t *testing.T) {
	var expectedResponse *talentpb.JobOperationResult = &talentpb.JobOperationResult{}

	mockJob.err = nil
	mockJob.reqs = nil

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

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var jobs []*talentpb.Job = nil
	var request = &talentpb.BatchCreateJobsRequest{
		Parent: formattedParent,
		Jobs:   jobs,
	}

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

	respLRO, err := c.BatchCreateJobs(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, mockJob.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 TestJobServiceBatchCreateJobsError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockJob.err = nil
	mockJob.resps = append(mockJob.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/tenants/%s", "[PROJECT]", "[TENANT]")
	var jobs []*talentpb.Job = nil
	var request = &talentpb.BatchCreateJobsRequest{
		Parent: formattedParent,
		Jobs:   jobs,
	}

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

	respLRO, err := c.BatchCreateJobs(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 TestJobServiceBatchUpdateJobs(t *testing.T) {
	var expectedResponse *talentpb.JobOperationResult = &talentpb.JobOperationResult{}

	mockJob.err = nil
	mockJob.reqs = nil

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

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var jobs []*talentpb.Job = nil
	var request = &talentpb.BatchUpdateJobsRequest{
		Parent: formattedParent,
		Jobs:   jobs,
	}

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

	respLRO, err := c.BatchUpdateJobs(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, mockJob.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 TestJobServiceBatchUpdateJobsError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockJob.err = nil
	mockJob.resps = append(mockJob.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/tenants/%s", "[PROJECT]", "[TENANT]")
	var jobs []*talentpb.Job = nil
	var request = &talentpb.BatchUpdateJobsRequest{
		Parent: formattedParent,
		Jobs:   jobs,
	}

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

	respLRO, err := c.BatchUpdateJobs(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 TestProfileServiceListProfiles(t *testing.T) {
	var nextPageToken string = ""
	var profilesElement *talentpb.Profile = &talentpb.Profile{}
	var profiles = []*talentpb.Profile{profilesElement}
	var expectedResponse = &talentpb.ListProfilesResponse{
		NextPageToken: nextPageToken,
		Profiles:      profiles,
	}

	mockProfile.err = nil
	mockProfile.reqs = nil

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

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var request = &talentpb.ListProfilesRequest{
		Parent: formattedParent,
	}

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

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

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

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

	want := (interface{})(expectedResponse.Profiles[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 TestProfileServiceListProfilesError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockProfile.err = gstatus.Error(errCode, "test error")

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var request = &talentpb.ListProfilesRequest{
		Parent: formattedParent,
	}

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

	resp, err := c.ListProfiles(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 TestProfileServiceCreateProfile(t *testing.T) {
	var name string = "name3373707"
	var externalId string = "externalId-1153075697"
	var source string = "source-896505829"
	var uri string = "uri116076"
	var groupId string = "groupId506361563"
	var processed bool = true
	var keywordSnippet string = "keywordSnippet1325317319"
	var expectedResponse = &talentpb.Profile{
		Name:           name,
		ExternalId:     externalId,
		Source:         source,
		Uri:            uri,
		GroupId:        groupId,
		Processed:      processed,
		KeywordSnippet: keywordSnippet,
	}

	mockProfile.err = nil
	mockProfile.reqs = nil

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

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var profile *talentpb.Profile = &talentpb.Profile{}
	var request = &talentpb.CreateProfileRequest{
		Parent:  formattedParent,
		Profile: profile,
	}

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

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

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

	if want, got := request, mockProfile.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 TestProfileServiceCreateProfileError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockProfile.err = gstatus.Error(errCode, "test error")

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var profile *talentpb.Profile = &talentpb.Profile{}
	var request = &talentpb.CreateProfileRequest{
		Parent:  formattedParent,
		Profile: profile,
	}

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

	resp, err := c.CreateProfile(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 TestProfileServiceGetProfile(t *testing.T) {
	var name2 string = "name2-1052831874"
	var externalId string = "externalId-1153075697"
	var source string = "source-896505829"
	var uri string = "uri116076"
	var groupId string = "groupId506361563"
	var processed bool = true
	var keywordSnippet string = "keywordSnippet1325317319"
	var expectedResponse = &talentpb.Profile{
		Name:           name2,
		ExternalId:     externalId,
		Source:         source,
		Uri:            uri,
		GroupId:        groupId,
		Processed:      processed,
		KeywordSnippet: keywordSnippet,
	}

	mockProfile.err = nil
	mockProfile.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/profiles/%s", "[PROJECT]", "[TENANT]", "[PROFILE]")
	var request = &talentpb.GetProfileRequest{
		Name: formattedName,
	}

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

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

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

	if want, got := request, mockProfile.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 TestProfileServiceGetProfileError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockProfile.err = gstatus.Error(errCode, "test error")

	var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/profiles/%s", "[PROJECT]", "[TENANT]", "[PROFILE]")
	var request = &talentpb.GetProfileRequest{
		Name: formattedName,
	}

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

	resp, err := c.GetProfile(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 TestProfileServiceUpdateProfile(t *testing.T) {
	var name string = "name3373707"
	var externalId string = "externalId-1153075697"
	var source string = "source-896505829"
	var uri string = "uri116076"
	var groupId string = "groupId506361563"
	var processed bool = true
	var keywordSnippet string = "keywordSnippet1325317319"
	var expectedResponse = &talentpb.Profile{
		Name:           name,
		ExternalId:     externalId,
		Source:         source,
		Uri:            uri,
		GroupId:        groupId,
		Processed:      processed,
		KeywordSnippet: keywordSnippet,
	}

	mockProfile.err = nil
	mockProfile.reqs = nil

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

	var profile *talentpb.Profile = &talentpb.Profile{}
	var request = &talentpb.UpdateProfileRequest{
		Profile: profile,
	}

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

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

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

	if want, got := request, mockProfile.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 TestProfileServiceUpdateProfileError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockProfile.err = gstatus.Error(errCode, "test error")

	var profile *talentpb.Profile = &talentpb.Profile{}
	var request = &talentpb.UpdateProfileRequest{
		Profile: profile,
	}

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

	resp, err := c.UpdateProfile(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 TestProfileServiceDeleteProfile(t *testing.T) {
	var expectedResponse *emptypb.Empty = &emptypb.Empty{}

	mockProfile.err = nil
	mockProfile.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/profiles/%s", "[PROJECT]", "[TENANT]", "[PROFILE]")
	var request = &talentpb.DeleteProfileRequest{
		Name: formattedName,
	}

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

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

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

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

}

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

	var formattedName string = fmt.Sprintf("projects/%s/tenants/%s/profiles/%s", "[PROJECT]", "[TENANT]", "[PROFILE]")
	var request = &talentpb.DeleteProfileRequest{
		Name: formattedName,
	}

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

	err = c.DeleteProfile(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 TestProfileServiceSearchProfiles(t *testing.T) {
	var estimatedTotalSize int64 = 1882144769
	var nextPageToken string = ""
	var resultSetId string = "resultSetId-770306950"
	var summarizedProfilesElement *talentpb.SummarizedProfile = &talentpb.SummarizedProfile{}
	var summarizedProfiles = []*talentpb.SummarizedProfile{summarizedProfilesElement}
	var expectedResponse = &talentpb.SearchProfilesResponse{
		EstimatedTotalSize: estimatedTotalSize,
		NextPageToken:      nextPageToken,
		ResultSetId:        resultSetId,
		SummarizedProfiles: summarizedProfiles,
	}

	mockProfile.err = nil
	mockProfile.reqs = nil

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

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var requestMetadata *talentpb.RequestMetadata = &talentpb.RequestMetadata{}
	var request = &talentpb.SearchProfilesRequest{
		Parent:          formattedParent,
		RequestMetadata: requestMetadata,
	}

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

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

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

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

	want := (interface{})(expectedResponse.SummarizedProfiles[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 TestProfileServiceSearchProfilesError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockProfile.err = gstatus.Error(errCode, "test error")

	var formattedParent string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var requestMetadata *talentpb.RequestMetadata = &talentpb.RequestMetadata{}
	var request = &talentpb.SearchProfilesRequest{
		Parent:          formattedParent,
		RequestMetadata: requestMetadata,
	}

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

	resp, err := c.SearchProfiles(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 TestTenantServiceCreateTenant(t *testing.T) {
	var name string = "name3373707"
	var externalId string = "externalId-1153075697"
	var expectedResponse = &talentpb.Tenant{
		Name:       name,
		ExternalId: externalId,
	}

	mockTenant.err = nil
	mockTenant.reqs = nil

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

	var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]")
	var tenant *talentpb.Tenant = &talentpb.Tenant{}
	var request = &talentpb.CreateTenantRequest{
		Parent: formattedParent,
		Tenant: tenant,
	}

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

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

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

	if want, got := request, mockTenant.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 TestTenantServiceCreateTenantError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockTenant.err = gstatus.Error(errCode, "test error")

	var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]")
	var tenant *talentpb.Tenant = &talentpb.Tenant{}
	var request = &talentpb.CreateTenantRequest{
		Parent: formattedParent,
		Tenant: tenant,
	}

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

	resp, err := c.CreateTenant(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 TestTenantServiceGetTenant(t *testing.T) {
	var name2 string = "name2-1052831874"
	var externalId string = "externalId-1153075697"
	var expectedResponse = &talentpb.Tenant{
		Name:       name2,
		ExternalId: externalId,
	}

	mockTenant.err = nil
	mockTenant.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var request = &talentpb.GetTenantRequest{
		Name: formattedName,
	}

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

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

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

	if want, got := request, mockTenant.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 TestTenantServiceGetTenantError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockTenant.err = gstatus.Error(errCode, "test error")

	var formattedName string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var request = &talentpb.GetTenantRequest{
		Name: formattedName,
	}

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

	resp, err := c.GetTenant(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 TestTenantServiceUpdateTenant(t *testing.T) {
	var name string = "name3373707"
	var externalId string = "externalId-1153075697"
	var expectedResponse = &talentpb.Tenant{
		Name:       name,
		ExternalId: externalId,
	}

	mockTenant.err = nil
	mockTenant.reqs = nil

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

	var tenant *talentpb.Tenant = &talentpb.Tenant{}
	var request = &talentpb.UpdateTenantRequest{
		Tenant: tenant,
	}

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

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

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

	if want, got := request, mockTenant.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 TestTenantServiceUpdateTenantError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockTenant.err = gstatus.Error(errCode, "test error")

	var tenant *talentpb.Tenant = &talentpb.Tenant{}
	var request = &talentpb.UpdateTenantRequest{
		Tenant: tenant,
	}

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

	resp, err := c.UpdateTenant(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 TestTenantServiceDeleteTenant(t *testing.T) {
	var expectedResponse *emptypb.Empty = &emptypb.Empty{}

	mockTenant.err = nil
	mockTenant.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var request = &talentpb.DeleteTenantRequest{
		Name: formattedName,
	}

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

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

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

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

}

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

	var formattedName string = fmt.Sprintf("projects/%s/tenants/%s", "[PROJECT]", "[TENANT]")
	var request = &talentpb.DeleteTenantRequest{
		Name: formattedName,
	}

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

	err = c.DeleteTenant(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 TestTenantServiceListTenants(t *testing.T) {
	var nextPageToken string = ""
	var tenantsElement *talentpb.Tenant = &talentpb.Tenant{}
	var tenants = []*talentpb.Tenant{tenantsElement}
	var expectedResponse = &talentpb.ListTenantsResponse{
		NextPageToken: nextPageToken,
		Tenants:       tenants,
	}

	mockTenant.err = nil
	mockTenant.reqs = nil

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

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

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

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

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

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

	want := (interface{})(expectedResponse.Tenants[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 TestTenantServiceListTenantsError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockTenant.err = gstatus.Error(errCode, "test error")

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

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

	resp, err := c.ListTenants(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
}
