# ColaFlow Day 5 Integration Tests # Simple ASCII-only version $baseUrl = "http://localhost:5167" $ErrorActionPreference = "Continue" $testsPassed = 0 $testsFailed = 0 $testsTotal = 0 function Test-Success { param($Name) $script:testsPassed++ $script:testsTotal++ Write-Host "[PASS] $Name" -ForegroundColor Green } function Test-Failure { param($Name, $Error) $script:testsFailed++ $script:testsTotal++ Write-Host "[FAIL] $Name" -ForegroundColor Red Write-Host " Error: $Error" -ForegroundColor DarkRed } Write-Host "================================================" -ForegroundColor Cyan Write-Host "ColaFlow Day 5 Integration Test Suite" -ForegroundColor Cyan Write-Host "Testing: Refresh Token + RBAC" -ForegroundColor Cyan Write-Host "================================================" -ForegroundColor Cyan Write-Host "" # Wait for API Write-Host "Waiting for API server..." -ForegroundColor Yellow Start-Sleep -Seconds 8 # ============================= # PHASE 1: REFRESH TOKEN TESTS # ============================= Write-Host "`n--- PHASE 1: REFRESH TOKEN TESTS ---`n" -ForegroundColor Yellow # Test 1: Register and get tokens Write-Host "[Test 1] Register tenant and get tokens" -ForegroundColor White $slug1 = "test-$(Get-Random -Minimum 1000 -Maximum 9999)" $body1 = @{ tenantName = "Test Corp" tenantSlug = $slug1 subscriptionPlan = "Professional" adminEmail = "admin@test.com" adminPassword = "Admin@1234" adminFullName = "Admin" } | ConvertTo-Json try { $reg1 = Invoke-RestMethod -Uri "$baseUrl/api/tenants/register" -Method Post -ContentType "application/json" -Body $body1 $token1 = $reg1.accessToken $refresh1 = $reg1.refreshToken if ($token1 -and $refresh1) { Test-Success "Register returns access token and refresh token" } else { Test-Failure "Register returns tokens" "Missing tokens" } } catch { Test-Failure "Register tenant" $_.Exception.Message exit 1 } # Test 2: Use access token Write-Host "`n[Test 2] Use access token" -ForegroundColor White try { $headers1 = @{ "Authorization" = "Bearer $token1" } $me1 = Invoke-RestMethod -Uri "$baseUrl/api/auth/me" -Method Get -Headers $headers1 if ($me1.userId) { Test-Success "Access token works for /api/auth/me" } else { Test-Failure "Access token" "No user data returned" } } catch { Test-Failure "Use access token" $_.Exception.Message } # Test 3: Refresh token Write-Host "`n[Test 3] Refresh access token" -ForegroundColor White try { $refreshBody1 = @{ refreshToken = $refresh1 } | ConvertTo-Json $refRes1 = Invoke-RestMethod -Uri "$baseUrl/api/auth/refresh" -Method Post -ContentType "application/json" -Body $refreshBody1 $token2 = $refRes1.accessToken $refresh2 = $refRes1.refreshToken if ($token2 -and $refresh2 -and $token2 -ne $token1 -and $refresh2 -ne $refresh1) { Test-Success "Token refresh generates new tokens" } else { Test-Failure "Token refresh" "Tokens not rotated" } } catch { Test-Failure "Refresh token" $_.Exception.Message } # Test 4: Old token rejected Write-Host "`n[Test 4] Old refresh token rejected" -ForegroundColor White try { $oldBody = @{ refreshToken = $refresh1 } | ConvertTo-Json try { $bad = Invoke-RestMethod -Uri "$baseUrl/api/auth/refresh" -Method Post -ContentType "application/json" -Body $oldBody Test-Failure "Old token rejection" "Old token was accepted!" } catch { $code = $_.Exception.Response.StatusCode.value__ if ($code -eq 401) { Test-Success "Old refresh token rejected (401)" } else { Test-Failure "Old token rejection" "Got status $code instead of 401" } } } catch { Test-Failure "Old token test" $_.Exception.Message } # Test 5: New token works Write-Host "`n[Test 5] New access token works" -ForegroundColor White try { $headers2 = @{ "Authorization" = "Bearer $token2" } $me2 = Invoke-RestMethod -Uri "$baseUrl/api/auth/me" -Method Get -Headers $headers2 if ($me2.userId -eq $me1.userId) { Test-Success "New access token works" } else { Test-Failure "New access token" "User mismatch" } } catch { Test-Failure "New access token" $_.Exception.Message } # Test 6: Logout Write-Host "`n[Test 6] Logout revokes token" -ForegroundColor White try { $logoutBody = @{ refreshToken = $refresh2 } | ConvertTo-Json $logout = Invoke-RestMethod -Uri "$baseUrl/api/auth/logout" -Method Post -ContentType "application/json" -Body $logoutBody if ($logout.message -like "*success*") { Test-Success "Logout successful" } else { Test-Failure "Logout" "No success message" } } catch { Test-Failure "Logout" $_.Exception.Message } # Test 7: Revoked token rejected Write-Host "`n[Test 7] Revoked token rejected" -ForegroundColor White try { $revokeBody = @{ refreshToken = $refresh2 } | ConvertTo-Json try { $bad2 = Invoke-RestMethod -Uri "$baseUrl/api/auth/refresh" -Method Post -ContentType "application/json" -Body $revokeBody Test-Failure "Revoked token rejection" "Revoked token accepted!" } catch { $code = $_.Exception.Response.StatusCode.value__ if ($code -eq 401) { Test-Success "Revoked token rejected (401)" } else { Test-Failure "Revoked token rejection" "Got status $code" } } } catch { Test-Failure "Revoked token test" $_.Exception.Message } # ====================== # PHASE 2: RBAC TESTS # ====================== Write-Host "`n--- PHASE 2: RBAC TESTS ---`n" -ForegroundColor Yellow # Test 8: Register for RBAC Write-Host "[Test 8] Register tenant for RBAC test" -ForegroundColor White $slug2 = "rbac-$(Get-Random -Minimum 1000 -Maximum 9999)" $body2 = @{ tenantName = "RBAC Corp" tenantSlug = $slug2 subscriptionPlan = "Professional" adminEmail = "rbac@test.com" adminPassword = "Admin@1234" adminFullName = "RBAC Admin" } | ConvertTo-Json try { $reg2 = Invoke-RestMethod -Uri "$baseUrl/api/tenants/register" -Method Post -ContentType "application/json" -Body $body2 $rbacToken = $reg2.accessToken $rbacRefresh = $reg2.refreshToken Test-Success "RBAC test tenant registered" } catch { Test-Failure "RBAC tenant registration" $_.Exception.Message } # Test 9: Verify TenantOwner role Write-Host "`n[Test 9] Verify TenantOwner role assigned" -ForegroundColor White try { $rbacHeaders = @{ "Authorization" = "Bearer $rbacToken" } $rbacMe = Invoke-RestMethod -Uri "$baseUrl/api/auth/me" -Method Get -Headers $rbacHeaders if ($rbacMe.tenantRole -eq "TenantOwner" -and $rbacMe.role -eq "TenantOwner") { Test-Success "TenantOwner role correctly assigned" } else { Test-Failure "TenantOwner role" "Got: tenantRole=$($rbacMe.tenantRole), role=$($rbacMe.role)" } } catch { Test-Failure "Role verification" $_.Exception.Message } # Test 10: Role persistence after login Write-Host "`n[Test 10] Role persists after login" -ForegroundColor White try { $loginBody = @{ tenantSlug = $slug2 email = "rbac@test.com" password = "Admin@1234" } | ConvertTo-Json $login = Invoke-RestMethod -Uri "$baseUrl/api/auth/login" -Method Post -ContentType "application/json" -Body $loginBody $loginToken = $login.accessToken $loginHeaders = @{ "Authorization" = "Bearer $loginToken" } $loginMe = Invoke-RestMethod -Uri "$baseUrl/api/auth/me" -Method Get -Headers $loginHeaders if ($loginMe.tenantRole -eq "TenantOwner") { Test-Success "Role persists after login" } else { Test-Failure "Role persistence" "Got: $($loginMe.tenantRole)" } } catch { Test-Failure "Login role persistence" $_.Exception.Message } # Test 11: Role in refreshed token Write-Host "`n[Test 11] Role preserved in refreshed token" -ForegroundColor White try { $refreshBody2 = @{ refreshToken = $rbacRefresh } | ConvertTo-Json $refRes2 = Invoke-RestMethod -Uri "$baseUrl/api/auth/refresh" -Method Post -ContentType "application/json" -Body $refreshBody2 $refreshedToken = $refRes2.accessToken $refreshedHeaders = @{ "Authorization" = "Bearer $refreshedToken" } $refreshedMe = Invoke-RestMethod -Uri "$baseUrl/api/auth/me" -Method Get -Headers $refreshedHeaders if ($refreshedMe.tenantRole -eq "TenantOwner") { Test-Success "Role preserved in refreshed token" } else { Test-Failure "Role in refreshed token" "Got: $($refreshedMe.tenantRole)" } } catch { Test-Failure "Refreshed token role" $_.Exception.Message } # Test 12: JWT claims present Write-Host "`n[Test 12] All required JWT claims present" -ForegroundColor White try { $claimsHeaders = @{ "Authorization" = "Bearer $rbacToken" } $claims = Invoke-RestMethod -Uri "$baseUrl/api/auth/me" -Method Get -Headers $claimsHeaders $hasAll = $claims.userId -and $claims.email -and $claims.tenantRole -and $claims.role -and $claims.tenantId if ($hasAll) { Test-Success "All required claims present" } else { Test-Failure "JWT claims" "Missing claims" } } catch { Test-Failure "Claims inspection" $_.Exception.Message } # ====================== # PHASE 3: REGRESSION # ====================== Write-Host "`n--- PHASE 3: REGRESSION TESTS (Day 4) ---`n" -ForegroundColor Yellow # Test 13: Password hashing Write-Host "[Test 13] Password hashing still works" -ForegroundColor White try { $slug3 = "hash-$(Get-Random -Minimum 1000 -Maximum 9999)" $body3 = @{ tenantName = "Hash Test" tenantSlug = $slug3 subscriptionPlan = "Free" adminEmail = "hash@test.com" adminPassword = "Password@123" adminFullName = "Hasher" } | ConvertTo-Json $reg3 = Invoke-RestMethod -Uri "$baseUrl/api/tenants/register" -Method Post -ContentType "application/json" -Body $body3 $loginBody3 = @{ tenantSlug = $slug3 email = "hash@test.com" password = "Password@123" } | ConvertTo-Json $login3 = Invoke-RestMethod -Uri "$baseUrl/api/auth/login" -Method Post -ContentType "application/json" -Body $loginBody3 if ($login3.accessToken) { Test-Success "Password hashing working (Day 4 regression)" } else { Test-Failure "Password hashing" "Login failed" } } catch { Test-Failure "Password hashing test" $_.Exception.Message } # Test 14: JWT authentication Write-Host "`n[Test 14] JWT authentication still works" -ForegroundColor White try { $jwtHeaders = @{ "Authorization" = "Bearer $rbacToken" } $jwtMe = Invoke-RestMethod -Uri "$baseUrl/api/auth/me" -Method Get -Headers $jwtHeaders if ($jwtMe.userId) { Test-Success "JWT authentication working (Day 4 regression)" } else { Test-Failure "JWT authentication" "No user data" } } catch { Test-Failure "JWT regression test" $_.Exception.Message } # ====================== # TEST SUMMARY # ====================== Write-Host "`n================================================" -ForegroundColor Magenta Write-Host "TEST EXECUTION SUMMARY" -ForegroundColor Magenta Write-Host "================================================" -ForegroundColor Magenta Write-Host "`nTotal Tests: $testsTotal" -ForegroundColor White Write-Host "Tests Passed: $testsPassed" -ForegroundColor Green Write-Host "Tests Failed: $testsFailed" -ForegroundColor $(if ($testsFailed -eq 0) { "Green" } else { "Red" }) $passRate = if ($testsTotal -gt 0) { [math]::Round(($testsPassed / $testsTotal) * 100, 2) } else { 0 } Write-Host "Pass Rate: $passRate%" -ForegroundColor $(if ($passRate -ge 90) { "Green" } elseif ($passRate -ge 70) { "Yellow" } else { "Red" }) Write-Host "`n================================================" -ForegroundColor Magenta if ($passRate -ge 95) { Write-Host "RESULT: EXCELLENT - Ready for production!" -ForegroundColor Green exit 0 } elseif ($passRate -ge 80) { Write-Host "RESULT: GOOD - Minor issues found" -ForegroundColor Yellow exit 1 } else { Write-Host "RESULT: CRITICAL - Major issues found!" -ForegroundColor Red exit 1 }