test(supply-api): extend auth and iam guard coverage

Add nil and wildcard coverage for IAM claims helpers, ensure auth security tests run with authentication enabled, and make settlement mocks express pending-withdraw/error branches explicitly.
This commit is contained in:
Your Name
2026-04-11 09:34:13 +08:00
parent dfa8a891ab
commit eefb68c5b3
3 changed files with 119 additions and 4 deletions

View File

@@ -748,3 +748,112 @@ func TestHasAnyScope_False(t *testing.T) {
assert.False(t, hasAnyScope([]string{"platform:read"}, []string{"platform:admin", "supply:write"}))
assert.False(t, hasAnyScope([]string{"tenant:read"}, []string{"platform:admin"}))
}
// TestMigrateClaims_NilInput 测试MigrateClaims处理nil输入
func TestMigrateClaims_NilInput(t *testing.T) {
// act
result := MigrateClaims(nil)
// assert
assert.Nil(t, result, "MigrateClaims with nil input should return nil")
}
// TestMigrateClaims_ValidClaims 测试MigrateClaims处理有效claims
func TestMigrateClaims_ValidClaims(t *testing.T) {
// arrange
claims := &IAMTokenClaims{
SubjectID: "user:test",
Role: "viewer",
Scope: []string{"platform:read"},
TenantID: 1,
Version: 0,
}
// act
result := MigrateClaims(claims)
// assert
assert.NotNil(t, result, "MigrateClaims should return non-nil for valid claims")
assert.Equal(t, ClaimsVersion, result.Version, "Version should be updated to ClaimsVersion")
assert.Equal(t, "user:test", result.SubjectID, "SubjectID should be preserved")
}
// TestValidateClaims_NilClaims 测试ValidateClaims处理nil claims
func TestValidateClaims_NilClaims(t *testing.T) {
// act
err := ValidateClaims(nil)
// assert
assert.Error(t, err, "ValidateClaims should return error for nil claims")
assert.Equal(t, ErrInvalidClaims, err, "Error should be ErrInvalidClaims")
}
// TestValidateClaims_EmptySubjectID 测试ValidateClaims处理空SubjectID
func TestValidateClaims_EmptySubjectID(t *testing.T) {
// arrange
claims := &IAMTokenClaims{
SubjectID: "", // empty
Role: "viewer",
Scope: []string{"platform:read"},
TenantID: 1,
}
// act
err := ValidateClaims(claims)
// assert
assert.Error(t, err, "ValidateClaims should return error for empty SubjectID")
assert.Equal(t, ErrInvalidSubjectID, err, "Error should be ErrInvalidSubjectID")
}
// TestValidateClaims_ValidClaims 测试ValidateClaims处理有效claims
func TestValidateClaims_ValidClaims(t *testing.T) {
// arrange
claims := &IAMTokenClaims{
SubjectID: "user:test",
Role: "viewer",
Scope: []string{"platform:read"},
TenantID: 1,
}
// act
err := ValidateClaims(claims)
// assert
assert.NoError(t, err, "ValidateClaims should not return error for valid claims")
}
// TestLogWildcardScopeAccess_NilClaims 测试logWildcardScopeAccess处理nil claims
func TestLogWildcardScopeAccess_NilClaims(t *testing.T) {
// act - should not panic
logWildcardScopeAccess(context.Background(), nil, "platform:read")
}
// TestLogWildcardScopeAccess_WithWildcard 测试logWildcardScopeAccess记录通配符访问
func TestLogWildcardScopeAccess_WithWildcard(t *testing.T) {
// arrange
claims := &IAMTokenClaims{
SubjectID: "user:admin",
Role: "super_admin",
Scope: []string{"*"},
TenantID: 1,
}
// act - should not panic and should log
logWildcardScopeAccess(context.Background(), claims, "platform:read")
}
// TestHasWildcardScope_True 测试hasWildcardScope - 有通配符
func TestHasWildcardScope_True(t *testing.T) {
// act & assert
assert.True(t, hasWildcardScope([]string{"*"}), "wildcard scope should return true")
assert.True(t, hasWildcardScope([]string{"platform:read", "*"}), "mixed with wildcard should return true")
}
// TestHasWildcardScope_False 测试hasWildcardScope - 无通配符
func TestHasWildcardScope_False(t *testing.T) {
// act & assert
assert.False(t, hasWildcardScope([]string{"platform:read"}), "regular scope should return false")
assert.False(t, hasWildcardScope([]string{"platform:read", "platform:write"}), "multiple regular scopes should return false")
assert.False(t, hasWildcardScope([]string{}), "empty scopes should return false")
}

View File

@@ -23,6 +23,7 @@ func TestMED09_ErrorMessageShouldNotLeakInternalDetails(t *testing.T) {
config: AuthConfig{
SecretKey: secretKey,
Issuer: issuer,
Enabled: true, // 确保鉴权启用
},
tokenCache: NewTokenCache(),
// Intentionally no tokenBackend - to simulate error scenario

View File

@@ -101,9 +101,11 @@ func (m *MockPackageStore) List(ctx context.Context, supplierID int64) ([]*domai
// MockSettlementStore 结算存储 mock
type MockSettlementStore struct {
Settlements map[int64]*domain.Settlement
NextID int64
Balance float64
Settlements map[int64]*domain.Settlement
NextID int64
Balance float64
HasPendingWithdraw bool // 控制 HasPendingOrProcessingWithdraw 返回值
HasPendingWithdrawError error // 控制 HasPendingOrProcessingWithdraw 错误
}
// NewMockSettlementStore 创建结算存储 mock
@@ -152,7 +154,10 @@ func (m *MockSettlementStore) GetWithdrawableBalance(ctx context.Context, suppli
}
func (m *MockSettlementStore) HasPendingOrProcessingWithdraw(ctx context.Context, supplierID int64) (bool, error) {
return false, nil // 默认允许提现
if m.HasPendingWithdrawError != nil {
return false, m.HasPendingWithdrawError
}
return m.HasPendingWithdraw, nil
}
// MockEarningStore 收益存储 mock