Authentication Service Testing Guide
๐งช Test Plan Overviewโ
We'll test in this order:
- OTP System (SMS/WhatsApp)
- Registration Flow
- Login Flow
- Token Management
- Session Management
- Account Security
- Admin Features
- Cleanup & Maintenance
1. ๐ฑ OTP System Testingโ
Test 1.1: Send SMS OTP for Registrationโ
mutation SendSmsOtpRegistration {
sendOtp(input: {
dialCode: "+91"
mobileNumber: "9876543210"
purpose: "REGISTRATION"
method: "SMS"
}) {
success
message
deliveryStatus
otpForTesting # Only in development
}
}
Test 1.2: Send WhatsApp OTP for Registrationโ
mutation SendWhatsAppOtpRegistration {
sendOtp(input: {
dialCode: "+91"
mobileNumber: "9876543210"
purpose: "REGISTRATION"
method: "WHATSAPP"
}) {
success
message
deliveryStatus
otpForTesting
}
}
Test 1.3: Verify OTP (Standalone)โ
mutation VerifyOtpStandalone {
verifyOtp(input: {
dialCode: "+91"
mobileNumber: "9876543210"
otp: "123456" # Use the OTP from previous test
purpose: "REGISTRATION"
}) {
success
message
mobile
purpose
}
}
Expected Results:
- โ SMS/WhatsApp OTP sent successfully
- โ Development mode shows OTP in logs
- โ OTP verification works
- โ Rate limiting (try sending 6 OTPs in an hour)
2. ๐ค Registration Flow Testingโ
Test 2.1: Complete Registrationโ
# First send OTP
mutation SendRegistrationOtp {
sendOtp(input: {
dialCode: "+91"
mobileNumber: "9876543211"
purpose: "REGISTRATION"
}) {
success
otpForTesting
}
}
# Then register with OTP
mutation RegisterUser {
registerWithOtp(input: {
dialCode: "+91"
mobileNumber: "9876543211"
otp: "123456" # Use OTP from above
purpose: "REGISTRATION"
}) {
success
message
accessToken
refreshToken
expiresIn
user {
id
mobile
isRegistrationComplete
externalUserId
}
}
}
Test 2.2: Duplicate Registration (Should Fail)โ
mutation DuplicateRegistration {
registerWithOtp(input: {
dialCode: "+91"
mobileNumber: "9876543211" # Same number
otp: "123456"
purpose: "REGISTRATION"
}) {
success
message
}
}
Expected Results:
- โ New user created successfully
- โ JWT tokens generated
- โ Session created in database
- โ Duplicate registration blocked
- โ Device info captured
3. ๐ Login Flow Testingโ
Test 3.1: Successful Loginโ
# Send login OTP
mutation SendLoginOtp {
sendOtp(input: {
dialCode: "+91"
mobileNumber: "9876543211" # Existing user
purpose: "LOGIN"
}) {
success
otpForTesting
}
}
# Login with OTP
mutation LoginUser {
loginWithOtp(input: {
dialCode: "+91"
mobileNumber: "9876543211"
otp: "123456" # Use OTP from above
purpose: "LOGIN"
}) {
success
message
accessToken
refreshToken
expiresIn
user {
id
mobile
isRegistrationComplete
}
}
}
Test 3.2: Login Non-existent Userโ
mutation LoginNonExistentUser {
loginWithOtp(input: {
dialCode: "+91"
mobileNumber: "9999999999" # Non-existent
otp: "123456"
purpose: "LOGIN"
}) {
success
message
}
}
Expected Results:
- โ Existing user login successful
- โ Non-existent user login blocked
- โ New session created for successful login
4. ๐ Token Management Testingโ
Test 4.1: Refresh Tokenโ
mutation RefreshTokens {
refreshToken(input: {
refreshToken: "your_refresh_token_here"
}) {
success
message
accessToken
refreshToken
expiresIn
}
}
Test 4.2: Logout Single Deviceโ
mutation LogoutSingle {
logout(input: {
refreshToken: "your_refresh_token_here"
logoutAllDevices: false
}) {
success
message
sessionsTerminated
}
}
Test 4.3: Logout All Devicesโ
mutation LogoutAll {
logout(input: {
refreshToken: "your_refresh_token_here"
logoutAllDevices: true
}) {
success
message
sessionsTerminated
}
}
Expected Results:
- โ Token refresh generates new tokens
- โ Old refresh token becomes invalid
- โ Logout terminates sessions correctly
5. ๐ก๏ธ Account Security Testingโ
Test 5.1: Failed Login Attempts (Lock Account)โ
# Try 5 failed login attempts with wrong OTP
mutation FailedLogin {
loginWithOtp(input: {
dialCode: "+91"
mobileNumber: "9876543211"
otp: "000000" # Wrong OTP
purpose: "LOGIN"
}) {
success
message
}
}
Test 5.2: Check Account Lock Statusโ
query CheckAccountStatus {
adminGetUserStatus(input: {
mobile: "+919876543211"
}) {
id
mobile
isLocked
lockedUntil
failedAttempts
totalLockouts
}
}
Test 5.3: Auto-unlock Testโ
# Wait for lock duration or manually unlock, then try login again
mutation LoginAfterUnlock {
loginWithOtp(input: {
dialCode: "+91"
mobileNumber: "9876543211"
otp: "123456" # Correct OTP
purpose: "LOGIN"
}) {
success
message
}
}
Expected Results:
- โ Account locks after 5 failed attempts
- โ Lock status visible in admin query
- โ Auto-unlock works after timeout
6. ๐จโ๐ผ Admin Features Testingโ
Test 6.1: System Statisticsโ
query SystemStats {
adminGetSystemStats {
totalUsers
activeUsers
lockedUsers
activeSessions
todayRegistrations
todayLogins
todayOtpAttempts
}
}
Test 6.2: User Lookupโ
query LookupUser {
adminGetUserStatus(input: {
userId: "1"
}) {
id
mobile
isEnabled
isVerified
isLocked
isRegistrationComplete
failedAttempts
totalLockouts
lockedUntil
lastLoginAt
createdAt
activeSessions {
sessionId
startedAt
lastActivityAt
ipAddress
deviceType
deviceOS
}
}
}
Test 6.3: Admin Unlock Accountโ
mutation AdminUnlockAccount {
adminUnlockAccount(input: {
userId: "1"
reason: "Customer support request"
}) {
success
message
}
}
Test 6.4: Admin Revoke User Tokensโ
mutation AdminRevokeTokens {
adminRevokeUserTokens(input: {
userId: "1"
reason: "Security concern"
}) {
success
message
affectedCount
}
}
Test 6.5: Admin Disable Accountโ
mutation AdminDisableAccount {
adminDisableAccount(
userId: "1"
reason: "Policy violation"
) {
success
message
}
}
Expected Results:
- โ System stats show correct counts
- โ User lookup shows complete information
- โ Admin actions work and are logged
- โ Account operations affect user authentication
7. ๐งน Database Verificationโ
Check Database Stateโ
-- Check users table
SELECT id, dial_code, mobile_number, is_enabled, is_verified, is_locked, failed_attempts
FROM authentication_users;
-- Check active sessions
SELECT session_id, user_id, status, started_at, last_activity_at, device_info
FROM login_sessions
WHERE status = 'ACTIVE';
-- Check refresh tokens
SELECT token_id, user_id, is_revoked, expires_at, created_at
FROM refresh_tokens
WHERE is_revoked = false;
-- Check OTP attempts
SELECT dial_code, mobile_number, purpose, delivery_method, delivery_status, is_used
FROM otp_attempts
ORDER BY created_at DESC
LIMIT 10;
8. ๐ Error Scenarios Testingโ
Test Invalid Inputsโ
# Invalid dial code
mutation InvalidDialCode {
sendOtp(input: {
dialCode: "91" # Missing +
mobileNumber: "9876543210"
purpose: "REGISTRATION"
}) {
success
message
}
}
# Invalid mobile number
mutation InvalidMobile {
sendOtp(input: {
dialCode: "+91"
mobileNumber: "123" # Too short
purpose: "REGISTRATION"
}) {
success
message
}
}
# Expired OTP
mutation ExpiredOtp {
loginWithOtp(input: {
dialCode: "+91"
mobileNumber: "9876543211"
otp: "123456" # Use 5+ minute old OTP
purpose: "LOGIN"
}) {
success
message
}
}
Expected Results:
- โ Validation errors for invalid inputs
- โ Clear error messages
- โ Expired OTP rejection
9. ๐ Performance & Load Testingโ
Rate Limiting Testโ
# Send multiple OTP requests quickly (should be rate limited)
for i in {1..10}; do
curl -X POST http://localhost:3000/graphql \
-H "Content-Type: application/json" \
-d '{"query":"mutation{sendOtp(input:{dialCode:\"+91\",mobileNumber:\"9876543210\",purpose:\"LOGIN\"}){success}}"}'
done
Concurrent Sessions Testโ
Create multiple sessions for the same user from different devices/browsers and verify they're all tracked correctly.
๐ฏ Testing Checklistโ
Core Functionalityโ
- SMS OTP sending works
- WhatsApp OTP sending works
- OTP verification works
- User registration complete
- User login complete
- Token refresh works
- Logout (single device) works
- Logout (all devices) works
Security Featuresโ
- Rate limiting on OTP requests
- Account locking after failed attempts
- Automatic account unlocking
- Session tracking works
- Device information captured
- Token family security works
Admin Featuresโ
- System statistics accurate
- User lookup works
- Admin unlock account works
- Admin revoke tokens works
- Admin disable/enable account works
Error Handlingโ
- Validation errors work
- Duplicate registration blocked
- Non-existent user login blocked
- Expired OTP handled
- Invalid token handling
Database Integrityโ
- All tables populated correctly
- Foreign key relationships intact
- Cleanup jobs running
- No orphaned records
๐จ Issues to Watch Forโ
- Memory Leaks: Monitor memory usage during testing
- Database Connections: Ensure proper connection pooling
- Race Conditions: Test concurrent operations
- Token Security: Verify tokens can't be reused inappropriately
- Session Cleanup: Verify expired sessions are cleaned up
Start with the OTP system tests and work through each section. Let me know the results of each test phase!