test_all_apis.ps1 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. # Full API test using /login and database menu queries
  2. $companyUrl = "http://localhost:8006"
  3. # Step 1: Login via /login (which is in SecurityConfig anonymous whitelist)
  4. Write-Host "=== Step 1: Login ==="
  5. $loginBody = '{"tenantCode":"T202605253515","username":"admin","password":"admin123"}'
  6. $loginResp = Invoke-WebRequest -Uri "$companyUrl/login" -Method POST -ContentType "application/json" -Body $loginBody -UseBasicParsing
  7. $loginJson = $loginResp.Content | ConvertFrom-Json
  8. $token = $loginJson.token
  9. Write-Host "Token OK, length: $($token.Length)"
  10. $headers = @{ Authorization = "Bearer $token" }
  11. # Step 2: Get menu routes via getRouters
  12. Write-Host "`n=== Step 2: Get Routers ==="
  13. $routesResp = Invoke-WebRequest -Uri "$companyUrl/getRouters" -Method GET -Headers $headers -UseBasicParsing
  14. $routesJson = $routesResp.Content | ConvertFrom-Json
  15. Write-Host "getRouters code: $($routesJson.code)"
  16. # Recursive extract perms from menu tree
  17. function Extract-Perms {
  18. param($menuList)
  19. $results = @()
  20. foreach ($menu in $menuList) {
  21. if ($menu.perms -and $menu.perms.Trim() -ne "") {
  22. $results += $menu.perms
  23. }
  24. if ($menu.children -and $menu.children.Count -gt 0) {
  25. $results += Extract-Perms -menuList $menu.children
  26. }
  27. }
  28. return $results
  29. }
  30. $allPerms = Extract-Perms -menuList $routesJson.data
  31. Write-Host "Perms from getRouters: $($allPerms.Count)"
  32. # Step 3: Also get menu list from system/menu/list (has more detail including buttons)
  33. Write-Host "`n=== Step 3: Get Menu List ==="
  34. try {
  35. $menuResp = Invoke-WebRequest -Uri "$companyUrl/system/menu/list" -Method GET -Headers $headers -UseBasicParsing
  36. $menuJson = $menuResp.Content | ConvertFrom-Json
  37. Write-Host "system/menu/list code: $($menuJson.code), total: $($menuJson.total)"
  38. # Extract perms from menu list
  39. $menuPerms = @()
  40. foreach ($row in $menuJson.rows) {
  41. if ($row.perms -and $row.perms.Trim() -ne "") {
  42. $menuPerms += $row.perms
  43. }
  44. }
  45. Write-Host "Perms from system/menu/list: $($menuPerms.Count)"
  46. } catch {
  47. Write-Host "system/menu/list error: $($_.Exception.Message)"
  48. $menuPerms = @()
  49. }
  50. # Merge all perms
  51. $allPerms = $allPerms + $menuPerms | Sort-Object -Unique
  52. Write-Host "`nTotal unique perms: $($allPerms.Count)"
  53. # Step 4: Convert perms to API paths
  54. # perms format: module:entity:action -> /module/entity/action
  55. $apiPaths = @{}
  56. foreach ($perm in $allPerms) {
  57. if ($perm -match "^\s*$") { continue }
  58. $parts = $perm -split ":"
  59. if ($parts.Count -ge 3) {
  60. $mod = $parts[0]
  61. $ent = $parts[1]
  62. $act = $parts[2]
  63. $p = "/$mod/$ent/$act"
  64. if (-not $apiPaths.ContainsKey($p)) { $apiPaths[$p] = $perm }
  65. } elseif ($parts.Count -eq 2) {
  66. $mod = $parts[0]
  67. $ent = $parts[1]
  68. $p = "/$mod/$ent/list"
  69. if (-not $apiPaths.ContainsKey($p)) { $apiPaths[$p] = $perm }
  70. }
  71. }
  72. Write-Host "Total unique API paths from perms: $($apiPaths.Count)"
  73. # Step 5: Also extract component paths from menus (page routes)
  74. Write-Host "`n=== Step 5: Extract page routes ==="
  75. $pagePaths = @{}
  76. function Extract-PageRoutes {
  77. param($menuList)
  78. foreach ($menu in $menuList) {
  79. if ($menu.path -and $menu.path -ne "" -and $menu.component -and $menu.component -ne "") {
  80. $pagePaths[$menu.path] = $menu.component
  81. }
  82. if ($menu.children -and $menu.children.Count -gt 0) {
  83. Extract-PageRoutes -menuList $menu.children
  84. }
  85. }
  86. }
  87. Extract-PageRoutes -menuList $routesJson.data
  88. Write-Host "Page routes: $($pagePaths.Count)"
  89. # Step 6: Now scan saasadminui src/api for ALL API URLs
  90. Write-Host "`n=== Step 6: Scan saasadminui src/api for URLs ==="
  91. $apiFiles = Get-ChildItem -Path "d:\ylrz\saasadminui\src\api" -Recurse -Filter "*.js"
  92. $frontendApis = @{}
  93. foreach ($file in $apiFiles) {
  94. $content = Get-Content $file.FullName -Raw -Encoding UTF8
  95. # Match url patterns: url: '/xxx/yyy/zzz' or url: "/xxx/yyy/zzz"
  96. $matches = [regex]::Matches($content, "url:\s*['`"]([^'`"]+)['`"]")
  97. foreach ($m in $matches) {
  98. $url = $m.Groups[1].Value
  99. # Remove template variables like ${xxx}
  100. $cleanUrl = $url -replace '\$\{[^}]+\}', '1'
  101. if (-not $frontendApis.ContainsKey($cleanUrl)) {
  102. $frontendApis[$cleanUrl] = $file.Name
  103. }
  104. }
  105. }
  106. Write-Host "Frontend API URLs found: $($frontendApis.Count)"
  107. # Step 7: Test ALL unique API paths (from perms + frontend)
  108. Write-Host "`n=== Step 7: Test all API endpoints ==="
  109. # Merge all paths
  110. $testPaths = @{}
  111. foreach ($p in $apiPaths.Keys) { if (-not $testPaths.ContainsKey($p)) { $testPaths[$p] = "perms:$($apiPaths[$p])" } }
  112. foreach ($p in $frontendApis.Keys) {
  113. if (-not $testPaths.ContainsKey($p)) { $testPaths[$p] = "frontend:$($frontendApis[$p])" }
  114. }
  115. Write-Host "Total unique paths to test: $($testPaths.Count)"
  116. $ok = [System.Collections.ArrayList]::new()
  117. $notFound = [System.Collections.ArrayList]::new()
  118. $serverErr = [System.Collections.ArrayList]::new()
  119. $forbidden = [System.Collections.ArrayList]::new()
  120. $timeout = [System.Collections.ArrayList]::new()
  121. $other = [System.Collections.ArrayList]::new()
  122. $i = 0
  123. $total = $testPaths.Count
  124. foreach ($path in ($testPaths.Keys | Sort-Object)) {
  125. $i++
  126. $source = $testPaths[$path]
  127. if ($i % 100 -eq 0) { Write-Host " Progress: $i / $total" }
  128. # Determine method - GET for list/query, POST for add/edit/remove
  129. $method = "GET"
  130. if ($path -match "/add|/edit|/remove|/delete|/save|/update|/import|/export|/upload") {
  131. $method = "POST"
  132. }
  133. try {
  134. if ($method -eq "GET") {
  135. $resp = Invoke-WebRequest -Uri "$companyUrl$path" -Method GET -Headers $headers -UseBasicParsing -TimeoutSec 8
  136. } else {
  137. $resp = Invoke-WebRequest -Uri "$companyUrl$path" -Method POST -Headers $headers -ContentType "application/json" -Body "{}" -UseBasicParsing -TimeoutSec 8
  138. }
  139. $body = $resp.Content | ConvertFrom-Json
  140. if ($body.code -and $body.code -ne 200) {
  141. $code = "$($body.code)"
  142. if ($code -eq "404") { [void]$notFound.Add("$path | $source") }
  143. elseif ($code -eq "500") { [void]$serverErr.Add("$path | $source") }
  144. elseif ($code -eq "403") { [void]$forbidden.Add("$path | $source") }
  145. else { [void]$other.Add("$path | $source | code=$code") }
  146. } else {
  147. [void]$ok.Add("$path | $source")
  148. }
  149. } catch {
  150. $err = "$($_.Exception.Message)"
  151. if ($err -match "404") { [void]$notFound.Add("$path | $source") }
  152. elseif ($err -match "500") { [void]$serverErr.Add("$path | $source") }
  153. elseif ($err -match "403") { [void]$forbidden.Add("$path | $source") }
  154. elseif ($err -match "timeout|timed out") { [void]$timeout.Add("$path | $source") }
  155. else { [void]$other.Add("$path | $source | err") }
  156. }
  157. }
  158. # Step 8: Summary
  159. Write-Host "`n========================================"
  160. Write-Host "=== API Test Results ==="
  161. Write-Host "========================================"
  162. Write-Host "200 OK: $($ok.Count)"
  163. Write-Host "404 Not Found: $($notFound.Count)"
  164. Write-Host "500 Server Error: $($serverErr.Count)"
  165. Write-Host "403 Forbidden: $($forbidden.Count)"
  166. Write-Host "TIMEOUT: $($timeout.Count)"
  167. Write-Host "OTHER: $($other.Count)"
  168. if ($notFound.Count -gt 0) {
  169. Write-Host "`n--- 404 Details ---"
  170. $notFound | Sort-Object | ForEach-Object { Write-Host " $_" }
  171. }
  172. if ($serverErr.Count -gt 0) {
  173. Write-Host "`n--- 500 Details ---"
  174. $serverErr | Sort-Object | ForEach-Object { Write-Host " $_" }
  175. }
  176. if ($forbidden.Count -gt 0) {
  177. Write-Host "`n--- 403 Details ---"
  178. $forbidden | Sort-Object | ForEach-Object { Write-Host " $_" }
  179. }
  180. if ($timeout.Count -gt 0) {
  181. Write-Host "`n--- TIMEOUT Details ---"
  182. $timeout | Sort-Object | ForEach-Object { Write-Host " $_" }
  183. }
  184. if ($other.Count -gt 0) {
  185. Write-Host "`n--- OTHER Details ---"
  186. $other | Sort-Object | ForEach-Object { Write-Host " $_" }
  187. }
  188. # Save results
  189. $out = [System.Collections.ArrayList]::new()
  190. [void]$out.Add("API Test Results - $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')")
  191. [void]$out.Add("=" * 60)
  192. [void]$out.Add("200 OK: $($ok.Count)")
  193. [void]$out.Add("404 Not Found: $($notFound.Count)")
  194. [void]$out.Add("500 Server Error: $($serverErr.Count)")
  195. [void]$out.Add("403 Forbidden: $($forbidden.Count)")
  196. [void]$out.Add("TIMEOUT: $($timeout.Count)")
  197. [void]$out.Add("OTHER: $($other.Count)")
  198. [void]$out.Add("")
  199. [void]$out.Add("=== 200 OK ===")
  200. $ok | Sort-Object | ForEach-Object { [void]$out.Add($_) }
  201. [void]$out.Add("")
  202. [void]$out.Add("=== 404 Not Found ===")
  203. $notFound | Sort-Object | ForEach-Object { [void]$out.Add($_) }
  204. [void]$out.Add("")
  205. [void]$out.Add("=== 500 Server Error ===")
  206. $serverErr | Sort-Object | ForEach-Object { [void]$out.Add($_) }
  207. [void]$out.Add("")
  208. [void]$out.Add("=== 403 Forbidden ===")
  209. $forbidden | Sort-Object | ForEach-Object { [void]$out.Add($_) }
  210. [void]$out.Add("")
  211. [void]$out.Add("=== TIMEOUT ===")
  212. $timeout | Sort-Object | ForEach-Object { [void]$out.Add($_) }
  213. [void]$out.Add("")
  214. [void]$out.Add("=== OTHER ===")
  215. $other | Sort-Object | ForEach-Object { [void]$out.Add($_) }
  216. [System.IO.File]::WriteAllLines("d:\ylrz\saasadminui\api_test_results.txt", $out, (New-Object System.Text.UTF8Encoding($false)))
  217. Write-Host "`nResults saved to d:\ylrz\saasadminui\api_test_results.txt"