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

import (
	emptypb "github.com/golang/protobuf/ptypes/empty"
	irmpb "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2"
)

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

	reqs []proto.Message

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

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

func (s *mockIncidentServer) CreateIncident(ctx context.Context, req *irmpb.CreateIncidentRequest) (*irmpb.Incident, 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].(*irmpb.Incident), nil
}

func (s *mockIncidentServer) GetIncident(ctx context.Context, req *irmpb.GetIncidentRequest) (*irmpb.Incident, 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].(*irmpb.Incident), nil
}

func (s *mockIncidentServer) SearchIncidents(ctx context.Context, req *irmpb.SearchIncidentsRequest) (*irmpb.SearchIncidentsResponse, 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].(*irmpb.SearchIncidentsResponse), nil
}

func (s *mockIncidentServer) UpdateIncident(ctx context.Context, req *irmpb.UpdateIncidentRequest) (*irmpb.Incident, 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].(*irmpb.Incident), nil
}

func (s *mockIncidentServer) SearchSimilarIncidents(ctx context.Context, req *irmpb.SearchSimilarIncidentsRequest) (*irmpb.SearchSimilarIncidentsResponse, 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].(*irmpb.SearchSimilarIncidentsResponse), nil
}

func (s *mockIncidentServer) CreateAnnotation(ctx context.Context, req *irmpb.CreateAnnotationRequest) (*irmpb.Annotation, 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].(*irmpb.Annotation), nil
}

func (s *mockIncidentServer) ListAnnotations(ctx context.Context, req *irmpb.ListAnnotationsRequest) (*irmpb.ListAnnotationsResponse, 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].(*irmpb.ListAnnotationsResponse), nil
}

func (s *mockIncidentServer) CreateTag(ctx context.Context, req *irmpb.CreateTagRequest) (*irmpb.Tag, 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].(*irmpb.Tag), nil
}

func (s *mockIncidentServer) DeleteTag(ctx context.Context, req *irmpb.DeleteTagRequest) (*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 *mockIncidentServer) ListTags(ctx context.Context, req *irmpb.ListTagsRequest) (*irmpb.ListTagsResponse, 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].(*irmpb.ListTagsResponse), nil
}

func (s *mockIncidentServer) CreateSignal(ctx context.Context, req *irmpb.CreateSignalRequest) (*irmpb.Signal, 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].(*irmpb.Signal), nil
}

func (s *mockIncidentServer) SearchSignals(ctx context.Context, req *irmpb.SearchSignalsRequest) (*irmpb.SearchSignalsResponse, 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].(*irmpb.SearchSignalsResponse), nil
}

func (s *mockIncidentServer) LookupSignal(ctx context.Context, req *irmpb.LookupSignalRequest) (*irmpb.Signal, 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].(*irmpb.Signal), nil
}

func (s *mockIncidentServer) GetSignal(ctx context.Context, req *irmpb.GetSignalRequest) (*irmpb.Signal, 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].(*irmpb.Signal), nil
}

func (s *mockIncidentServer) UpdateSignal(ctx context.Context, req *irmpb.UpdateSignalRequest) (*irmpb.Signal, 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].(*irmpb.Signal), nil
}

func (s *mockIncidentServer) EscalateIncident(ctx context.Context, req *irmpb.EscalateIncidentRequest) (*irmpb.EscalateIncidentResponse, 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].(*irmpb.EscalateIncidentResponse), nil
}

func (s *mockIncidentServer) CreateArtifact(ctx context.Context, req *irmpb.CreateArtifactRequest) (*irmpb.Artifact, 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].(*irmpb.Artifact), nil
}

func (s *mockIncidentServer) ListArtifacts(ctx context.Context, req *irmpb.ListArtifactsRequest) (*irmpb.ListArtifactsResponse, 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].(*irmpb.ListArtifactsResponse), nil
}

func (s *mockIncidentServer) UpdateArtifact(ctx context.Context, req *irmpb.UpdateArtifactRequest) (*irmpb.Artifact, 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].(*irmpb.Artifact), nil
}

func (s *mockIncidentServer) DeleteArtifact(ctx context.Context, req *irmpb.DeleteArtifactRequest) (*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 *mockIncidentServer) SendShiftHandoff(ctx context.Context, req *irmpb.SendShiftHandoffRequest) (*irmpb.SendShiftHandoffResponse, 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].(*irmpb.SendShiftHandoffResponse), nil
}

func (s *mockIncidentServer) CreateSubscription(ctx context.Context, req *irmpb.CreateSubscriptionRequest) (*irmpb.Subscription, 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].(*irmpb.Subscription), nil
}

func (s *mockIncidentServer) UpdateSubscription(ctx context.Context, req *irmpb.UpdateSubscriptionRequest) (*irmpb.Subscription, 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].(*irmpb.Subscription), nil
}

func (s *mockIncidentServer) ListSubscriptions(ctx context.Context, req *irmpb.ListSubscriptionsRequest) (*irmpb.ListSubscriptionsResponse, 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].(*irmpb.ListSubscriptionsResponse), nil
}

func (s *mockIncidentServer) DeleteSubscription(ctx context.Context, req *irmpb.DeleteSubscriptionRequest) (*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 *mockIncidentServer) CreateIncidentRoleAssignment(ctx context.Context, req *irmpb.CreateIncidentRoleAssignmentRequest) (*irmpb.IncidentRoleAssignment, 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].(*irmpb.IncidentRoleAssignment), nil
}

func (s *mockIncidentServer) DeleteIncidentRoleAssignment(ctx context.Context, req *irmpb.DeleteIncidentRoleAssignmentRequest) (*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 *mockIncidentServer) ListIncidentRoleAssignments(ctx context.Context, req *irmpb.ListIncidentRoleAssignmentsRequest) (*irmpb.ListIncidentRoleAssignmentsResponse, 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].(*irmpb.ListIncidentRoleAssignmentsResponse), nil
}

func (s *mockIncidentServer) RequestIncidentRoleHandover(ctx context.Context, req *irmpb.RequestIncidentRoleHandoverRequest) (*irmpb.IncidentRoleAssignment, 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].(*irmpb.IncidentRoleAssignment), nil
}

func (s *mockIncidentServer) ConfirmIncidentRoleHandover(ctx context.Context, req *irmpb.ConfirmIncidentRoleHandoverRequest) (*irmpb.IncidentRoleAssignment, 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].(*irmpb.IncidentRoleAssignment), nil
}

func (s *mockIncidentServer) ForceIncidentRoleHandover(ctx context.Context, req *irmpb.ForceIncidentRoleHandoverRequest) (*irmpb.IncidentRoleAssignment, 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].(*irmpb.IncidentRoleAssignment), nil
}

func (s *mockIncidentServer) CancelIncidentRoleHandover(ctx context.Context, req *irmpb.CancelIncidentRoleHandoverRequest) (*irmpb.IncidentRoleAssignment, 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].(*irmpb.IncidentRoleAssignment), nil
}

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

var (
	mockIncident mockIncidentServer
)

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

	serv := grpc.NewServer()
	irmpb.RegisterIncidentServiceServer(serv, &mockIncident)

	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 TestIncidentServiceCreateIncident(t *testing.T) {
	var name string = "name3373707"
	var title string = "title110371416"
	var etag string = "etag3123477"
	var duplicateIncident string = "duplicateIncident-316496506"
	var expectedResponse = &irmpb.Incident{
		Name:              name,
		Title:             title,
		Etag:              etag,
		DuplicateIncident: duplicateIncident,
	}

	mockIncident.err = nil
	mockIncident.reqs = nil

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

	var incident *irmpb.Incident = &irmpb.Incident{}
	var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]")
	var request = &irmpb.CreateIncidentRequest{
		Incident: incident,
		Parent:   formattedParent,
	}

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

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

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

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

	var incident *irmpb.Incident = &irmpb.Incident{}
	var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]")
	var request = &irmpb.CreateIncidentRequest{
		Incident: incident,
		Parent:   formattedParent,
	}

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

	resp, err := c.CreateIncident(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 TestIncidentServiceGetIncident(t *testing.T) {
	var name2 string = "name2-1052831874"
	var title string = "title110371416"
	var etag string = "etag3123477"
	var duplicateIncident string = "duplicateIncident-316496506"
	var expectedResponse = &irmpb.Incident{
		Name:              name2,
		Title:             title,
		Etag:              etag,
		DuplicateIncident: duplicateIncident,
	}

	mockIncident.err = nil
	mockIncident.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]")
	var request = &irmpb.GetIncidentRequest{
		Name: formattedName,
	}

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

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

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

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

	var formattedName string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]")
	var request = &irmpb.GetIncidentRequest{
		Name: formattedName,
	}

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

	resp, err := c.GetIncident(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 TestIncidentServiceSearchIncidents(t *testing.T) {
	var nextPageToken string = ""
	var incidentsElement *irmpb.Incident = &irmpb.Incident{}
	var incidents = []*irmpb.Incident{incidentsElement}
	var expectedResponse = &irmpb.SearchIncidentsResponse{
		NextPageToken: nextPageToken,
		Incidents:     incidents,
	}

	mockIncident.err = nil
	mockIncident.reqs = nil

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

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

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

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

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

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

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

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

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

	resp, err := c.SearchIncidents(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 TestIncidentServiceUpdateIncident(t *testing.T) {
	var name string = "name3373707"
	var title string = "title110371416"
	var etag string = "etag3123477"
	var duplicateIncident string = "duplicateIncident-316496506"
	var expectedResponse = &irmpb.Incident{
		Name:              name,
		Title:             title,
		Etag:              etag,
		DuplicateIncident: duplicateIncident,
	}

	mockIncident.err = nil
	mockIncident.reqs = nil

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

	var incident *irmpb.Incident = &irmpb.Incident{}
	var request = &irmpb.UpdateIncidentRequest{
		Incident: incident,
	}

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

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

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

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

	var incident *irmpb.Incident = &irmpb.Incident{}
	var request = &irmpb.UpdateIncidentRequest{
		Incident: incident,
	}

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

	resp, err := c.UpdateIncident(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 TestIncidentServiceSearchSimilarIncidents(t *testing.T) {
	var nextPageToken string = ""
	var resultsElement *irmpb.SearchSimilarIncidentsResponse_Result = &irmpb.SearchSimilarIncidentsResponse_Result{}
	var results = []*irmpb.SearchSimilarIncidentsResponse_Result{resultsElement}
	var expectedResponse = &irmpb.SearchSimilarIncidentsResponse{
		NextPageToken: nextPageToken,
		Results:       results,
	}

	mockIncident.err = nil
	mockIncident.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]")
	var request = &irmpb.SearchSimilarIncidentsRequest{
		Name: formattedName,
	}

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

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

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

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

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

	var formattedName string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]")
	var request = &irmpb.SearchSimilarIncidentsRequest{
		Name: formattedName,
	}

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

	resp, err := c.SearchSimilarIncidents(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 TestIncidentServiceCreateAnnotation(t *testing.T) {
	var name string = "name3373707"
	var content string = "content951530617"
	var contentType string = "contentType831846208"
	var expectedResponse = &irmpb.Annotation{
		Name:        name,
		Content:     content,
		ContentType: contentType,
	}

	mockIncident.err = nil
	mockIncident.reqs = nil

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

	var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]")
	var annotation *irmpb.Annotation = &irmpb.Annotation{}
	var request = &irmpb.CreateAnnotationRequest{
		Parent:     formattedParent,
		Annotation: annotation,
	}

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

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

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

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

	var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]")
	var annotation *irmpb.Annotation = &irmpb.Annotation{}
	var request = &irmpb.CreateAnnotationRequest{
		Parent:     formattedParent,
		Annotation: annotation,
	}

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

	resp, err := c.CreateAnnotation(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 TestIncidentServiceListAnnotations(t *testing.T) {
	var nextPageToken string = ""
	var annotationsElement *irmpb.Annotation = &irmpb.Annotation{}
	var annotations = []*irmpb.Annotation{annotationsElement}
	var expectedResponse = &irmpb.ListAnnotationsResponse{
		NextPageToken: nextPageToken,
		Annotations:   annotations,
	}

	mockIncident.err = nil
	mockIncident.reqs = nil

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

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

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

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

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

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

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

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

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

	resp, err := c.ListAnnotations(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 TestIncidentServiceCreateTag(t *testing.T) {
	var name string = "name3373707"
	var displayName string = "displayName1615086568"
	var expectedResponse = &irmpb.Tag{
		Name:        name,
		DisplayName: displayName,
	}

	mockIncident.err = nil
	mockIncident.reqs = nil

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

	var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]")
	var tag *irmpb.Tag = &irmpb.Tag{}
	var request = &irmpb.CreateTagRequest{
		Parent: formattedParent,
		Tag:    tag,
	}

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

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

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

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

	var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]")
	var tag *irmpb.Tag = &irmpb.Tag{}
	var request = &irmpb.CreateTagRequest{
		Parent: formattedParent,
		Tag:    tag,
	}

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

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

	mockIncident.err = nil
	mockIncident.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/tags/%s", "[PROJECT]", "[INCIDENT]", "[TAG]")
	var request = &irmpb.DeleteTagRequest{
		Name: formattedName,
	}

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

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

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

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

}

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

	var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/tags/%s", "[PROJECT]", "[INCIDENT]", "[TAG]")
	var request = &irmpb.DeleteTagRequest{
		Name: formattedName,
	}

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

	err = c.DeleteTag(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 TestIncidentServiceListTags(t *testing.T) {
	var nextPageToken string = ""
	var tagsElement *irmpb.Tag = &irmpb.Tag{}
	var tags = []*irmpb.Tag{tagsElement}
	var expectedResponse = &irmpb.ListTagsResponse{
		NextPageToken: nextPageToken,
		Tags:          tags,
	}

	mockIncident.err = nil
	mockIncident.reqs = nil

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

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

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

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

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

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

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

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

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

	resp, err := c.ListTags(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 TestIncidentServiceCreateSignal(t *testing.T) {
	var name string = "name3373707"
	var etag string = "etag3123477"
	var incident string = "incident86983890"
	var title string = "title110371416"
	var contentType string = "contentType831846208"
	var content string = "content951530617"
	var expectedResponse = &irmpb.Signal{
		Name:        name,
		Etag:        etag,
		Incident:    incident,
		Title:       title,
		ContentType: contentType,
		Content:     content,
	}

	mockIncident.err = nil
	mockIncident.reqs = nil

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

	var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]")
	var signal *irmpb.Signal = &irmpb.Signal{}
	var request = &irmpb.CreateSignalRequest{
		Parent: formattedParent,
		Signal: signal,
	}

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

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

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

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

	var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]")
	var signal *irmpb.Signal = &irmpb.Signal{}
	var request = &irmpb.CreateSignalRequest{
		Parent: formattedParent,
		Signal: signal,
	}

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

	resp, err := c.CreateSignal(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 TestIncidentServiceSearchSignals(t *testing.T) {
	var nextPageToken string = ""
	var signalsElement *irmpb.Signal = &irmpb.Signal{}
	var signals = []*irmpb.Signal{signalsElement}
	var expectedResponse = &irmpb.SearchSignalsResponse{
		NextPageToken: nextPageToken,
		Signals:       signals,
	}

	mockIncident.err = nil
	mockIncident.reqs = nil

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

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

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

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

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

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

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

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

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

	resp, err := c.SearchSignals(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 TestIncidentServiceGetSignal(t *testing.T) {
	var name2 string = "name2-1052831874"
	var etag string = "etag3123477"
	var incident string = "incident86983890"
	var title string = "title110371416"
	var contentType string = "contentType831846208"
	var content string = "content951530617"
	var expectedResponse = &irmpb.Signal{
		Name:        name2,
		Etag:        etag,
		Incident:    incident,
		Title:       title,
		ContentType: contentType,
		Content:     content,
	}

	mockIncident.err = nil
	mockIncident.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/signals/%s", "[PROJECT]", "[SIGNAL]")
	var request = &irmpb.GetSignalRequest{
		Name: formattedName,
	}

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

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

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

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

	var formattedName string = fmt.Sprintf("projects/%s/signals/%s", "[PROJECT]", "[SIGNAL]")
	var request = &irmpb.GetSignalRequest{
		Name: formattedName,
	}

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

	resp, err := c.GetSignal(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 TestIncidentServiceLookupSignal(t *testing.T) {
	var name string = "name3373707"
	var etag string = "etag3123477"
	var incident string = "incident86983890"
	var title string = "title110371416"
	var contentType string = "contentType831846208"
	var content string = "content951530617"
	var expectedResponse = &irmpb.Signal{
		Name:        name,
		Etag:        etag,
		Incident:    incident,
		Title:       title,
		ContentType: contentType,
		Content:     content,
	}

	mockIncident.err = nil
	mockIncident.reqs = nil

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

	var request *irmpb.LookupSignalRequest = &irmpb.LookupSignalRequest{}

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

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

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

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

	var request *irmpb.LookupSignalRequest = &irmpb.LookupSignalRequest{}

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

	resp, err := c.LookupSignal(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 TestIncidentServiceUpdateSignal(t *testing.T) {
	var name string = "name3373707"
	var etag string = "etag3123477"
	var incident string = "incident86983890"
	var title string = "title110371416"
	var contentType string = "contentType831846208"
	var content string = "content951530617"
	var expectedResponse = &irmpb.Signal{
		Name:        name,
		Etag:        etag,
		Incident:    incident,
		Title:       title,
		ContentType: contentType,
		Content:     content,
	}

	mockIncident.err = nil
	mockIncident.reqs = nil

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

	var signal *irmpb.Signal = &irmpb.Signal{}
	var request = &irmpb.UpdateSignalRequest{
		Signal: signal,
	}

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

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

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

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

	var signal *irmpb.Signal = &irmpb.Signal{}
	var request = &irmpb.UpdateSignalRequest{
		Signal: signal,
	}

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

	resp, err := c.UpdateSignal(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 TestIncidentServiceEscalateIncident(t *testing.T) {
	var expectedResponse *irmpb.EscalateIncidentResponse = &irmpb.EscalateIncidentResponse{}

	mockIncident.err = nil
	mockIncident.reqs = nil

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

	var incident *irmpb.Incident = &irmpb.Incident{}
	var request = &irmpb.EscalateIncidentRequest{
		Incident: incident,
	}

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

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

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

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

	var incident *irmpb.Incident = &irmpb.Incident{}
	var request = &irmpb.EscalateIncidentRequest{
		Incident: incident,
	}

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

	resp, err := c.EscalateIncident(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 TestIncidentServiceCreateArtifact(t *testing.T) {
	var name string = "name3373707"
	var displayName string = "displayName1615086568"
	var etag string = "etag3123477"
	var url string = "url116079"
	var expectedResponse = &irmpb.Artifact{
		Name:        name,
		DisplayName: displayName,
		Etag:        etag,
		Url:         url,
	}

	mockIncident.err = nil
	mockIncident.reqs = nil

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

	var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]")
	var artifact *irmpb.Artifact = &irmpb.Artifact{}
	var request = &irmpb.CreateArtifactRequest{
		Parent:   formattedParent,
		Artifact: artifact,
	}

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

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

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

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

	var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]")
	var artifact *irmpb.Artifact = &irmpb.Artifact{}
	var request = &irmpb.CreateArtifactRequest{
		Parent:   formattedParent,
		Artifact: artifact,
	}

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

	resp, err := c.CreateArtifact(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 TestIncidentServiceListArtifacts(t *testing.T) {
	var nextPageToken string = ""
	var artifactsElement *irmpb.Artifact = &irmpb.Artifact{}
	var artifacts = []*irmpb.Artifact{artifactsElement}
	var expectedResponse = &irmpb.ListArtifactsResponse{
		NextPageToken: nextPageToken,
		Artifacts:     artifacts,
	}

	mockIncident.err = nil
	mockIncident.reqs = nil

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

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

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

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

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

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

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

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

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

	resp, err := c.ListArtifacts(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 TestIncidentServiceUpdateArtifact(t *testing.T) {
	var name string = "name3373707"
	var displayName string = "displayName1615086568"
	var etag string = "etag3123477"
	var url string = "url116079"
	var expectedResponse = &irmpb.Artifact{
		Name:        name,
		DisplayName: displayName,
		Etag:        etag,
		Url:         url,
	}

	mockIncident.err = nil
	mockIncident.reqs = nil

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

	var artifact *irmpb.Artifact = &irmpb.Artifact{}
	var request = &irmpb.UpdateArtifactRequest{
		Artifact: artifact,
	}

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

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

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

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

	var artifact *irmpb.Artifact = &irmpb.Artifact{}
	var request = &irmpb.UpdateArtifactRequest{
		Artifact: artifact,
	}

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

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

	mockIncident.err = nil
	mockIncident.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/artifacts/%s", "[PROJECT]", "[INCIDENT]", "[ARTIFACT]")
	var request = &irmpb.DeleteArtifactRequest{
		Name: formattedName,
	}

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

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

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

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

}

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

	var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/artifacts/%s", "[PROJECT]", "[INCIDENT]", "[ARTIFACT]")
	var request = &irmpb.DeleteArtifactRequest{
		Name: formattedName,
	}

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

	err = c.DeleteArtifact(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 TestIncidentServiceSendShiftHandoff(t *testing.T) {
	var contentType string = "contentType831846208"
	var content string = "content951530617"
	var expectedResponse = &irmpb.SendShiftHandoffResponse{
		ContentType: contentType,
		Content:     content,
	}

	mockIncident.err = nil
	mockIncident.reqs = nil

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

	var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]")
	var recipients []string = nil
	var subject string = "subject-1867885268"
	var request = &irmpb.SendShiftHandoffRequest{
		Parent:     formattedParent,
		Recipients: recipients,
		Subject:    subject,
	}

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

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

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

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

	var formattedParent string = fmt.Sprintf("projects/%s", "[PROJECT]")
	var recipients []string = nil
	var subject string = "subject-1867885268"
	var request = &irmpb.SendShiftHandoffRequest{
		Parent:     formattedParent,
		Recipients: recipients,
		Subject:    subject,
	}

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

	resp, err := c.SendShiftHandoff(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 TestIncidentServiceCreateSubscription(t *testing.T) {
	var name string = "name3373707"
	var etag string = "etag3123477"
	var expectedResponse = &irmpb.Subscription{
		Name: name,
		Etag: etag,
	}

	mockIncident.err = nil
	mockIncident.reqs = nil

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

	var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]")
	var subscription *irmpb.Subscription = &irmpb.Subscription{}
	var request = &irmpb.CreateSubscriptionRequest{
		Parent:       formattedParent,
		Subscription: subscription,
	}

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

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

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

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

	var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]")
	var subscription *irmpb.Subscription = &irmpb.Subscription{}
	var request = &irmpb.CreateSubscriptionRequest{
		Parent:       formattedParent,
		Subscription: subscription,
	}

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

	resp, err := c.CreateSubscription(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 TestIncidentServiceUpdateSubscription(t *testing.T) {
	var name string = "name3373707"
	var etag string = "etag3123477"
	var expectedResponse = &irmpb.Subscription{
		Name: name,
		Etag: etag,
	}

	mockIncident.err = nil
	mockIncident.reqs = nil

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

	var subscription *irmpb.Subscription = &irmpb.Subscription{}
	var request = &irmpb.UpdateSubscriptionRequest{
		Subscription: subscription,
	}

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

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

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

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

	var subscription *irmpb.Subscription = &irmpb.Subscription{}
	var request = &irmpb.UpdateSubscriptionRequest{
		Subscription: subscription,
	}

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

	resp, err := c.UpdateSubscription(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 TestIncidentServiceListSubscriptions(t *testing.T) {
	var nextPageToken string = ""
	var subscriptionsElement *irmpb.Subscription = &irmpb.Subscription{}
	var subscriptions = []*irmpb.Subscription{subscriptionsElement}
	var expectedResponse = &irmpb.ListSubscriptionsResponse{
		NextPageToken: nextPageToken,
		Subscriptions: subscriptions,
	}

	mockIncident.err = nil
	mockIncident.reqs = nil

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

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

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

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

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

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

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

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

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

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

	mockIncident.err = nil
	mockIncident.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/subscriptions/%s", "[PROJECT]", "[INCIDENT]", "[SUBSCRIPTION]")
	var request = &irmpb.DeleteSubscriptionRequest{
		Name: formattedName,
	}

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

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

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

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

}

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

	var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/subscriptions/%s", "[PROJECT]", "[INCIDENT]", "[SUBSCRIPTION]")
	var request = &irmpb.DeleteSubscriptionRequest{
		Name: formattedName,
	}

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

	err = c.DeleteSubscription(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 TestIncidentServiceCreateIncidentRoleAssignment(t *testing.T) {
	var name string = "name3373707"
	var etag string = "etag3123477"
	var expectedResponse = &irmpb.IncidentRoleAssignment{
		Name: name,
		Etag: etag,
	}

	mockIncident.err = nil
	mockIncident.reqs = nil

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

	var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]")
	var incidentRoleAssignment *irmpb.IncidentRoleAssignment = &irmpb.IncidentRoleAssignment{}
	var request = &irmpb.CreateIncidentRoleAssignmentRequest{
		Parent:                 formattedParent,
		IncidentRoleAssignment: incidentRoleAssignment,
	}

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

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

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

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

	var formattedParent string = fmt.Sprintf("projects/%s/incidents/%s", "[PROJECT]", "[INCIDENT]")
	var incidentRoleAssignment *irmpb.IncidentRoleAssignment = &irmpb.IncidentRoleAssignment{}
	var request = &irmpb.CreateIncidentRoleAssignmentRequest{
		Parent:                 formattedParent,
		IncidentRoleAssignment: incidentRoleAssignment,
	}

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

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

	mockIncident.err = nil
	mockIncident.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/roleAssignments/%s", "[PROJECT]", "[INCIDENT]", "[ROLE_ASSIGNMENT]")
	var request = &irmpb.DeleteIncidentRoleAssignmentRequest{
		Name: formattedName,
	}

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

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

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

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

}

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

	var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/roleAssignments/%s", "[PROJECT]", "[INCIDENT]", "[ROLE_ASSIGNMENT]")
	var request = &irmpb.DeleteIncidentRoleAssignmentRequest{
		Name: formattedName,
	}

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

	err = c.DeleteIncidentRoleAssignment(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 TestIncidentServiceListIncidentRoleAssignments(t *testing.T) {
	var nextPageToken string = ""
	var incidentRoleAssignmentsElement *irmpb.IncidentRoleAssignment = &irmpb.IncidentRoleAssignment{}
	var incidentRoleAssignments = []*irmpb.IncidentRoleAssignment{incidentRoleAssignmentsElement}
	var expectedResponse = &irmpb.ListIncidentRoleAssignmentsResponse{
		NextPageToken:           nextPageToken,
		IncidentRoleAssignments: incidentRoleAssignments,
	}

	mockIncident.err = nil
	mockIncident.reqs = nil

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

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

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

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

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

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

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

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

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

	resp, err := c.ListIncidentRoleAssignments(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 TestIncidentServiceRequestIncidentRoleHandover(t *testing.T) {
	var name2 string = "name2-1052831874"
	var etag string = "etag3123477"
	var expectedResponse = &irmpb.IncidentRoleAssignment{
		Name: name2,
		Etag: etag,
	}

	mockIncident.err = nil
	mockIncident.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/roleAssignments/%s", "[PROJECT]", "[INCIDENT]", "[ROLE_ASSIGNMENT]")
	var newAssignee *irmpb.User = &irmpb.User{}
	var request = &irmpb.RequestIncidentRoleHandoverRequest{
		Name:        formattedName,
		NewAssignee: newAssignee,
	}

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

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

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

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

	var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/roleAssignments/%s", "[PROJECT]", "[INCIDENT]", "[ROLE_ASSIGNMENT]")
	var newAssignee *irmpb.User = &irmpb.User{}
	var request = &irmpb.RequestIncidentRoleHandoverRequest{
		Name:        formattedName,
		NewAssignee: newAssignee,
	}

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

	resp, err := c.RequestIncidentRoleHandover(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 TestIncidentServiceConfirmIncidentRoleHandover(t *testing.T) {
	var name2 string = "name2-1052831874"
	var etag string = "etag3123477"
	var expectedResponse = &irmpb.IncidentRoleAssignment{
		Name: name2,
		Etag: etag,
	}

	mockIncident.err = nil
	mockIncident.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/roleAssignments/%s", "[PROJECT]", "[INCIDENT]", "[ROLE_ASSIGNMENT]")
	var newAssignee *irmpb.User = &irmpb.User{}
	var request = &irmpb.ConfirmIncidentRoleHandoverRequest{
		Name:        formattedName,
		NewAssignee: newAssignee,
	}

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

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

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

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

	var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/roleAssignments/%s", "[PROJECT]", "[INCIDENT]", "[ROLE_ASSIGNMENT]")
	var newAssignee *irmpb.User = &irmpb.User{}
	var request = &irmpb.ConfirmIncidentRoleHandoverRequest{
		Name:        formattedName,
		NewAssignee: newAssignee,
	}

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

	resp, err := c.ConfirmIncidentRoleHandover(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 TestIncidentServiceForceIncidentRoleHandover(t *testing.T) {
	var name2 string = "name2-1052831874"
	var etag string = "etag3123477"
	var expectedResponse = &irmpb.IncidentRoleAssignment{
		Name: name2,
		Etag: etag,
	}

	mockIncident.err = nil
	mockIncident.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/roleAssignments/%s", "[PROJECT]", "[INCIDENT]", "[ROLE_ASSIGNMENT]")
	var newAssignee *irmpb.User = &irmpb.User{}
	var request = &irmpb.ForceIncidentRoleHandoverRequest{
		Name:        formattedName,
		NewAssignee: newAssignee,
	}

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

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

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

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

	var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/roleAssignments/%s", "[PROJECT]", "[INCIDENT]", "[ROLE_ASSIGNMENT]")
	var newAssignee *irmpb.User = &irmpb.User{}
	var request = &irmpb.ForceIncidentRoleHandoverRequest{
		Name:        formattedName,
		NewAssignee: newAssignee,
	}

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

	resp, err := c.ForceIncidentRoleHandover(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 TestIncidentServiceCancelIncidentRoleHandover(t *testing.T) {
	var name2 string = "name2-1052831874"
	var etag string = "etag3123477"
	var expectedResponse = &irmpb.IncidentRoleAssignment{
		Name: name2,
		Etag: etag,
	}

	mockIncident.err = nil
	mockIncident.reqs = nil

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

	var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/roleAssignments/%s", "[PROJECT]", "[INCIDENT]", "[ROLE_ASSIGNMENT]")
	var newAssignee *irmpb.User = &irmpb.User{}
	var request = &irmpb.CancelIncidentRoleHandoverRequest{
		Name:        formattedName,
		NewAssignee: newAssignee,
	}

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

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

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

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

	var formattedName string = fmt.Sprintf("projects/%s/incidents/%s/roleAssignments/%s", "[PROJECT]", "[INCIDENT]", "[ROLE_ASSIGNMENT]")
	var newAssignee *irmpb.User = &irmpb.User{}
	var request = &irmpb.CancelIncidentRoleHandoverRequest{
		Name:        formattedName,
		NewAssignee: newAssignee,
	}

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

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