yao/openapi/oauth/providers/user/exists_test.go
Max 21c7caed5d Add lightweight existence check methods for OAuth accounts, roles, types, and users
- Implemented methods to check the existence of OAuth accounts, roles, types, and users by their respective identifiers, enhancing the user provider's functionality.
- Added error handling for these methods to ensure robust feedback in case of failures.
- Updated the user provider interface to include the new existence check methods, improving overall usability and maintainability.
2025-08-03 07:14:09 +08:00

243 lines
7 KiB
Go

package user_test
import (
"context"
"strings"
"testing"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/yaoapp/kun/maps"
)
// TestExistsMethods tests all resource existence check methods
func TestExistsMethods(t *testing.T) {
prepare(t)
defer clean()
ctx := context.Background()
// Use UUID to ensure unique identifiers across test runs
testUUID := strings.ReplaceAll(uuid.New().String(), "-", "")[:8] // 8 char UUID
testUserID := "test-user-for-exists-" + testUUID
testUsername := "testexistsuser" + testUUID
testEmail := "testexists" + testUUID + "@example.com"
t.Run("UserExists", func(t *testing.T) {
// Test non-existent user
exists, err := testProvider.UserExists(ctx, "nonexistent-user-id")
assert.NoError(t, err)
assert.False(t, exists)
// Create a test user
userData := maps.MapStrAny{
"user_id": testUserID,
"preferred_username": testUsername,
"email": testEmail,
"password": "password123",
"status": "active",
}
_, err = testProvider.CreateUser(ctx, userData)
assert.NoError(t, err)
// Test existing user
exists, err = testProvider.UserExists(ctx, testUserID)
assert.NoError(t, err)
assert.True(t, exists)
})
t.Run("UserExistsByEmail", func(t *testing.T) {
// Test non-existent email
exists, err := testProvider.UserExistsByEmail(ctx, "nonexistent@example.com")
assert.NoError(t, err)
assert.False(t, exists)
// Test existing email (using unique email from test setup)
exists, err = testProvider.UserExistsByEmail(ctx, testEmail)
assert.NoError(t, err)
assert.True(t, exists)
})
t.Run("UserExistsByPreferredUsername", func(t *testing.T) {
// Test non-existent username
exists, err := testProvider.UserExistsByPreferredUsername(ctx, "nonexistentuser")
assert.NoError(t, err)
assert.False(t, exists)
// Test existing username (using unique username from test setup)
exists, err = testProvider.UserExistsByPreferredUsername(ctx, testUsername)
assert.NoError(t, err)
assert.True(t, exists)
})
// Define unique IDs for roles and types
testRoleID := "test-role-for-exists-" + testUUID
testTypeID := "test-type-for-exists-" + testUUID
t.Run("RoleExists", func(t *testing.T) {
// Test non-existent role
exists, err := testProvider.RoleExists(ctx, "nonexistent-role")
assert.NoError(t, err)
assert.False(t, exists)
// Create a test role
roleData := maps.MapStrAny{
"role_id": testRoleID,
"name": "Test Exists Role " + testUUID,
"description": "Role for testing exists method",
"is_active": true,
}
_, err = testProvider.CreateRole(ctx, roleData)
assert.NoError(t, err)
// Test existing role
exists, err = testProvider.RoleExists(ctx, testRoleID)
assert.NoError(t, err)
assert.True(t, exists)
})
t.Run("TypeExists", func(t *testing.T) {
// Test non-existent type
exists, err := testProvider.TypeExists(ctx, "nonexistent-type")
assert.NoError(t, err)
assert.False(t, exists)
// Create a test type
typeData := maps.MapStrAny{
"type_id": testTypeID,
"name": "Test Exists Type " + testUUID,
"description": "Type for testing exists method",
"is_active": true,
}
_, err = testProvider.CreateType(ctx, typeData)
assert.NoError(t, err)
// Test existing type
exists, err = testProvider.TypeExists(ctx, testTypeID)
assert.NoError(t, err)
assert.True(t, exists)
})
t.Run("OAuthAccountExists", func(t *testing.T) {
// Test non-existent OAuth account
exists, err := testProvider.OAuthAccountExists(ctx, "nonexistent-provider", "nonexistent-subject")
assert.NoError(t, err)
assert.False(t, exists)
// Create a test OAuth account (using unique identifiers)
testOAuthProvider := "test-provider-" + testUUID
testSubject := "test-subject-for-exists-" + testUUID
oauthData := maps.MapStrAny{
"provider": testOAuthProvider,
"sub": testSubject,
"name": "Test OAuth User " + testUUID,
"email": "testoauth" + testUUID + "@example.com",
"is_active": true,
}
_, err = testProvider.CreateOAuthAccount(ctx, testUserID, oauthData)
assert.NoError(t, err)
// Test existing OAuth account
exists, err = testProvider.OAuthAccountExists(ctx, testOAuthProvider, testSubject)
assert.NoError(t, err)
assert.True(t, exists)
})
t.Run("UserHasRole", func(t *testing.T) {
// Test user without role
hasRole, err := testProvider.UserHasRole(ctx, testUserID)
assert.NoError(t, err)
assert.False(t, hasRole)
// Assign role to user
err = testProvider.SetUserRole(ctx, testUserID, testRoleID)
assert.NoError(t, err)
// Test user with role
hasRole, err = testProvider.UserHasRole(ctx, testUserID)
assert.NoError(t, err)
assert.True(t, hasRole)
// Test non-existent user
_, err = testProvider.UserHasRole(ctx, "nonexistent-user")
assert.Error(t, err)
assert.Contains(t, err.Error(), "user not found")
})
t.Run("UserHasType", func(t *testing.T) {
// Test user without type
hasType, err := testProvider.UserHasType(ctx, testUserID)
assert.NoError(t, err)
assert.False(t, hasType)
// Assign type to user
err = testProvider.SetUserType(ctx, testUserID, testTypeID)
assert.NoError(t, err)
// Test user with type
hasType, err = testProvider.UserHasType(ctx, testUserID)
assert.NoError(t, err)
assert.True(t, hasType)
// Test non-existent user
_, err = testProvider.UserHasType(ctx, "nonexistent-user")
assert.Error(t, err)
assert.Contains(t, err.Error(), "user not found")
})
}
// TestExistsPerformance tests the performance benefit of Exists methods vs full Get methods
func TestExistsPerformance(t *testing.T) {
prepare(t)
defer clean()
ctx := context.Background()
// Use UUID to ensure unique identifiers
perfUUID := strings.ReplaceAll(uuid.New().String(), "-", "")[:8] // 8 char UUID
perfUserID := "perf-test-user-" + perfUUID
perfUsername := "perfuser" + perfUUID
perfEmail := "perf" + perfUUID + "@example.com"
// Create a test user for performance comparison
userData := maps.MapStrAny{
"user_id": perfUserID,
"preferred_username": perfUsername,
"email": perfEmail,
"password": "password123",
"status": "active",
}
_, err := testProvider.CreateUser(ctx, userData)
assert.NoError(t, err)
t.Run("UserExists_vs_GetUser", func(t *testing.T) {
// Both should work, but UserExists should be more efficient
// (we can't easily measure performance in unit tests, but we verify functionality)
// Test UserExists
exists, err := testProvider.UserExists(ctx, perfUserID)
assert.NoError(t, err)
assert.True(t, exists)
// Test GetUser (more expensive)
user, err := testProvider.GetUser(ctx, perfUserID)
assert.NoError(t, err)
assert.NotNil(t, user)
assert.Equal(t, perfUserID, user["user_id"])
// Both methods should give consistent results for existence
exists, err = testProvider.UserExists(ctx, "nonexistent-user")
assert.NoError(t, err)
assert.False(t, exists)
_, err = testProvider.GetUser(ctx, "nonexistent-user")
assert.Error(t, err)
assert.Contains(t, err.Error(), "user not found")
})
}