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

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

	"github.com/golang/protobuf/proto"
	"github.com/golang/protobuf/ptypes"
	timestamppb "github.com/golang/protobuf/ptypes/timestamp"
	"google.golang.org/api/option"
	securitycenterpb "google.golang.org/genproto/googleapis/cloud/securitycenter/v1"
	iampb "google.golang.org/genproto/googleapis/iam/v1"
	longrunningpb "google.golang.org/genproto/googleapis/longrunning"

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

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

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

type mockSecurityCenterServer struct {
	// Embed for forward compatibility.
	// Tests will keep working if more methods are added
	// in the future.
	securitycenterpb.SecurityCenterServer

	reqs []proto.Message

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

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

func (s *mockSecurityCenterServer) CreateSource(ctx context.Context, req *securitycenterpb.CreateSourceRequest) (*securitycenterpb.Source, 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].(*securitycenterpb.Source), nil
}

func (s *mockSecurityCenterServer) CreateFinding(ctx context.Context, req *securitycenterpb.CreateFindingRequest) (*securitycenterpb.Finding, 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].(*securitycenterpb.Finding), nil
}

func (s *mockSecurityCenterServer) 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 *mockSecurityCenterServer) GetOrganizationSettings(ctx context.Context, req *securitycenterpb.GetOrganizationSettingsRequest) (*securitycenterpb.OrganizationSettings, 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].(*securitycenterpb.OrganizationSettings), nil
}

func (s *mockSecurityCenterServer) GetSource(ctx context.Context, req *securitycenterpb.GetSourceRequest) (*securitycenterpb.Source, 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].(*securitycenterpb.Source), nil
}

func (s *mockSecurityCenterServer) GroupAssets(ctx context.Context, req *securitycenterpb.GroupAssetsRequest) (*securitycenterpb.GroupAssetsResponse, 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].(*securitycenterpb.GroupAssetsResponse), nil
}

func (s *mockSecurityCenterServer) GroupFindings(ctx context.Context, req *securitycenterpb.GroupFindingsRequest) (*securitycenterpb.GroupFindingsResponse, 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].(*securitycenterpb.GroupFindingsResponse), nil
}

func (s *mockSecurityCenterServer) ListAssets(ctx context.Context, req *securitycenterpb.ListAssetsRequest) (*securitycenterpb.ListAssetsResponse, 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].(*securitycenterpb.ListAssetsResponse), nil
}

func (s *mockSecurityCenterServer) ListFindings(ctx context.Context, req *securitycenterpb.ListFindingsRequest) (*securitycenterpb.ListFindingsResponse, 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].(*securitycenterpb.ListFindingsResponse), nil
}

func (s *mockSecurityCenterServer) ListSources(ctx context.Context, req *securitycenterpb.ListSourcesRequest) (*securitycenterpb.ListSourcesResponse, 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].(*securitycenterpb.ListSourcesResponse), nil
}

func (s *mockSecurityCenterServer) RunAssetDiscovery(ctx context.Context, req *securitycenterpb.RunAssetDiscoveryRequest) (*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 *mockSecurityCenterServer) SetFindingState(ctx context.Context, req *securitycenterpb.SetFindingStateRequest) (*securitycenterpb.Finding, 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].(*securitycenterpb.Finding), nil
}

func (s *mockSecurityCenterServer) 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 *mockSecurityCenterServer) 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 *mockSecurityCenterServer) UpdateFinding(ctx context.Context, req *securitycenterpb.UpdateFindingRequest) (*securitycenterpb.Finding, 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].(*securitycenterpb.Finding), nil
}

func (s *mockSecurityCenterServer) UpdateOrganizationSettings(ctx context.Context, req *securitycenterpb.UpdateOrganizationSettingsRequest) (*securitycenterpb.OrganizationSettings, 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].(*securitycenterpb.OrganizationSettings), nil
}

func (s *mockSecurityCenterServer) UpdateSource(ctx context.Context, req *securitycenterpb.UpdateSourceRequest) (*securitycenterpb.Source, 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].(*securitycenterpb.Source), nil
}

func (s *mockSecurityCenterServer) UpdateSecurityMarks(ctx context.Context, req *securitycenterpb.UpdateSecurityMarksRequest) (*securitycenterpb.SecurityMarks, 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].(*securitycenterpb.SecurityMarks), nil
}

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

var (
	mockSecurityCenter mockSecurityCenterServer
)

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

	serv := grpc.NewServer()
	securitycenterpb.RegisterSecurityCenterServer(serv, &mockSecurityCenter)

	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 TestSecurityCenterCreateSource(t *testing.T) {
	var name string = "name3373707"
	var displayName string = "displayName1615086568"
	var description string = "description-1724546052"
	var expectedResponse = &securitycenterpb.Source{
		Name:        name,
		DisplayName: displayName,
		Description: description,
	}

	mockSecurityCenter.err = nil
	mockSecurityCenter.reqs = nil

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

	var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]")
	var source *securitycenterpb.Source = &securitycenterpb.Source{}
	var request = &securitycenterpb.CreateSourceRequest{
		Parent: formattedParent,
		Source: source,
	}

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

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

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

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

	var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]")
	var source *securitycenterpb.Source = &securitycenterpb.Source{}
	var request = &securitycenterpb.CreateSourceRequest{
		Parent: formattedParent,
		Source: source,
	}

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

	resp, err := c.CreateSource(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 TestSecurityCenterCreateFinding(t *testing.T) {
	var name string = "name3373707"
	var parent2 string = "parent21175163357"
	var resourceName string = "resourceName979421212"
	var category string = "category50511102"
	var externalUri string = "externalUri-1385596168"
	var expectedResponse = &securitycenterpb.Finding{
		Name:         name,
		Parent:       parent2,
		ResourceName: resourceName,
		Category:     category,
		ExternalUri:  externalUri,
	}

	mockSecurityCenter.err = nil
	mockSecurityCenter.reqs = nil

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

	var formattedParent string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]")
	var findingId string = "findingId728776081"
	var finding *securitycenterpb.Finding = &securitycenterpb.Finding{}
	var request = &securitycenterpb.CreateFindingRequest{
		Parent:    formattedParent,
		FindingId: findingId,
		Finding:   finding,
	}

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

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

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

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

	var formattedParent string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]")
	var findingId string = "findingId728776081"
	var finding *securitycenterpb.Finding = &securitycenterpb.Finding{}
	var request = &securitycenterpb.CreateFindingRequest{
		Parent:    formattedParent,
		FindingId: findingId,
		Finding:   finding,
	}

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

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

	mockSecurityCenter.err = nil
	mockSecurityCenter.reqs = nil

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

	var formattedResource string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]")
	var request = &iampb.GetIamPolicyRequest{
		Resource: formattedResource,
	}

	c, err := NewClient(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, mockSecurityCenter.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 TestSecurityCenterGetIamPolicyError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockSecurityCenter.err = gstatus.Error(errCode, "test error")

	var formattedResource string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]")
	var request = &iampb.GetIamPolicyRequest{
		Resource: formattedResource,
	}

	c, err := NewClient(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 TestSecurityCenterGetOrganizationSettings(t *testing.T) {
	var name2 string = "name2-1052831874"
	var enableAssetDiscovery bool = false
	var expectedResponse = &securitycenterpb.OrganizationSettings{
		Name:                 name2,
		EnableAssetDiscovery: enableAssetDiscovery,
	}

	mockSecurityCenter.err = nil
	mockSecurityCenter.reqs = nil

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

	var formattedName string = fmt.Sprintf("organizations/%s/organizationSettings", "[ORGANIZATION]")
	var request = &securitycenterpb.GetOrganizationSettingsRequest{
		Name: formattedName,
	}

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

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

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

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

	var formattedName string = fmt.Sprintf("organizations/%s/organizationSettings", "[ORGANIZATION]")
	var request = &securitycenterpb.GetOrganizationSettingsRequest{
		Name: formattedName,
	}

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

	resp, err := c.GetOrganizationSettings(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 TestSecurityCenterGetSource(t *testing.T) {
	var name2 string = "name2-1052831874"
	var displayName string = "displayName1615086568"
	var description string = "description-1724546052"
	var expectedResponse = &securitycenterpb.Source{
		Name:        name2,
		DisplayName: displayName,
		Description: description,
	}

	mockSecurityCenter.err = nil
	mockSecurityCenter.reqs = nil

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

	var formattedName string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]")
	var request = &securitycenterpb.GetSourceRequest{
		Name: formattedName,
	}

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

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

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

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

	var formattedName string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]")
	var request = &securitycenterpb.GetSourceRequest{
		Name: formattedName,
	}

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

	resp, err := c.GetSource(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 TestSecurityCenterGroupAssets(t *testing.T) {
	var nextPageToken string = ""
	var totalSize int32 = 705419236
	var groupByResultsElement *securitycenterpb.GroupResult = &securitycenterpb.GroupResult{}
	var groupByResults = []*securitycenterpb.GroupResult{groupByResultsElement}
	var expectedResponse = &securitycenterpb.GroupAssetsResponse{
		NextPageToken:  nextPageToken,
		TotalSize:      totalSize,
		GroupByResults: groupByResults,
	}

	mockSecurityCenter.err = nil
	mockSecurityCenter.reqs = nil

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

	var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]")
	var groupBy string = "groupBy506361367"
	var request = &securitycenterpb.GroupAssetsRequest{
		Parent:  formattedParent,
		GroupBy: groupBy,
	}

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

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

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

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

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

	var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]")
	var groupBy string = "groupBy506361367"
	var request = &securitycenterpb.GroupAssetsRequest{
		Parent:  formattedParent,
		GroupBy: groupBy,
	}

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

	resp, err := c.GroupAssets(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 TestSecurityCenterGroupFindings(t *testing.T) {
	var nextPageToken string = ""
	var totalSize int32 = 705419236
	var groupByResultsElement *securitycenterpb.GroupResult = &securitycenterpb.GroupResult{}
	var groupByResults = []*securitycenterpb.GroupResult{groupByResultsElement}
	var expectedResponse = &securitycenterpb.GroupFindingsResponse{
		NextPageToken:  nextPageToken,
		TotalSize:      totalSize,
		GroupByResults: groupByResults,
	}

	mockSecurityCenter.err = nil
	mockSecurityCenter.reqs = nil

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

	var formattedParent string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]")
	var groupBy string = "groupBy506361367"
	var request = &securitycenterpb.GroupFindingsRequest{
		Parent:  formattedParent,
		GroupBy: groupBy,
	}

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

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

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

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

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

	var formattedParent string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]")
	var groupBy string = "groupBy506361367"
	var request = &securitycenterpb.GroupFindingsRequest{
		Parent:  formattedParent,
		GroupBy: groupBy,
	}

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

	resp, err := c.GroupFindings(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 TestSecurityCenterListAssets(t *testing.T) {
	var nextPageToken string = ""
	var totalSize int32 = 705419236
	var listAssetsResultsElement *securitycenterpb.ListAssetsResponse_ListAssetsResult = &securitycenterpb.ListAssetsResponse_ListAssetsResult{}
	var listAssetsResults = []*securitycenterpb.ListAssetsResponse_ListAssetsResult{listAssetsResultsElement}
	var expectedResponse = &securitycenterpb.ListAssetsResponse{
		NextPageToken:     nextPageToken,
		TotalSize:         totalSize,
		ListAssetsResults: listAssetsResults,
	}

	mockSecurityCenter.err = nil
	mockSecurityCenter.reqs = nil

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

	var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]")
	var request = &securitycenterpb.ListAssetsRequest{
		Parent: formattedParent,
	}

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

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

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

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

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

	var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]")
	var request = &securitycenterpb.ListAssetsRequest{
		Parent: formattedParent,
	}

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

	resp, err := c.ListAssets(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 TestSecurityCenterListFindings(t *testing.T) {
	var nextPageToken string = ""
	var totalSize int32 = 705419236
	var listFindingsResultsElement *securitycenterpb.ListFindingsResponse_ListFindingsResult = &securitycenterpb.ListFindingsResponse_ListFindingsResult{}
	var listFindingsResults = []*securitycenterpb.ListFindingsResponse_ListFindingsResult{listFindingsResultsElement}
	var expectedResponse = &securitycenterpb.ListFindingsResponse{
		NextPageToken:       nextPageToken,
		TotalSize:           totalSize,
		ListFindingsResults: listFindingsResults,
	}

	mockSecurityCenter.err = nil
	mockSecurityCenter.reqs = nil

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

	var formattedParent string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]")
	var request = &securitycenterpb.ListFindingsRequest{
		Parent: formattedParent,
	}

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

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

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

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

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

	var formattedParent string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]")
	var request = &securitycenterpb.ListFindingsRequest{
		Parent: formattedParent,
	}

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

	resp, err := c.ListFindings(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 TestSecurityCenterListSources(t *testing.T) {
	var nextPageToken string = ""
	var sourcesElement *securitycenterpb.Source = &securitycenterpb.Source{}
	var sources = []*securitycenterpb.Source{sourcesElement}
	var expectedResponse = &securitycenterpb.ListSourcesResponse{
		NextPageToken: nextPageToken,
		Sources:       sources,
	}

	mockSecurityCenter.err = nil
	mockSecurityCenter.reqs = nil

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

	var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]")
	var request = &securitycenterpb.ListSourcesRequest{
		Parent: formattedParent,
	}

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

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

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

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

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

	var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]")
	var request = &securitycenterpb.ListSourcesRequest{
		Parent: formattedParent,
	}

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

	resp, err := c.ListSources(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 TestSecurityCenterRunAssetDiscovery(t *testing.T) {
	var expectedResponse *securitycenterpb.RunAssetDiscoveryResponse = &securitycenterpb.RunAssetDiscoveryResponse{}

	mockSecurityCenter.err = nil
	mockSecurityCenter.reqs = nil

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

	var formattedParent string = fmt.Sprintf("organizations/%s", "[ORGANIZATION]")
	var request = &securitycenterpb.RunAssetDiscoveryRequest{
		Parent: formattedParent,
	}

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

	respLRO, err := c.RunAssetDiscovery(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, mockSecurityCenter.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 TestSecurityCenterRunAssetDiscoveryError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockSecurityCenter.err = nil
	mockSecurityCenter.resps = append(mockSecurityCenter.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("organizations/%s", "[ORGANIZATION]")
	var request = &securitycenterpb.RunAssetDiscoveryRequest{
		Parent: formattedParent,
	}

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

	respLRO, err := c.RunAssetDiscovery(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 TestSecurityCenterSetFindingState(t *testing.T) {
	var name2 string = "name2-1052831874"
	var parent string = "parent-995424086"
	var resourceName string = "resourceName979421212"
	var category string = "category50511102"
	var externalUri string = "externalUri-1385596168"
	var expectedResponse = &securitycenterpb.Finding{
		Name:         name2,
		Parent:       parent,
		ResourceName: resourceName,
		Category:     category,
		ExternalUri:  externalUri,
	}

	mockSecurityCenter.err = nil
	mockSecurityCenter.reqs = nil

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

	var formattedName string = fmt.Sprintf("organizations/%s/sources/%s/findings/%s", "[ORGANIZATION]", "[SOURCE]", "[FINDING]")
	var state securitycenterpb.Finding_State = securitycenterpb.Finding_STATE_UNSPECIFIED
	var startTime *timestamppb.Timestamp = &timestamppb.Timestamp{}
	var request = &securitycenterpb.SetFindingStateRequest{
		Name:      formattedName,
		State:     state,
		StartTime: startTime,
	}

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

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

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

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

	var formattedName string = fmt.Sprintf("organizations/%s/sources/%s/findings/%s", "[ORGANIZATION]", "[SOURCE]", "[FINDING]")
	var state securitycenterpb.Finding_State = securitycenterpb.Finding_STATE_UNSPECIFIED
	var startTime *timestamppb.Timestamp = &timestamppb.Timestamp{}
	var request = &securitycenterpb.SetFindingStateRequest{
		Name:      formattedName,
		State:     state,
		StartTime: startTime,
	}

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

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

	mockSecurityCenter.err = nil
	mockSecurityCenter.reqs = nil

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

	var formattedResource string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]")
	var policy *iampb.Policy = &iampb.Policy{}
	var request = &iampb.SetIamPolicyRequest{
		Resource: formattedResource,
		Policy:   policy,
	}

	c, err := NewClient(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, mockSecurityCenter.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 TestSecurityCenterSetIamPolicyError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockSecurityCenter.err = gstatus.Error(errCode, "test error")

	var formattedResource string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]")
	var policy *iampb.Policy = &iampb.Policy{}
	var request = &iampb.SetIamPolicyRequest{
		Resource: formattedResource,
		Policy:   policy,
	}

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

	mockSecurityCenter.err = nil
	mockSecurityCenter.reqs = nil

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

	var formattedResource string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]")
	var permissions []string = nil
	var request = &iampb.TestIamPermissionsRequest{
		Resource:    formattedResource,
		Permissions: permissions,
	}

	c, err := NewClient(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, mockSecurityCenter.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 TestSecurityCenterTestIamPermissionsError(t *testing.T) {
	errCode := codes.PermissionDenied
	mockSecurityCenter.err = gstatus.Error(errCode, "test error")

	var formattedResource string = fmt.Sprintf("organizations/%s/sources/%s", "[ORGANIZATION]", "[SOURCE]")
	var permissions []string = nil
	var request = &iampb.TestIamPermissionsRequest{
		Resource:    formattedResource,
		Permissions: permissions,
	}

	c, err := NewClient(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 TestSecurityCenterUpdateFinding(t *testing.T) {
	var name string = "name3373707"
	var parent string = "parent-995424086"
	var resourceName string = "resourceName979421212"
	var category string = "category50511102"
	var externalUri string = "externalUri-1385596168"
	var expectedResponse = &securitycenterpb.Finding{
		Name:         name,
		Parent:       parent,
		ResourceName: resourceName,
		Category:     category,
		ExternalUri:  externalUri,
	}

	mockSecurityCenter.err = nil
	mockSecurityCenter.reqs = nil

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

	var finding *securitycenterpb.Finding = &securitycenterpb.Finding{}
	var request = &securitycenterpb.UpdateFindingRequest{
		Finding: finding,
	}

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

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

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

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

	var finding *securitycenterpb.Finding = &securitycenterpb.Finding{}
	var request = &securitycenterpb.UpdateFindingRequest{
		Finding: finding,
	}

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

	resp, err := c.UpdateFinding(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 TestSecurityCenterUpdateOrganizationSettings(t *testing.T) {
	var name string = "name3373707"
	var enableAssetDiscovery bool = false
	var expectedResponse = &securitycenterpb.OrganizationSettings{
		Name:                 name,
		EnableAssetDiscovery: enableAssetDiscovery,
	}

	mockSecurityCenter.err = nil
	mockSecurityCenter.reqs = nil

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

	var organizationSettings *securitycenterpb.OrganizationSettings = &securitycenterpb.OrganizationSettings{}
	var request = &securitycenterpb.UpdateOrganizationSettingsRequest{
		OrganizationSettings: organizationSettings,
	}

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

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

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

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

	var organizationSettings *securitycenterpb.OrganizationSettings = &securitycenterpb.OrganizationSettings{}
	var request = &securitycenterpb.UpdateOrganizationSettingsRequest{
		OrganizationSettings: organizationSettings,
	}

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

	resp, err := c.UpdateOrganizationSettings(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 TestSecurityCenterUpdateSource(t *testing.T) {
	var name string = "name3373707"
	var displayName string = "displayName1615086568"
	var description string = "description-1724546052"
	var expectedResponse = &securitycenterpb.Source{
		Name:        name,
		DisplayName: displayName,
		Description: description,
	}

	mockSecurityCenter.err = nil
	mockSecurityCenter.reqs = nil

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

	var source *securitycenterpb.Source = &securitycenterpb.Source{}
	var request = &securitycenterpb.UpdateSourceRequest{
		Source: source,
	}

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

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

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

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

	var source *securitycenterpb.Source = &securitycenterpb.Source{}
	var request = &securitycenterpb.UpdateSourceRequest{
		Source: source,
	}

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

	resp, err := c.UpdateSource(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 TestSecurityCenterUpdateSecurityMarks(t *testing.T) {
	var name string = "name3373707"
	var expectedResponse = &securitycenterpb.SecurityMarks{
		Name: name,
	}

	mockSecurityCenter.err = nil
	mockSecurityCenter.reqs = nil

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

	var securityMarks *securitycenterpb.SecurityMarks = &securitycenterpb.SecurityMarks{}
	var request = &securitycenterpb.UpdateSecurityMarksRequest{
		SecurityMarks: securityMarks,
	}

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

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

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

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

	var securityMarks *securitycenterpb.SecurityMarks = &securitycenterpb.SecurityMarks{}
	var request = &securitycenterpb.UpdateSecurityMarksRequest{
		SecurityMarks: securityMarks,
	}

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

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