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

import (
	webriskpb "google.golang.org/genproto/googleapis/cloud/webrisk/v1beta1"
)

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

	reqs []proto.Message

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

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

func (s *mockWebRiskServiceV1Beta1Server) ComputeThreatListDiff(ctx context.Context, req *webriskpb.ComputeThreatListDiffRequest) (*webriskpb.ComputeThreatListDiffResponse, 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].(*webriskpb.ComputeThreatListDiffResponse), nil
}

func (s *mockWebRiskServiceV1Beta1Server) SearchUris(ctx context.Context, req *webriskpb.SearchUrisRequest) (*webriskpb.SearchUrisResponse, 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].(*webriskpb.SearchUrisResponse), nil
}

func (s *mockWebRiskServiceV1Beta1Server) SearchHashes(ctx context.Context, req *webriskpb.SearchHashesRequest) (*webriskpb.SearchHashesResponse, 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].(*webriskpb.SearchHashesResponse), nil
}

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

var (
	mockWebRiskServiceV1Beta1 mockWebRiskServiceV1Beta1Server
)

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

	serv := grpc.NewServer()
	webriskpb.RegisterWebRiskServiceV1Beta1Server(serv, &mockWebRiskServiceV1Beta1)

	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 TestWebRiskServiceV1Beta1ComputeThreatListDiff(t *testing.T) {
	var newVersionToken []byte = []byte("115")
	var expectedResponse = &webriskpb.ComputeThreatListDiffResponse{
		NewVersionToken: newVersionToken,
	}

	mockWebRiskServiceV1Beta1.err = nil
	mockWebRiskServiceV1Beta1.reqs = nil

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

	var threatType webriskpb.ThreatType = webriskpb.ThreatType_THREAT_TYPE_UNSPECIFIED
	var constraints *webriskpb.ComputeThreatListDiffRequest_Constraints = &webriskpb.ComputeThreatListDiffRequest_Constraints{}
	var request = &webriskpb.ComputeThreatListDiffRequest{
		ThreatType:  threatType,
		Constraints: constraints,
	}

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

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

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

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

	var threatType webriskpb.ThreatType = webriskpb.ThreatType_THREAT_TYPE_UNSPECIFIED
	var constraints *webriskpb.ComputeThreatListDiffRequest_Constraints = &webriskpb.ComputeThreatListDiffRequest_Constraints{}
	var request = &webriskpb.ComputeThreatListDiffRequest{
		ThreatType:  threatType,
		Constraints: constraints,
	}

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

	resp, err := c.ComputeThreatListDiff(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 TestWebRiskServiceV1Beta1SearchUris(t *testing.T) {
	var expectedResponse *webriskpb.SearchUrisResponse = &webriskpb.SearchUrisResponse{}

	mockWebRiskServiceV1Beta1.err = nil
	mockWebRiskServiceV1Beta1.reqs = nil

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

	var uri string = "uri116076"
	var threatTypes []webriskpb.ThreatType = nil
	var request = &webriskpb.SearchUrisRequest{
		Uri:         uri,
		ThreatTypes: threatTypes,
	}

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

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

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

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

	var uri string = "uri116076"
	var threatTypes []webriskpb.ThreatType = nil
	var request = &webriskpb.SearchUrisRequest{
		Uri:         uri,
		ThreatTypes: threatTypes,
	}

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

	resp, err := c.SearchUris(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 TestWebRiskServiceV1Beta1SearchHashes(t *testing.T) {
	var expectedResponse *webriskpb.SearchHashesResponse = &webriskpb.SearchHashesResponse{}

	mockWebRiskServiceV1Beta1.err = nil
	mockWebRiskServiceV1Beta1.reqs = nil

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

	var request *webriskpb.SearchHashesRequest = &webriskpb.SearchHashesRequest{}

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

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

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

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

	var request *webriskpb.SearchHashesRequest = &webriskpb.SearchHashesRequest{}

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

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