# Comprehensive API test script for saasadminui # 1. Login to get token # 2. Extract all API paths from saasadminui frontend source # 3. Test each API against fs-company (8006) # 4. Categorize results: 200, 404, 500, 403 $companyUrl = "http://localhost:8006" # Step 1: Login Write-Host "=== Step 1: Login ===" $loginBody = '{"username":"admin","password":"admin123","tenantCode":"T202605253515"}' $loginResp = Invoke-RestMethod -Uri "$companyUrl/login" -Method POST -ContentType "application/json" -Body $loginBody $token = $loginResp.token Write-Host "Login OK, token length: $($token.Length)" $headers = @{ Authorization = "Bearer $token" } # Step 2: Extract API paths from saasadminui frontend source Write-Host "`n=== Step 2: Extract API paths ===" $apiDir = "d:\ylrz\saasadminui\src\api" $apiPaths = @{} Get-ChildItem -Path $apiDir -Filter "*.js" -Recurse | ForEach-Object { $content = Get-Content $_.FullName -Raw -Encoding UTF8 # Match patterns like: url: '/xxx/yyy' or url: "/xxx/yyy" or request({ url: '/xxx/yyy' $matches = [regex]::Matches($content, "[Uu][Rr][Ll]\s*[:=]\s*['""]([^'""]+)['""]") foreach ($m in $matches) { $path = $m.Groups[1].Value if ($path -match "^/" -and $path -notmatch "\$\{" -and $path -notmatch "^/proxy") { # Determine HTTP method from context $method = "GET" $lineBefore = $content.Substring(0, $m.Index) if ($lineBefore -match "(?m)(delete|remove|del)\s*\(" -or $path -match "/del|/remove") { $method = "DELETE" } elseif ($lineBefore -match "(?m)(add|create|save|insert|post|upload)\s*\(" -or $path -match "/add|/create|/save|/upload") { $method = "POST" } elseif ($lineBefore -match "(?m)(update|edit|modify|put)\s*\(" -or $path -match "/edit|/update") { $method = "PUT" } if (-not $apiPaths.ContainsKey($path)) { $apiPaths[$path] = $method } } } } Write-Host "Found $($apiPaths.Count) unique API paths" # Step 3: Test each API Write-Host "`n=== Step 3: Testing APIs ===" $results = @{ ok = 0; notFound = 0; serverError = 0; forbidden = 0; other = 0 } $notFoundList = @() $serverErrorList = @() $forbiddenList = @() $errorDetails = @{} $total = $apiPaths.Count $idx = 0 foreach ($path in ($apiPaths.Keys | Sort-Object)) { $idx++ $method = $apiPaths[$path] $url = "$companyUrl$path" try { if ($method -eq "GET") { $resp = Invoke-WebRequest -Uri $url -Headers $headers -Method GET -UseBasicParsing -TimeoutSec 10 } elseif ($method -eq "POST") { $resp = Invoke-WebRequest -Uri $url -Headers $headers -Method POST -ContentType "application/json" -Body "{}" -UseBasicParsing -TimeoutSec 10 } elseif ($method -eq "PUT") { $resp = Invoke-WebRequest -Uri $url -Headers $headers -Method PUT -ContentType "application/json" -Body "{}" -UseBasicParsing -TimeoutSec 10 } elseif ($method -eq "DELETE") { $resp = Invoke-WebRequest -Uri $url -Headers $headers -Method DELETE -UseBasicParsing -TimeoutSec 10 } $code = $resp.StatusCode $results.ok++ } catch { $statusCode = $_.Exception.Response.StatusCode.value__ if ($statusCode -eq 404) { $results.notFound++ $notFoundList += $path } elseif ($statusCode -eq 500) { $results.serverError++ $serverErrorList += $path # Get error message try { $reader = New-Object System.IO.StreamReader($_.Exception.Response.GetResponseStream()) $errBody = $reader.ReadToEnd() $reader.Close() if ($errBody -match '"message":"([^"]+)"') { $errorDetails[$path] = $matches[1] } elseif ($errBody -match '"msg":"([^"]+)"') { $errorDetails[$path] = $matches[1] } } catch {} } elseif ($statusCode -eq 403) { $results.forbidden++ $forbiddenList += $path } else { $results.other++ } } if ($idx % 100 -eq 0) { Write-Host " Progress: $idx / $total (200=$($results.ok), 404=$($results.notFound), 500=$($results.serverError))" } } # Step 4: Output results Write-Host "`n=== Results ===" Write-Host "200 OK: $($results.ok)" Write-Host "404 Not Found: $($results.notFound)" Write-Host "500 Server Error: $($results.serverError)" Write-Host "403 Forbidden: $($results.forbidden)" Write-Host "Other: $($results.other)" # Save detailed results $notFoundList | Out-File -FilePath "d:\ylrz\saasadminui\api_404.txt" -Encoding UTF8 $serverErrorList | Out-File -FilePath "d:\ylrz\saasadminui\api_500.txt" -Encoding UTF8 $forbiddenList | Out-File -FilePath "d:\ylrz\saasadminui\api_403.txt" -Encoding UTF8 # Analyze 404 by prefix Write-Host "`n=== 404 by prefix ===" $notFoundByPrefix = @{} foreach ($p in $notFoundList) { $parts = $p.Split("/") if ($parts.Length -ge 3) { $prefix = "/$($parts[1])/$($parts[2])" } elseif ($parts.Length -ge 2) { $prefix = "/$($parts[1])" } else { $prefix = $p } if (-not $notFoundByPrefix.ContainsKey($prefix)) { $notFoundByPrefix[$prefix] = 0 } $notFoundByPrefix[$prefix]++ } $notFoundByPrefix.GetEnumerator() | Sort-Object Value -Descending | Select-Object -First 30 | ForEach-Object { Write-Host " $($_.Key): $($_.Value)" } Write-Host "`n=== 500 by prefix ===" $serverErrorByPrefix = @{} foreach ($p in $serverErrorList) { $parts = $p.Split("/") if ($parts.Length -ge 3) { $prefix = "/$($parts[1])/$($parts[2])" } elseif ($parts.Length -ge 2) { $prefix = "/$($parts[1])" } else { $prefix = $p } if (-not $serverErrorByPrefix.ContainsKey($prefix)) { $serverErrorByPrefix[$prefix] = 0 } $serverErrorByPrefix[$prefix]++ } $serverErrorByPrefix.GetEnumerator() | Sort-Object Value -Descending | Select-Object -First 30 | ForEach-Object { Write-Host " $($_.Key): $($_.Value)" } Write-Host "`n=== 500 error details ===" $errorDetails.GetEnumerator() | Select-Object -First 30 | ForEach-Object { Write-Host " $($_.Key): $($_.Value)" } Write-Host "`nDone!"