Repository: grpc/grpc-go
File: credentials/jwt/token_file_call_creds_test.go (Go)

Code before:
		{
			name:           "insecure_transport_creds_as_call_option",
			useTLS:         false,
			credsAsDialOpt: false,
			wantErr:        "cannot send secure credentials on an insecure connection",
		},
		{
			name:           "insecure_transport_creds_as_dial_option",
			useTLS:         false,
			credsAsDialOpt: true,
			wantErr:        "the credentials require transport level security",
		},
		{
			name:           "secure_transport_creds_as_dial_option",
			useTLS:         true,
			credsAsDialOpt: true,
		},
		{
			name:           "secure_transport_creds_as_call_option",
			useTLS:         true,
			credsAsDialOpt: false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			token := createTestJWT(t, time.Now().Add(time.Hour))
			tokenFile := writeTempFile(t, "token", token)

			jwtCreds, err := NewTokenFileCallCredentials(tokenFile)
			if err != nil {
				t.Fatalf("NewTokenFileCallCredentials(%q) failed: %v", tokenFile, err)
			}

			expectedAuth := "Bearer " + token
			ss := &stubserver.StubServer{
				EmptyCallF: func(ctx context.Context, _ *testpb.Empty) (*testpb.Empty, error) {
					md, ok := metadata.FromIncomingContext(ctx)
					if !ok {
						return nil, fmt.Errorf("no metadata received")
					}
					authHeaders := md.Get("authorization")
					if len(authHeaders) != 1 || authHeaders[0] != expectedAuth {
						return nil, fmt.Errorf("authorization header mismatch: got %v, want %q", authHeaders, expectedAuth)
					}
					return &testpb.Empty{}, nil
				},
			}

			var serverOpts []grpc.ServerOption
			var clientCreds credentials.TransportCredentials

Review comment (bug):
I feel the test logic is too complicated because of having to handle all possible conditions specified in the test table.

See: https://google.github.io/styleguide/go/decisions#table-driven-tests, and specifically the paragraph that says:
When some test cases need to be checked using different logic from other test cases, it is appropriate to write multiple test functions, as explained in [GoTip #50: Disjoint Table Tests](https://google.github.io/styleguide/go/index.html#gotip).

Unfortunately the link to the GoTip episode is still work in progress, but I'm guessing you get the idea. It would be better to split this test up into more focussed ones (there could still be some possibility of having a table in there, but with lesser number of options), such that the test logic in each of them is very simple and straight-forward. The motivation here is that when a test fails, it should be very easy for person who is debugging the failure to understand the test logic and go about fixing it.

Code after:
	if err != nil {
		t.Fatalf("Failed to marshal claims: %v", err)
	}

	headerB64 := base64.URLEncoding.EncodeToString(headerBytes)
	claimsB64 := base64.URLEncoding.EncodeToString(claimsBytes)

	// Remove padding for URL-safe base64
	headerB64 = strings.TrimRight(headerB64, "=")
	claimsB64 = strings.TrimRight(claimsB64, "=")

	// For testing, we'll use a fake signature
	signature := base64.URLEncoding.EncodeToString([]byte("fake_signature"))
	signature = strings.TrimRight(signature, "=")

	return fmt.Sprintf("%s.%s.%s", headerB64, claimsB64, signature)
}

func writeTempFile(t *testing.T, name, content string) string {
	t.Helper()
	tempDir := t.TempDir()
	filePath := filepath.Join(tempDir, name)
	if err := os.WriteFile(filePath, []byte(content), 0600); err != nil {
		t.Fatalf("Failed to write temp file: %v", err)
	}
	return filePath
}