github.com/thiagoyeds/go-cloud@v0.26.0/blob/gcsblob/iam_test.go (about)

     1  // Copyright 2020 The Go Cloud Development Kit Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     https://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package gcsblob
    16  
    17  import (
    18  	"context"
    19  	"errors"
    20  	"testing"
    21  
    22  	gax "github.com/googleapis/gax-go/v2"
    23  	credentialspb "google.golang.org/genproto/googleapis/iam/credentials/v1"
    24  )
    25  
    26  const (
    27  	mockKey       = "key0000"
    28  	mockSignature = "signature"
    29  )
    30  
    31  type mockIAMClient struct {
    32  	requestErr error
    33  }
    34  
    35  func (m mockIAMClient) SignBlob(context.Context, *credentialspb.SignBlobRequest, ...gax.CallOption) (*credentialspb.SignBlobResponse, error) {
    36  	if m.requestErr != nil {
    37  		return nil, m.requestErr
    38  	}
    39  	return &credentialspb.SignBlobResponse{KeyId: mockKey, SignedBlob: []byte(mockSignature)}, nil
    40  }
    41  
    42  func TestIAMCredentialsClient(t *testing.T) {
    43  	tests := []struct {
    44  		name       string
    45  		connectErr error
    46  		mockClient interface {
    47  			SignBlob(context.Context, *credentialspb.SignBlobRequest, ...gax.CallOption) (*credentialspb.SignBlobResponse, error)
    48  		}
    49  
    50  		// These are for the produced SignBytesFunc
    51  		input      []byte
    52  		wantOutput []byte
    53  		requestErr error
    54  	}{
    55  		{"happy path: signing", nil,
    56  			mockIAMClient{},
    57  			[]byte("payload"), []byte(mockSignature), nil,
    58  		},
    59  		{"won't connect", errors.New("Missing role: serviceAccountTokenCreator"),
    60  			mockIAMClient{},
    61  			[]byte("payload"), nil, nil,
    62  		},
    63  		{"request fails", nil,
    64  			mockIAMClient{requestErr: context.Canceled},
    65  			[]byte("payload"), nil, context.Canceled,
    66  		},
    67  	}
    68  
    69  	for _, test := range tests {
    70  		t.Run(test.name, func(t *testing.T) {
    71  			c := credentialsClient{err: test.connectErr, client: test.mockClient}
    72  			makeSignBytesFn := c.CreateMakeSignBytesWith(nil, serviceAccountID)
    73  
    74  			signBytesFn := makeSignBytesFn(nil) // Our mocks don't read any context.
    75  			haveOutput, haveErr := signBytesFn(test.input)
    76  
    77  			if len(test.wantOutput) > 0 && string(haveOutput) != string(test.wantOutput) {
    78  				t.Errorf("Unexpected output:\n -- have: %v\n -- want: %v",
    79  					string(haveOutput), string(test.wantOutput))
    80  				return
    81  			}
    82  
    83  			if test.connectErr == nil && test.requestErr == nil {
    84  				return
    85  			}
    86  			if test.connectErr != nil && haveErr != test.connectErr {
    87  				t.Error("The connection error, a permanent error, has not been returned but should.")
    88  			}
    89  			if test.requestErr != nil && haveErr != test.requestErr {
    90  				t.Error("The per-request error has not been returned but should.")
    91  			}
    92  		})
    93  	}
    94  }