// Copyright 2018 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 containeranalysis

import (
	emptypb "github.com/golang/protobuf/ptypes/empty"
	containeranalysispb "google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1"
	grafeaspb "google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1/grafeas"
	iampb "google.golang.org/genproto/googleapis/iam/v1"
)

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 mockContainerAnalysisV1Beta1Server struct {
	// Embed for forward compatibility.
	// Tests will keep working if more methods are added
	// in the future.
	containeranalysispb.ContainerAnalysisV1Beta1Server

	reqs []proto.Message

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

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

func (s *mockContainerAnalysisV1Beta1Server) SetIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest) (*iampb.Policy, 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].(*iampb.Policy), nil
}

func (s *mockContainerAnalysisV1Beta1Server) GetIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest) (*iampb.Policy, 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].(*iampb.Policy), nil
}

func (s *mockContainerAnalysisV1Beta1Server) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest) (*iampb.TestIamPermissionsResponse, 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].(*iampb.TestIamPermissionsResponse), nil
}

func (s *mockContainerAnalysisV1Beta1Server) GetScanConfig(ctx context.Context, req *containeranalysispb.GetScanConfigRequest) (*containeranalysispb.ScanConfig, 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].(*containeranalysispb.ScanConfig), nil
}

func (s *mockContainerAnalysisV1Beta1Server) ListScanConfigs(ctx context.Context, req *containeranalysispb.ListScanConfigsRequest) (*containeranalysispb.ListScanConfigsResponse, 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].(*containeranalysispb.ListScanConfigsResponse), nil
}

func (s *mockContainerAnalysisV1Beta1Server) UpdateScanConfig(ctx context.Context, req *containeranalysispb.UpdateScanConfigRequest) (*containeranalysispb.ScanConfig, 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].(*containeranalysispb.ScanConfig), nil
}

type mockGrafeasV1Beta1Server struct {
	// Embed for forward compatibility.
	// Tests will keep working if more methods are added
	// in the future.
	grafeaspb.GrafeasV1Beta1Server

	reqs []proto.Message

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

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

func (s *mockGrafeasV1Beta1Server) GetOccurrence(ctx context.Context, req *grafeaspb.GetOccurrenceRequest) (*grafeaspb.Occurrence, 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].(*grafeaspb.Occurrence), nil
}

func (s *mockGrafeasV1Beta1Server) ListOccurrences(ctx context.Context, req *grafeaspb.ListOccurrencesRequest) (*grafeaspb.ListOccurrencesResponse, 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].(*grafeaspb.ListOccurrencesResponse), nil
}

func (s *mockGrafeasV1Beta1Server) DeleteOccurrence(ctx context.Context, req *grafeaspb.DeleteOccurrenceRequest) (*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 *mockGrafeasV1Beta1Server) CreateOccurrence(ctx context.Context, req *grafeaspb.CreateOccurrenceRequest) (*grafeaspb.Occurrence, 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].(*grafeaspb.Occurrence), nil
}

func (s *mockGrafeasV1Beta1Server) BatchCreateOccurrences(ctx context.Context, req *grafeaspb.BatchCreateOccurrencesRequest) (*grafeaspb.BatchCreateOccurrencesResponse, 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].(*grafeaspb.BatchCreateOccurrencesResponse), nil
}

func (s *mockGrafeasV1Beta1Server) UpdateOccurrence(ctx context.Context, req *grafeaspb.UpdateOccurrenceRequest) (*grafeaspb.Occurrence, 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].(*grafeaspb.Occurrence), nil
}

func (s *mockGrafeasV1Beta1Server) GetOccurrenceNote(ctx context.Context, req *grafeaspb.GetOccurrenceNoteRequest) (*grafeaspb.Note, 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].(*grafeaspb.Note), nil
}

func (s *mockGrafeasV1Beta1Server) GetNote(ctx context.Context, req *grafeaspb.GetNoteRequest) (*grafeaspb.Note, 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].(*grafeaspb.Note), nil
}

func (s *mockGrafeasV1Beta1Server) ListNotes(ctx context.Context, req *grafeaspb.ListNotesRequest) (*grafeaspb.ListNotesResponse, 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].(*grafeaspb.ListNotesResponse), nil
}

func (s *mockGrafeasV1Beta1Server) DeleteNote(ctx context.Context, req *grafeaspb.DeleteNoteRequest) (*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 *mockGrafeasV1Beta1Server) CreateNote(ctx context.Context, req *grafeaspb.CreateNoteRequest) (*grafeaspb.Note, 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].(*grafeaspb.Note), nil
}

func (s *mockGrafeasV1Beta1Server) BatchCreateNotes(ctx context.Context, req *grafeaspb.BatchCreateNotesRequest) (*grafeaspb.BatchCreateNotesResponse, 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].(*grafeaspb.BatchCreateNotesResponse), nil
}

func (s *mockGrafeasV1Beta1Server) UpdateNote(ctx context.Context, req *grafeaspb.UpdateNoteRequest) (*grafeaspb.Note, 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].(*grafeaspb.Note), nil
}

func (s *mockGrafeasV1Beta1Server) ListNoteOccurrences(ctx context.Context, req *grafeaspb.ListNoteOccurrencesRequest) (*grafeaspb.ListNoteOccurrencesResponse, 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].(*grafeaspb.ListNoteOccurrencesResponse), nil
}

func (s *mockGrafeasV1Beta1Server) GetVulnerabilityOccurrencesSummary(ctx context.Context, req *grafeaspb.GetVulnerabilityOccurrencesSummaryRequest) (*grafeaspb.VulnerabilityOccurrencesSummary, 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].(*grafeaspb.VulnerabilityOccurrencesSummary), nil
}

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

var (
	mockContainerAnalysisV1Beta1 mockContainerAnalysisV1Beta1Server
	mockGrafeasV1Beta1           mockGrafeasV1Beta1Server
)

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

	serv := grpc.NewServer()
	containeranalysispb.RegisterContainerAnalysisV1Beta1Server(serv, &mockContainerAnalysisV1Beta1)
	grafeaspb.RegisterGrafeasV1Beta1Server(serv, &mockGrafeasV1Beta1)

	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 TestContainerAnalysisV1Beta1SetIamPolicy(t *testing.T) {
	var version int32 = 351608024
	var etag []byte = []byte("21")
	var expectedResponse = &iampb.Policy{
		Version: version,
		Etag:    etag,
	}

	mockContainerAnalysisV1Beta1.err = nil
	mockContainerAnalysisV1Beta1.reqs = nil

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

	var formattedResource string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]")
	var policy *iampb.Policy = &iampb.Policy{}
	var request = &iampb.SetIamPolicyRequest{
		Resource: formattedResource,
		Policy:   policy,
	}

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

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

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

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

	var formattedResource string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]")
	var policy *iampb.Policy = &iampb.Policy{}
	var request = &iampb.SetIamPolicyRequest{
		Resource: formattedResource,
		Policy:   policy,
	}

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

	resp, err := c.SetIamPolicy(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 TestContainerAnalysisV1Beta1GetIamPolicy(t *testing.T) {
	var version int32 = 351608024
	var etag []byte = []byte("21")
	var expectedResponse = &iampb.Policy{
		Version: version,
		Etag:    etag,
	}

	mockContainerAnalysisV1Beta1.err = nil
	mockContainerAnalysisV1Beta1.reqs = nil

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

	var formattedResource string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]")
	var request = &iampb.GetIamPolicyRequest{
		Resource: formattedResource,
	}

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

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

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

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

	var formattedResource string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]")
	var request = &iampb.GetIamPolicyRequest{
		Resource: formattedResource,
	}

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

	resp, err := c.GetIamPolicy(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 TestContainerAnalysisV1Beta1TestIamPermissions(t *testing.T) {
	var expectedResponse *iampb.TestIamPermissionsResponse = &iampb.TestIamPermissionsResponse{}

	mockContainerAnalysisV1Beta1.err = nil
	mockContainerAnalysisV1Beta1.reqs = nil

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

	var formattedResource string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]")
	var permissions []string = nil
	var request = &iampb.TestIamPermissionsRequest{
		Resource:    formattedResource,
		Permissions: permissions,
	}

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

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

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

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

	var formattedResource string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]")
	var permissions []string = nil
	var request = &iampb.TestIamPermissionsRequest{
		Resource:    formattedResource,
		Permissions: permissions,
	}

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

	resp, err := c.TestIamPermissions(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 TestContainerAnalysisV1Beta1GetScanConfig(t *testing.T) {
	var name2 string = "name2-1052831874"
	var description string = "description-1724546052"
	var enabled bool = false
	var expectedResponse = &containeranalysispb.ScanConfig{
		Name:        name2,
		Description: description,
		Enabled:     enabled,
	}

	mockContainerAnalysisV1Beta1.err = nil
	mockContainerAnalysisV1Beta1.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/scanConfigs/%s", "[PROJECT]", "[SCAN_CONFIG]")
	var request = &containeranalysispb.GetScanConfigRequest{
		Name: formattedName,
	}

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

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

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

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

	var formattedName string = fmt.Sprintf("projects/%s/scanConfigs/%s", "[PROJECT]", "[SCAN_CONFIG]")
	var request = &containeranalysispb.GetScanConfigRequest{
		Name: formattedName,
	}

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

	resp, err := c.GetScanConfig(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 TestContainerAnalysisV1Beta1ListScanConfigs(t *testing.T) {
	var nextPageToken string = ""
	var scanConfigsElement *containeranalysispb.ScanConfig = &containeranalysispb.ScanConfig{}
	var scanConfigs = []*containeranalysispb.ScanConfig{scanConfigsElement}
	var expectedResponse = &containeranalysispb.ListScanConfigsResponse{
		NextPageToken: nextPageToken,
		ScanConfigs:   scanConfigs,
	}

	mockContainerAnalysisV1Beta1.err = nil
	mockContainerAnalysisV1Beta1.reqs = nil

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

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

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

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

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

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

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

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

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

	resp, err := c.ListScanConfigs(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 TestContainerAnalysisV1Beta1UpdateScanConfig(t *testing.T) {
	var name2 string = "name2-1052831874"
	var description string = "description-1724546052"
	var enabled bool = false
	var expectedResponse = &containeranalysispb.ScanConfig{
		Name:        name2,
		Description: description,
		Enabled:     enabled,
	}

	mockContainerAnalysisV1Beta1.err = nil
	mockContainerAnalysisV1Beta1.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/scanConfigs/%s", "[PROJECT]", "[SCAN_CONFIG]")
	var scanConfig *containeranalysispb.ScanConfig = &containeranalysispb.ScanConfig{}
	var request = &containeranalysispb.UpdateScanConfigRequest{
		Name:       formattedName,
		ScanConfig: scanConfig,
	}

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

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

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

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

	var formattedName string = fmt.Sprintf("projects/%s/scanConfigs/%s", "[PROJECT]", "[SCAN_CONFIG]")
	var scanConfig *containeranalysispb.ScanConfig = &containeranalysispb.ScanConfig{}
	var request = &containeranalysispb.UpdateScanConfigRequest{
		Name:       formattedName,
		ScanConfig: scanConfig,
	}

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

	resp, err := c.UpdateScanConfig(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 TestGrafeasV1Beta1GetOccurrence(t *testing.T) {
	var name2 string = "name2-1052831874"
	var noteName string = "noteName1780787896"
	var remediation string = "remediation779381797"
	var expectedResponse = &grafeaspb.Occurrence{
		Name:        name2,
		NoteName:    noteName,
		Remediation: remediation,
	}

	mockGrafeasV1Beta1.err = nil
	mockGrafeasV1Beta1.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/occurrences/%s", "[PROJECT]", "[OCCURRENCE]")
	var request = &grafeaspb.GetOccurrenceRequest{
		Name: formattedName,
	}

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

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

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

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

	var formattedName string = fmt.Sprintf("projects/%s/occurrences/%s", "[PROJECT]", "[OCCURRENCE]")
	var request = &grafeaspb.GetOccurrenceRequest{
		Name: formattedName,
	}

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

	resp, err := c.GetOccurrence(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 TestGrafeasV1Beta1ListOccurrences(t *testing.T) {
	var nextPageToken string = ""
	var occurrencesElement *grafeaspb.Occurrence = &grafeaspb.Occurrence{}
	var occurrences = []*grafeaspb.Occurrence{occurrencesElement}
	var expectedResponse = &grafeaspb.ListOccurrencesResponse{
		NextPageToken: nextPageToken,
		Occurrences:   occurrences,
	}

	mockGrafeasV1Beta1.err = nil
	mockGrafeasV1Beta1.reqs = nil

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

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

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

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

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

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

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

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

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

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

	mockGrafeasV1Beta1.err = nil
	mockGrafeasV1Beta1.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/occurrences/%s", "[PROJECT]", "[OCCURRENCE]")
	var request = &grafeaspb.DeleteOccurrenceRequest{
		Name: formattedName,
	}

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

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

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

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

}

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

	var formattedName string = fmt.Sprintf("projects/%s/occurrences/%s", "[PROJECT]", "[OCCURRENCE]")
	var request = &grafeaspb.DeleteOccurrenceRequest{
		Name: formattedName,
	}

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

	err = c.DeleteOccurrence(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 TestGrafeasV1Beta1CreateOccurrence(t *testing.T) {
	var name string = "name3373707"
	var noteName string = "noteName1780787896"
	var remediation string = "remediation779381797"
	var expectedResponse = &grafeaspb.Occurrence{
		Name:        name,
		NoteName:    noteName,
		Remediation: remediation,
	}

	mockGrafeasV1Beta1.err = nil
	mockGrafeasV1Beta1.reqs = nil

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

	var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]")
	var occurrence *grafeaspb.Occurrence = &grafeaspb.Occurrence{}
	var request = &grafeaspb.CreateOccurrenceRequest{
		Parent:     formattedParent,
		Occurrence: occurrence,
	}

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

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

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

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

	var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]")
	var occurrence *grafeaspb.Occurrence = &grafeaspb.Occurrence{}
	var request = &grafeaspb.CreateOccurrenceRequest{
		Parent:     formattedParent,
		Occurrence: occurrence,
	}

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

	resp, err := c.CreateOccurrence(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 TestGrafeasV1Beta1BatchCreateOccurrences(t *testing.T) {
	var expectedResponse *grafeaspb.BatchCreateOccurrencesResponse = &grafeaspb.BatchCreateOccurrencesResponse{}

	mockGrafeasV1Beta1.err = nil
	mockGrafeasV1Beta1.reqs = nil

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

	var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]")
	var occurrences []*grafeaspb.Occurrence = nil
	var request = &grafeaspb.BatchCreateOccurrencesRequest{
		Parent:      formattedParent,
		Occurrences: occurrences,
	}

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

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

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

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

	var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]")
	var occurrences []*grafeaspb.Occurrence = nil
	var request = &grafeaspb.BatchCreateOccurrencesRequest{
		Parent:      formattedParent,
		Occurrences: occurrences,
	}

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

	resp, err := c.BatchCreateOccurrences(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 TestGrafeasV1Beta1UpdateOccurrence(t *testing.T) {
	var name2 string = "name2-1052831874"
	var noteName string = "noteName1780787896"
	var remediation string = "remediation779381797"
	var expectedResponse = &grafeaspb.Occurrence{
		Name:        name2,
		NoteName:    noteName,
		Remediation: remediation,
	}

	mockGrafeasV1Beta1.err = nil
	mockGrafeasV1Beta1.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/occurrences/%s", "[PROJECT]", "[OCCURRENCE]")
	var occurrence *grafeaspb.Occurrence = &grafeaspb.Occurrence{}
	var request = &grafeaspb.UpdateOccurrenceRequest{
		Name:       formattedName,
		Occurrence: occurrence,
	}

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

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

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

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

	var formattedName string = fmt.Sprintf("projects/%s/occurrences/%s", "[PROJECT]", "[OCCURRENCE]")
	var occurrence *grafeaspb.Occurrence = &grafeaspb.Occurrence{}
	var request = &grafeaspb.UpdateOccurrenceRequest{
		Name:       formattedName,
		Occurrence: occurrence,
	}

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

	resp, err := c.UpdateOccurrence(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 TestGrafeasV1Beta1GetOccurrenceNote(t *testing.T) {
	var name2 string = "name2-1052831874"
	var shortDescription string = "shortDescription-235369287"
	var longDescription string = "longDescription-1747792199"
	var expectedResponse = &grafeaspb.Note{
		Name:             name2,
		ShortDescription: shortDescription,
		LongDescription:  longDescription,
	}

	mockGrafeasV1Beta1.err = nil
	mockGrafeasV1Beta1.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/occurrences/%s", "[PROJECT]", "[OCCURRENCE]")
	var request = &grafeaspb.GetOccurrenceNoteRequest{
		Name: formattedName,
	}

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

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

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

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

	var formattedName string = fmt.Sprintf("projects/%s/occurrences/%s", "[PROJECT]", "[OCCURRENCE]")
	var request = &grafeaspb.GetOccurrenceNoteRequest{
		Name: formattedName,
	}

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

	resp, err := c.GetOccurrenceNote(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 TestGrafeasV1Beta1GetNote(t *testing.T) {
	var name2 string = "name2-1052831874"
	var shortDescription string = "shortDescription-235369287"
	var longDescription string = "longDescription-1747792199"
	var expectedResponse = &grafeaspb.Note{
		Name:             name2,
		ShortDescription: shortDescription,
		LongDescription:  longDescription,
	}

	mockGrafeasV1Beta1.err = nil
	mockGrafeasV1Beta1.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]")
	var request = &grafeaspb.GetNoteRequest{
		Name: formattedName,
	}

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

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

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

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

	var formattedName string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]")
	var request = &grafeaspb.GetNoteRequest{
		Name: formattedName,
	}

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

	resp, err := c.GetNote(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 TestGrafeasV1Beta1ListNotes(t *testing.T) {
	var nextPageToken string = ""
	var notesElement *grafeaspb.Note = &grafeaspb.Note{}
	var notes = []*grafeaspb.Note{notesElement}
	var expectedResponse = &grafeaspb.ListNotesResponse{
		NextPageToken: nextPageToken,
		Notes:         notes,
	}

	mockGrafeasV1Beta1.err = nil
	mockGrafeasV1Beta1.reqs = nil

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

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

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

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

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

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

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

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

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

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

	mockGrafeasV1Beta1.err = nil
	mockGrafeasV1Beta1.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]")
	var request = &grafeaspb.DeleteNoteRequest{
		Name: formattedName,
	}

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

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

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

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

}

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

	var formattedName string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]")
	var request = &grafeaspb.DeleteNoteRequest{
		Name: formattedName,
	}

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

	err = c.DeleteNote(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 TestGrafeasV1Beta1CreateNote(t *testing.T) {
	var name string = "name3373707"
	var shortDescription string = "shortDescription-235369287"
	var longDescription string = "longDescription-1747792199"
	var expectedResponse = &grafeaspb.Note{
		Name:             name,
		ShortDescription: shortDescription,
		LongDescription:  longDescription,
	}

	mockGrafeasV1Beta1.err = nil
	mockGrafeasV1Beta1.reqs = nil

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

	var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]")
	var noteId string = "noteId2129224840"
	var note *grafeaspb.Note = &grafeaspb.Note{}
	var request = &grafeaspb.CreateNoteRequest{
		Parent: formattedParent,
		NoteId: noteId,
		Note:   note,
	}

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

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

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

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

	var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]")
	var noteId string = "noteId2129224840"
	var note *grafeaspb.Note = &grafeaspb.Note{}
	var request = &grafeaspb.CreateNoteRequest{
		Parent: formattedParent,
		NoteId: noteId,
		Note:   note,
	}

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

	resp, err := c.CreateNote(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 TestGrafeasV1Beta1BatchCreateNotes(t *testing.T) {
	var expectedResponse *grafeaspb.BatchCreateNotesResponse = &grafeaspb.BatchCreateNotesResponse{}

	mockGrafeasV1Beta1.err = nil
	mockGrafeasV1Beta1.reqs = nil

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

	var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]")
	var notes map[string]*grafeaspb.Note = nil
	var request = &grafeaspb.BatchCreateNotesRequest{
		Parent: formattedParent,
		Notes:  notes,
	}

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

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

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

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

	var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]")
	var notes map[string]*grafeaspb.Note = nil
	var request = &grafeaspb.BatchCreateNotesRequest{
		Parent: formattedParent,
		Notes:  notes,
	}

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

	resp, err := c.BatchCreateNotes(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 TestGrafeasV1Beta1UpdateNote(t *testing.T) {
	var name2 string = "name2-1052831874"
	var shortDescription string = "shortDescription-235369287"
	var longDescription string = "longDescription-1747792199"
	var expectedResponse = &grafeaspb.Note{
		Name:             name2,
		ShortDescription: shortDescription,
		LongDescription:  longDescription,
	}

	mockGrafeasV1Beta1.err = nil
	mockGrafeasV1Beta1.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]")
	var note *grafeaspb.Note = &grafeaspb.Note{}
	var request = &grafeaspb.UpdateNoteRequest{
		Name: formattedName,
		Note: note,
	}

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

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

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

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

	var formattedName string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]")
	var note *grafeaspb.Note = &grafeaspb.Note{}
	var request = &grafeaspb.UpdateNoteRequest{
		Name: formattedName,
		Note: note,
	}

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

	resp, err := c.UpdateNote(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 TestGrafeasV1Beta1ListNoteOccurrences(t *testing.T) {
	var nextPageToken string = ""
	var occurrencesElement *grafeaspb.Occurrence = &grafeaspb.Occurrence{}
	var occurrences = []*grafeaspb.Occurrence{occurrencesElement}
	var expectedResponse = &grafeaspb.ListNoteOccurrencesResponse{
		NextPageToken: nextPageToken,
		Occurrences:   occurrences,
	}

	mockGrafeasV1Beta1.err = nil
	mockGrafeasV1Beta1.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]")
	var request = &grafeaspb.ListNoteOccurrencesRequest{
		Name: formattedName,
	}

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

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

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

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

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

	var formattedName string = fmt.Sprintf("projects/%s/notes/%s", "[PROJECT]", "[NOTE]")
	var request = &grafeaspb.ListNoteOccurrencesRequest{
		Name: formattedName,
	}

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

	resp, err := c.ListNoteOccurrences(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 TestGrafeasV1Beta1GetVulnerabilityOccurrencesSummary(t *testing.T) {
	var expectedResponse *grafeaspb.VulnerabilityOccurrencesSummary = &grafeaspb.VulnerabilityOccurrencesSummary{}

	mockGrafeasV1Beta1.err = nil
	mockGrafeasV1Beta1.reqs = nil

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

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

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

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

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

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

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

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

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