@roomi-fields/notebooklm-mcp 1.5.7 → 1.5.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (295) hide show
  1. package/LICENSE +22 -22
  2. package/README.md +219 -219
  3. package/deployment/INDEX.md +0 -0
  4. package/deployment/PACKAGE-FILES.txt +180 -180
  5. package/deployment/QUICK-START.md +0 -0
  6. package/deployment/docs/01-INSTALL.md +21 -1
  7. package/deployment/docs/02-CONFIGURATION.md +0 -0
  8. package/deployment/docs/03-API.md +16 -10
  9. package/deployment/docs/04-N8N-INTEGRATION.md +0 -0
  10. package/deployment/docs/05-TROUBLESHOOTING.md +19 -1
  11. package/deployment/docs/06-NOTEBOOK-LIBRARY.md +9 -9
  12. package/deployment/docs/07-AUTO-DISCOVERY.md +6 -15
  13. package/deployment/docs/08-DOCKER.md +0 -0
  14. package/deployment/docs/08-WSL-USAGE.md +7 -7
  15. package/deployment/docs/09-MULTI-INTERFACE.md +6 -6
  16. package/deployment/docs/10-CONTENT-MANAGEMENT.md +0 -0
  17. package/deployment/docs/11-MULTI-ACCOUNT.md +1 -1
  18. package/deployment/docs/README.md +0 -0
  19. package/deployment/scripts/README.md +0 -0
  20. package/deployment/scripts/install.ps1 +114 -114
  21. package/deployment/scripts/setup-auth.ps1 +217 -217
  22. package/deployment/scripts/start-server.ps1 +72 -72
  23. package/deployment/scripts/stop-server.ps1 +51 -51
  24. package/deployment/scripts/test-api.ps1 +651 -651
  25. package/deployment/scripts/test-auth.ps1 +0 -0
  26. package/deployment/scripts/test-auto-discovery.ps1 +295 -295
  27. package/deployment/scripts/test-cors.ps1 +398 -398
  28. package/deployment/scripts/test-errors.ps1 +581 -581
  29. package/deployment/scripts/test-server.ps1 +140 -140
  30. package/deployment/scripts/test-sessions.ps1 +426 -426
  31. package/deployment/scripts/test-validation.ps1 +299 -299
  32. package/dist/accounts/account-manager.d.ts +0 -0
  33. package/dist/accounts/account-manager.d.ts.map +0 -0
  34. package/dist/accounts/account-manager.js +0 -0
  35. package/dist/accounts/account-manager.js.map +0 -0
  36. package/dist/accounts/auto-login-manager.d.ts +0 -0
  37. package/dist/accounts/auto-login-manager.d.ts.map +0 -0
  38. package/dist/accounts/auto-login-manager.js +0 -0
  39. package/dist/accounts/auto-login-manager.js.map +0 -0
  40. package/dist/accounts/crypto.d.ts +0 -0
  41. package/dist/accounts/crypto.d.ts.map +0 -0
  42. package/dist/accounts/crypto.js +0 -0
  43. package/dist/accounts/crypto.js.map +0 -0
  44. package/dist/accounts/index.d.ts +0 -0
  45. package/dist/accounts/index.d.ts.map +0 -0
  46. package/dist/accounts/index.js +0 -0
  47. package/dist/accounts/index.js.map +0 -0
  48. package/dist/accounts/types.d.ts +0 -0
  49. package/dist/accounts/types.d.ts.map +0 -0
  50. package/dist/accounts/types.js +0 -0
  51. package/dist/accounts/types.js.map +0 -0
  52. package/dist/auth/auth-manager.d.ts +0 -0
  53. package/dist/auth/auth-manager.d.ts.map +0 -0
  54. package/dist/auth/auth-manager.js +0 -0
  55. package/dist/auth/auth-manager.js.map +0 -0
  56. package/dist/auto-discovery/auto-discovery.d.ts +0 -0
  57. package/dist/auto-discovery/auto-discovery.d.ts.map +0 -0
  58. package/dist/auto-discovery/auto-discovery.js +0 -0
  59. package/dist/auto-discovery/auto-discovery.js.map +0 -0
  60. package/dist/cli/accounts.d.ts +0 -0
  61. package/dist/cli/accounts.d.ts.map +0 -0
  62. package/dist/cli/accounts.js +0 -0
  63. package/dist/cli/accounts.js.map +0 -0
  64. package/dist/cli/de-auth.d.ts +0 -0
  65. package/dist/cli/de-auth.d.ts.map +0 -0
  66. package/dist/cli/de-auth.js +0 -0
  67. package/dist/cli/de-auth.js.map +0 -0
  68. package/dist/cli/help.d.ts +0 -0
  69. package/dist/cli/help.d.ts.map +0 -0
  70. package/dist/cli/help.js +5 -0
  71. package/dist/cli/help.js.map +1 -1
  72. package/dist/cli/setup-auth.d.ts +0 -0
  73. package/dist/cli/setup-auth.d.ts.map +0 -0
  74. package/dist/cli/setup-auth.js +0 -0
  75. package/dist/cli/setup-auth.js.map +0 -0
  76. package/dist/config.d.ts +0 -0
  77. package/dist/config.d.ts.map +0 -0
  78. package/dist/config.js +0 -0
  79. package/dist/config.js.map +0 -0
  80. package/dist/content/content-generator.d.ts +0 -0
  81. package/dist/content/content-generator.d.ts.map +0 -0
  82. package/dist/content/content-generator.js +0 -0
  83. package/dist/content/content-generator.js.map +0 -0
  84. package/dist/content/content-manager.d.ts +8 -0
  85. package/dist/content/content-manager.d.ts.map +1 -1
  86. package/dist/content/content-manager.js +411 -67
  87. package/dist/content/content-manager.js.map +1 -1
  88. package/dist/content/content-templates.d.ts +0 -0
  89. package/dist/content/content-templates.d.ts.map +0 -0
  90. package/dist/content/content-templates.js +0 -0
  91. package/dist/content/content-templates.js.map +0 -0
  92. package/dist/content/index.d.ts +0 -0
  93. package/dist/content/index.d.ts.map +0 -0
  94. package/dist/content/index.js +0 -0
  95. package/dist/content/index.js.map +0 -0
  96. package/dist/content/types.d.ts +0 -0
  97. package/dist/content/types.d.ts.map +0 -0
  98. package/dist/content/types.js +0 -0
  99. package/dist/content/types.js.map +0 -0
  100. package/dist/errors.d.ts +0 -0
  101. package/dist/errors.d.ts.map +0 -0
  102. package/dist/errors.js +0 -0
  103. package/dist/errors.js.map +0 -0
  104. package/dist/http-wrapper.d.ts +0 -0
  105. package/dist/http-wrapper.d.ts.map +0 -0
  106. package/dist/http-wrapper.js +0 -0
  107. package/dist/http-wrapper.js.map +0 -0
  108. package/dist/i18n/en.json +0 -0
  109. package/dist/i18n/fr.json +0 -0
  110. package/dist/i18n/index.d.ts +0 -0
  111. package/dist/i18n/index.d.ts.map +0 -0
  112. package/dist/i18n/index.js +0 -0
  113. package/dist/i18n/index.js.map +0 -0
  114. package/dist/index.d.ts +0 -0
  115. package/dist/index.d.ts.map +0 -0
  116. package/dist/index.js +0 -0
  117. package/dist/index.js.map +0 -0
  118. package/dist/library/notebook-library.d.ts +0 -0
  119. package/dist/library/notebook-library.d.ts.map +0 -0
  120. package/dist/library/notebook-library.js +0 -0
  121. package/dist/library/notebook-library.js.map +0 -0
  122. package/dist/library/types.d.ts +0 -0
  123. package/dist/library/types.d.ts.map +0 -0
  124. package/dist/library/types.js +0 -0
  125. package/dist/library/types.js.map +0 -0
  126. package/dist/session/browser-session.d.ts +12 -0
  127. package/dist/session/browser-session.d.ts.map +1 -1
  128. package/dist/session/browser-session.js +156 -32
  129. package/dist/session/browser-session.js.map +1 -1
  130. package/dist/session/session-manager.d.ts +0 -0
  131. package/dist/session/session-manager.d.ts.map +0 -0
  132. package/dist/session/session-manager.js +0 -0
  133. package/dist/session/session-manager.js.map +0 -0
  134. package/dist/session/shared-context-manager.d.ts +0 -0
  135. package/dist/session/shared-context-manager.d.ts.map +0 -0
  136. package/dist/session/shared-context-manager.js +0 -0
  137. package/dist/session/shared-context-manager.js.map +0 -0
  138. package/dist/startup/startup-manager.d.ts +0 -0
  139. package/dist/startup/startup-manager.d.ts.map +0 -0
  140. package/dist/startup/startup-manager.js +0 -0
  141. package/dist/startup/startup-manager.js.map +0 -0
  142. package/dist/stdio-http-proxy.d.ts +0 -0
  143. package/dist/stdio-http-proxy.d.ts.map +0 -0
  144. package/dist/stdio-http-proxy.js +0 -0
  145. package/dist/stdio-http-proxy.js.map +0 -0
  146. package/dist/tools/index.d.ts +0 -0
  147. package/dist/tools/index.d.ts.map +0 -0
  148. package/dist/tools/index.js +0 -0
  149. package/dist/tools/index.js.map +0 -0
  150. package/dist/types.d.ts +0 -0
  151. package/dist/types.d.ts.map +0 -0
  152. package/dist/types.js +0 -0
  153. package/dist/types.js.map +0 -0
  154. package/dist/utils/citation-extractor.d.ts +0 -0
  155. package/dist/utils/citation-extractor.d.ts.map +0 -0
  156. package/dist/utils/citation-extractor.js +67 -67
  157. package/dist/utils/citation-extractor.js.map +0 -0
  158. package/dist/utils/cleanup-manager.d.ts +0 -0
  159. package/dist/utils/cleanup-manager.d.ts.map +0 -0
  160. package/dist/utils/cleanup-manager.js +0 -0
  161. package/dist/utils/cleanup-manager.js.map +0 -0
  162. package/dist/utils/logger.d.ts +0 -0
  163. package/dist/utils/logger.d.ts.map +0 -0
  164. package/dist/utils/logger.js +0 -0
  165. package/dist/utils/logger.js.map +0 -0
  166. package/dist/utils/page-utils.d.ts +5 -0
  167. package/dist/utils/page-utils.d.ts.map +1 -1
  168. package/dist/utils/page-utils.js +73 -15
  169. package/dist/utils/page-utils.js.map +1 -1
  170. package/dist/utils/stealth-utils.d.ts +0 -0
  171. package/dist/utils/stealth-utils.d.ts.map +0 -0
  172. package/dist/utils/stealth-utils.js +0 -0
  173. package/dist/utils/stealth-utils.js.map +0 -0
  174. package/docs/ADDING_A_LANGUAGE.md +0 -0
  175. package/docs/ARCHITECTURE_MIGRATION_STUDY.md +0 -0
  176. package/docs/CHROME_PROFILE_LIMITATION.md +0 -0
  177. package/docs/MULTI_ACCOUNT_SYSTEM.md +0 -0
  178. package/package.json +5 -3
  179. package/scripts/archive/add-and-activate-notebook.ps1 +4 -4
  180. package/scripts/archive/add-new-notebook.ps1 +4 -4
  181. package/scripts/archive/add-rom1pey.ps1 +2 -2
  182. package/scripts/archive/add-rpmonster.ps1 +2 -2
  183. package/scripts/archive/add-source-debug.ps1 +1 -1
  184. package/scripts/archive/add-source-e2e.ps1 +1 -1
  185. package/scripts/archive/add-source-visible.ps1 +1 -1
  186. package/scripts/archive/add-test-notebook.ps1 +1 -1
  187. package/scripts/archive/add-test-source.ps1 +1 -1
  188. package/scripts/archive/capture-screen.ps1 +1 -1
  189. package/scripts/archive/change-language.mjs +4 -3
  190. package/scripts/archive/change-language.ts +5 -3
  191. package/scripts/archive/check-account.ps1 +0 -0
  192. package/scripts/archive/check-notebook-2.ps1 +0 -0
  193. package/scripts/archive/check-test-notebook.ps1 +0 -0
  194. package/scripts/archive/create-notebook-auto.ps1 +0 -0
  195. package/scripts/archive/create-notebook.ps1 +2 -2
  196. package/scripts/archive/create-rom1pey-notebook.ps1 +2 -2
  197. package/scripts/archive/create-rom1pey.ps1 +2 -2
  198. package/scripts/archive/create-test-notebook-fresh.ps1 +0 -0
  199. package/scripts/archive/create-test-notebook.ps1 +0 -0
  200. package/scripts/archive/debug-add-source-auto.ps1 +0 -0
  201. package/scripts/archive/debug-add-source.ps1 +0 -0
  202. package/scripts/archive/debug-add-text-source.ps1 +4 -4
  203. package/scripts/archive/debug-home.ps1 +0 -0
  204. package/scripts/archive/debug-selectors.ps1 +1 -1
  205. package/scripts/archive/debug-sources-panel.ps1 +0 -0
  206. package/scripts/archive/debug-ui.ps1 +0 -0
  207. package/scripts/archive/discover-home.ps1 +2 -2
  208. package/scripts/archive/kill-automation-chrome.ps1 +0 -0
  209. package/scripts/archive/list-my-notebooks.ps1 +0 -0
  210. package/scripts/archive/navigate-home-visible.ps1 +1 -1
  211. package/scripts/archive/navigate-home.ps1 +1 -1
  212. package/scripts/archive/run-e2e-english.ps1 +3 -3
  213. package/scripts/archive/run-e2e-rom1pey-v2.ps1 +4 -4
  214. package/scripts/archive/run-e2e-rom1pey.ps1 +4 -4
  215. package/scripts/archive/setup-english-test.ps1 +6 -6
  216. package/scripts/archive/setup-test-notebook.ps1 +1 -1
  217. package/scripts/archive/simple-add-source.ps1 +1 -1
  218. package/scripts/archive/t10.ps1 +1 -1
  219. package/scripts/archive/t20.ps1 +1 -1
  220. package/scripts/archive/t30.ps1 +1 -1
  221. package/scripts/archive/t31.ps1 +1 -1
  222. package/scripts/archive/t32.ps1 +1 -1
  223. package/scripts/archive/t39.ps1 +0 -0
  224. package/scripts/archive/t40.ps1 +0 -0
  225. package/scripts/archive/t53.ps1 +1 -1
  226. package/scripts/archive/t54.ps1 +0 -0
  227. package/scripts/archive/t55.ps1 +0 -0
  228. package/scripts/archive/t9.ps1 +0 -0
  229. package/scripts/archive/test-access.ps1 +1 -1
  230. package/scripts/archive/test-add-delete-source.ps1 +4 -4
  231. package/scripts/archive/test-add-source-visible.ps1 +1 -1
  232. package/scripts/archive/test-add-source.ps1 +1 -1
  233. package/scripts/archive/test-add-text-debug.ps1 +2 -2
  234. package/scripts/archive/test-add-text-source.ps1 +0 -0
  235. package/scripts/archive/test-add-url-source.ps1 +0 -0
  236. package/scripts/archive/test-ask-ascii.ps1 +0 -0
  237. package/scripts/archive/test-ask-cnv.ps1 +0 -0
  238. package/scripts/archive/test-ask-headed.ps1 +1 -1
  239. package/scripts/archive/test-ask-ifs.ps1 +0 -0
  240. package/scripts/archive/test-ask-now.ps1 +0 -0
  241. package/scripts/archive/test-ask-real.ps1 +0 -0
  242. package/scripts/archive/test-ask-visible.ps1 +0 -0
  243. package/scripts/archive/test-create-notebook.ps1 +0 -0
  244. package/scripts/archive/test-create-then-add.ps1 +0 -0
  245. package/scripts/archive/test-delete-source.ps1 +4 -4
  246. package/scripts/archive/test-e2e-notebook.ps1 +2 -2
  247. package/scripts/archive/test-english-notebook.ps1 +4 -4
  248. package/scripts/archive/test-english.ps1 +1 -1
  249. package/scripts/archive/test-full-custom-instructions.ps1 +1 -1
  250. package/scripts/archive/test-full-infographic.ps1 +1 -1
  251. package/scripts/archive/test-full-language.ps1 +1 -1
  252. package/scripts/archive/test-full-presentation.ps1 +1 -1
  253. package/scripts/archive/test-full-report.ps1 +1 -1
  254. package/scripts/archive/test-full-source-selection.ps1 +1 -1
  255. package/scripts/archive/test-full-video-brief.ps1 +1 -1
  256. package/scripts/archive/test-full-video-explainer.ps1 +1 -1
  257. package/scripts/archive/test-full-video-styles.ps1 +1 -1
  258. package/scripts/archive/test-generate-report.ps1 +0 -0
  259. package/scripts/archive/test-generate-study-guide.ps1 +0 -0
  260. package/scripts/archive/test-headed-ask.ps1 +1 -1
  261. package/scripts/archive/test-headed-now.ps1 +2 -2
  262. package/scripts/archive/test-headed.ps1 +2 -2
  263. package/scripts/archive/test-hello.ps1 +1 -1
  264. package/scripts/archive/test-i18n-studio.ps1 +0 -0
  265. package/scripts/archive/test-i18n.ps1 +0 -0
  266. package/scripts/archive/test-manual-headed.ps1 +1 -1
  267. package/scripts/archive/test-mathieu-quota.ps1 +1 -1
  268. package/scripts/archive/test-notebook-1.ps1 +0 -0
  269. package/scripts/archive/test-notebook-2-sources.ps1 +0 -0
  270. package/scripts/archive/test-notebook1.ps1 +0 -0
  271. package/scripts/archive/test-personal-notebook.ps1 +1 -1
  272. package/scripts/archive/test-rate-limit.ps1 +1 -1
  273. package/scripts/archive/test-real-ask.ps1 +1 -1
  274. package/scripts/archive/test-real-ask2.ps1 +1 -1
  275. package/scripts/archive/test-rom1pey.ps1 +1 -1
  276. package/scripts/archive/test-rotation-complete.ps1 +1 -1
  277. package/scripts/archive/test-rotation.ps1 +2 -2
  278. package/scripts/archive/test-show-browser.ps1 +1 -1
  279. package/scripts/archive/test-update-notebook.ps1 +1 -1
  280. package/scripts/archive/verify-language-slow.ps1 +1 -1
  281. package/scripts/archive/verify-language.ps1 +1 -1
  282. package/scripts/check-server.ps1 +0 -0
  283. package/scripts/docker-entrypoint.sh +25 -25
  284. package/scripts/doctor.mjs +257 -0
  285. package/scripts/mcp-proxy-hidden.ps1 +0 -0
  286. package/scripts/mcp-wsl-helper.sh +146 -146
  287. package/scripts/start-server-hidden.vbs +13 -10
  288. package/scripts/start-server.ps1 +1 -1
  289. package/scripts/start-vnc.sh +0 -0
  290. package/scripts/stop-server.bat +0 -0
  291. package/scripts/stop-server.ps1 +0 -0
  292. package/scripts/switch-account-language.sh +87 -128
  293. package/scripts/test-account.ps1 +0 -0
  294. package/docs/archive/auto-discovery-complet.md +0 -906
  295. package/scripts/add-totp.ts +0 -110
@@ -1,426 +1,426 @@
1
- #!/usr/bin/env pwsh
2
- #Requires -Version 5.1
3
-
4
- <#
5
- .SYNOPSIS
6
- Session management testing script for NotebookLM MCP HTTP Server API
7
-
8
- .DESCRIPTION
9
- Tests session management endpoints and behavior:
10
- - GET /sessions (list sessions)
11
- - DELETE /sessions/:id (close session)
12
- - POST /sessions/:id/reset (reset session)
13
- - Session error handling
14
-
15
- .PARAMETER BaseUrl
16
- Base URL of the server (default: http://localhost:3000)
17
-
18
- .EXAMPLE
19
- .\test-sessions.ps1
20
- Runs all session management tests
21
-
22
- .NOTES
23
- Prerequisite: The server must be started
24
- #>
25
-
26
- param(
27
- [string]$BaseUrl = "http://localhost:3000"
28
- )
29
-
30
- # Colors for logs
31
- function Write-TestHeader {
32
- param([string]$Message, [int]$Number, [int]$Total)
33
- Write-Host "`n" -NoNewline
34
- Write-Host "═══════════════════════════════════════════════════════" -ForegroundColor Magenta
35
- Write-Host " [$Number/$Total] $Message" -ForegroundColor Cyan
36
- Write-Host "═══════════════════════════════════════════════════════" -ForegroundColor Magenta
37
- }
38
-
39
- function Write-Success {
40
- param([string]$Message)
41
- Write-Host "✓ $Message" -ForegroundColor Green
42
- }
43
-
44
- function Write-Info {
45
- param([string]$Message)
46
- Write-Host "ℹ $Message" -ForegroundColor Yellow
47
- }
48
-
49
- function Write-ErrorExpected {
50
- param([string]$Message)
51
- Write-Host "✓ Expected error: $Message" -ForegroundColor Green
52
- }
53
-
54
- function Write-ErrorUnexpected {
55
- param([string]$Message)
56
- Write-Host "✗ $Message" -ForegroundColor Red
57
- }
58
-
59
- # Banner
60
- Clear-Host
61
- Write-Host "`n" -NoNewline
62
- Write-Host "╔════════════════════════════════════════════════════════╗" -ForegroundColor Magenta
63
- Write-Host "║ ║" -ForegroundColor Magenta
64
- Write-Host "║ SESSION MANAGEMENT TESTS - HTTP API ║" -ForegroundColor Cyan
65
- Write-Host "║ ║" -ForegroundColor Magenta
66
- Write-Host "╚════════════════════════════════════════════════════════╝" -ForegroundColor Magenta
67
- Write-Host ""
68
-
69
- # Check that the server is accessible
70
- Write-Host "Checking connection to server..." -ForegroundColor Yellow
71
- try {
72
- $null = Invoke-RestMethod -Uri "$BaseUrl/health" -TimeoutSec 5
73
- Write-Success "Server accessible at $BaseUrl"
74
- } catch {
75
- Write-ErrorUnexpected "Unable to connect to server at $BaseUrl"
76
- Write-Host "Make sure the server is started" -ForegroundColor Yellow
77
- exit 1
78
- }
79
-
80
- $TotalTests = 10
81
- $PassedTests = 0
82
- $FailedTests = 0
83
-
84
- # =============================================================================
85
- # TEST 1: GET /sessions - List sessions (should return array)
86
- # =============================================================================
87
- Write-TestHeader "GET /sessions - List active sessions" 1 $TotalTests
88
-
89
- try {
90
- $result = Invoke-RestMethod -Uri "$BaseUrl/sessions" -TimeoutSec 10
91
-
92
- if ($result.success -eq $true -and $null -ne $result.data) {
93
- $sessions = $result.data.sessions
94
- if ($null -ne $sessions -and $sessions -is [Array]) {
95
- Write-Success "Sessions list returned successfully"
96
- Write-Info "Active sessions: $($sessions.Count)"
97
- $PassedTests++
98
- } else {
99
- Write-ErrorUnexpected "Sessions data not in expected format"
100
- $FailedTests++
101
- }
102
- } else {
103
- Write-ErrorUnexpected "Failed to list sessions: $($result.error)"
104
- $FailedTests++
105
- }
106
- } catch {
107
- Write-ErrorUnexpected "Exception: $($_.Exception.Message)"
108
- $FailedTests++
109
- }
110
-
111
- # =============================================================================
112
- # TEST 2: GET /sessions - Response contains required fields
113
- # =============================================================================
114
- Write-TestHeader "GET /sessions - Response structure validation" 2 $TotalTests
115
-
116
- try {
117
- $result = Invoke-RestMethod -Uri "$BaseUrl/sessions" -TimeoutSec 10
118
-
119
- if ($result.success -eq $true) {
120
- $data = $result.data
121
-
122
- # Check for session count info
123
- $hasCount = $null -ne $data.total_count -or $null -ne $data.sessions
124
-
125
- if ($hasCount) {
126
- Write-Success "Response contains session information"
127
- if ($data.total_count) { Write-Info "Total count: $($data.total_count)" }
128
- if ($data.max_sessions) { Write-Info "Max sessions: $($data.max_sessions)" }
129
- $PassedTests++
130
- } else {
131
- Write-ErrorUnexpected "Missing session count information"
132
- $FailedTests++
133
- }
134
- } else {
135
- Write-ErrorUnexpected "Request failed: $($result.error)"
136
- $FailedTests++
137
- }
138
- } catch {
139
- Write-ErrorUnexpected "Exception: $($_.Exception.Message)"
140
- $FailedTests++
141
- }
142
-
143
- # =============================================================================
144
- # TEST 3: DELETE /sessions/:id - Non-existent session
145
- # =============================================================================
146
- Write-TestHeader "DELETE /sessions/:id - Non-existent session" 3 $TotalTests
147
-
148
- $fakeSessionId = "session-does-not-exist-12345"
149
-
150
- try {
151
- $result = Invoke-RestMethod -Uri "$BaseUrl/sessions/$fakeSessionId" -Method Delete -TimeoutSec 10
152
-
153
- if ($result.success -eq $false) {
154
- if ($result.error -like "*not found*" -or $result.error -like "*introuvable*") {
155
- Write-ErrorExpected "$($result.error)"
156
- $PassedTests++
157
- } else {
158
- Write-ErrorUnexpected "Unexpected error message: $($result.error)"
159
- $FailedTests++
160
- }
161
- } else {
162
- Write-ErrorUnexpected "Should return error for non-existent session"
163
- $FailedTests++
164
- }
165
- } catch {
166
- $errorResponse = $_.ErrorDetails.Message | ConvertFrom-Json
167
- if ($errorResponse.error -like "*not found*" -or $errorResponse.error -like "*introuvable*") {
168
- Write-ErrorExpected "$($errorResponse.error)"
169
- $PassedTests++
170
- } else {
171
- Write-ErrorUnexpected "Unexpected error: $($errorResponse.error)"
172
- $FailedTests++
173
- }
174
- }
175
-
176
- # =============================================================================
177
- # TEST 4: POST /sessions/:id/reset - Non-existent session
178
- # =============================================================================
179
- Write-TestHeader "POST /sessions/:id/reset - Non-existent session" 4 $TotalTests
180
-
181
- try {
182
- $result = Invoke-RestMethod -Uri "$BaseUrl/sessions/$fakeSessionId/reset" -Method Post -TimeoutSec 10
183
-
184
- if ($result.success -eq $false) {
185
- if ($result.error -like "*not found*" -or $result.error -like "*introuvable*") {
186
- Write-ErrorExpected "$($result.error)"
187
- $PassedTests++
188
- } else {
189
- Write-ErrorUnexpected "Unexpected error message: $($result.error)"
190
- $FailedTests++
191
- }
192
- } else {
193
- Write-ErrorUnexpected "Should return error for non-existent session"
194
- $FailedTests++
195
- }
196
- } catch {
197
- $errorResponse = $_.ErrorDetails.Message | ConvertFrom-Json
198
- if ($errorResponse.error -like "*not found*" -or $errorResponse.error -like "*introuvable*") {
199
- Write-ErrorExpected "$($errorResponse.error)"
200
- $PassedTests++
201
- } else {
202
- Write-ErrorUnexpected "Unexpected error: $($errorResponse.error)"
203
- $FailedTests++
204
- }
205
- }
206
-
207
- # =============================================================================
208
- # TEST 5: DELETE /sessions/:id - Empty session ID
209
- # =============================================================================
210
- Write-TestHeader "DELETE /sessions/ - Empty session ID (should 404)" 5 $TotalTests
211
-
212
- try {
213
- # This should hit the /sessions endpoint with GET semantics or 404
214
- $response = Invoke-WebRequest -Uri "$BaseUrl/sessions/" -Method Delete -TimeoutSec 10
215
-
216
- # If we get here with 200, check what happened
217
- Write-Info "Got response with status $($response.StatusCode)"
218
- # Empty ID might be treated differently by Express
219
- $PassedTests++
220
- } catch {
221
- $statusCode = $_.Exception.Response.StatusCode
222
-
223
- if ($statusCode -eq 404 -or $statusCode -eq 'NotFound') {
224
- Write-Success "Empty session ID correctly returns 404"
225
- $PassedTests++
226
- } elseif ($statusCode -eq 405 -or $statusCode -eq 'MethodNotAllowed') {
227
- Write-Success "Empty session ID correctly returns 405 (Method Not Allowed)"
228
- $PassedTests++
229
- } else {
230
- # Any error response is acceptable here
231
- Write-Success "Server handled empty session ID appropriately"
232
- $PassedTests++
233
- }
234
- }
235
-
236
- # =============================================================================
237
- # TEST 6: DELETE /sessions/:id - Special characters in ID
238
- # =============================================================================
239
- Write-TestHeader "DELETE /sessions/:id - Special characters in ID" 6 $TotalTests
240
-
241
- $specialId = "session%20with%20spaces"
242
-
243
- try {
244
- $result = Invoke-RestMethod -Uri "$BaseUrl/sessions/$specialId" -Method Delete -TimeoutSec 10
245
-
246
- if ($result.success -eq $false) {
247
- Write-Success "Server handled special characters in session ID"
248
- Write-Info "Error: $($result.error.Substring(0, [Math]::Min(50, $result.error.Length)))..."
249
- $PassedTests++
250
- } else {
251
- Write-Info "Unexpected success (session might exist?)"
252
- $PassedTests++
253
- }
254
- } catch {
255
- Write-Success "Server handled special characters appropriately"
256
- $PassedTests++
257
- }
258
-
259
- # =============================================================================
260
- # TEST 7: POST /sessions/:id/reset - Special characters in ID
261
- # =============================================================================
262
- Write-TestHeader "POST /sessions/:id/reset - Special characters in ID" 7 $TotalTests
263
-
264
- try {
265
- $result = Invoke-RestMethod -Uri "$BaseUrl/sessions/$specialId/reset" -Method Post -TimeoutSec 10
266
-
267
- if ($result.success -eq $false) {
268
- Write-Success "Server handled special characters in reset request"
269
- $PassedTests++
270
- } else {
271
- Write-Info "Unexpected success"
272
- $PassedTests++
273
- }
274
- } catch {
275
- Write-Success "Server handled special characters appropriately"
276
- $PassedTests++
277
- }
278
-
279
- # =============================================================================
280
- # TEST 8: GET /sessions - Multiple rapid requests
281
- # =============================================================================
282
- Write-TestHeader "GET /sessions - Multiple rapid requests (rate limiting)" 8 $TotalTests
283
-
284
- try {
285
- $successCount = 0
286
- $errorCount = 0
287
-
288
- for ($i = 1; $i -le 5; $i++) {
289
- try {
290
- $result = Invoke-RestMethod -Uri "$BaseUrl/sessions" -TimeoutSec 5
291
- if ($result.success -eq $true) {
292
- $successCount++
293
- } else {
294
- $errorCount++
295
- }
296
- } catch {
297
- $errorCount++
298
- }
299
- }
300
-
301
- if ($successCount -ge 3) {
302
- Write-Success "Server handled rapid requests ($successCount/5 successful)"
303
- $PassedTests++
304
- } else {
305
- Write-ErrorUnexpected "Too many failures in rapid requests ($errorCount/5 failed)"
306
- $FailedTests++
307
- }
308
- } catch {
309
- Write-ErrorUnexpected "Exception during rapid requests: $($_.Exception.Message)"
310
- $FailedTests++
311
- }
312
-
313
- # =============================================================================
314
- # TEST 9: Session info structure (if sessions exist)
315
- # =============================================================================
316
- Write-TestHeader "Session info - Validate session object structure" 9 $TotalTests
317
-
318
- try {
319
- $result = Invoke-RestMethod -Uri "$BaseUrl/sessions" -TimeoutSec 10
320
-
321
- if ($result.success -eq $true) {
322
- $sessions = $result.data.sessions
323
-
324
- if ($sessions.Count -gt 0) {
325
- $session = $sessions[0]
326
-
327
- # Check for expected session fields
328
- $hasId = $null -ne $session.id
329
- $hasCreated = $null -ne $session.created_at -or $null -ne $session.createdAt
330
- $hasActivity = $null -ne $session.last_activity -or $null -ne $session.lastActivity
331
-
332
- if ($hasId) {
333
- Write-Success "Session object has required 'id' field"
334
- Write-Info "Session ID: $($session.id)"
335
- if ($hasCreated) { Write-Info "Has created_at timestamp" }
336
- if ($hasActivity) { Write-Info "Has last_activity timestamp" }
337
- $PassedTests++
338
- } else {
339
- Write-ErrorUnexpected "Session object missing 'id' field"
340
- $FailedTests++
341
- }
342
- } else {
343
- Write-Info "No active sessions to validate structure"
344
- Write-Info "Test passed (no sessions to check)"
345
- $PassedTests++
346
- }
347
- } else {
348
- Write-ErrorUnexpected "Failed to get sessions: $($result.error)"
349
- $FailedTests++
350
- }
351
- } catch {
352
- Write-ErrorUnexpected "Exception: $($_.Exception.Message)"
353
- $FailedTests++
354
- }
355
-
356
- # =============================================================================
357
- # TEST 10: Session count consistency
358
- # =============================================================================
359
- Write-TestHeader "Session count - Verify count matches array length" 10 $TotalTests
360
-
361
- try {
362
- $result = Invoke-RestMethod -Uri "$BaseUrl/sessions" -TimeoutSec 10
363
-
364
- if ($result.success -eq $true) {
365
- $sessions = $result.data.sessions
366
- $reportedCount = $result.data.total_count
367
-
368
- $actualCount = if ($sessions) { $sessions.Count } else { 0 }
369
-
370
- if ($null -eq $reportedCount) {
371
- Write-Info "No total_count field (using array length)"
372
- Write-Success "Sessions array has $actualCount items"
373
- $PassedTests++
374
- } elseif ($reportedCount -eq $actualCount) {
375
- Write-Success "Session count matches: $reportedCount"
376
- $PassedTests++
377
- } else {
378
- Write-ErrorUnexpected "Count mismatch: reported=$reportedCount, actual=$actualCount"
379
- $FailedTests++
380
- }
381
- } else {
382
- Write-ErrorUnexpected "Failed to get sessions: $($result.error)"
383
- $FailedTests++
384
- }
385
- } catch {
386
- Write-ErrorUnexpected "Exception: $($_.Exception.Message)"
387
- $FailedTests++
388
- }
389
-
390
- # =============================================================================
391
- # FINAL SUMMARY
392
- # =============================================================================
393
- Write-Host "`n" -NoNewline
394
- Write-Host "╔════════════════════════════════════════════════════════╗" -ForegroundColor Magenta
395
- Write-Host "║ ║" -ForegroundColor Magenta
396
- Write-Host "║ SESSION MANAGEMENT TEST SUMMARY ║" -ForegroundColor Cyan
397
- Write-Host "║ ║" -ForegroundColor Magenta
398
- Write-Host "╚════════════════════════════════════════════════════════╝" -ForegroundColor Magenta
399
- Write-Host ""
400
-
401
- $TotalExecuted = $PassedTests + $FailedTests
402
- $SuccessRate = if ($TotalExecuted -gt 0) { [math]::Round(($PassedTests / $TotalExecuted) * 100, 1) } else { 0 }
403
-
404
- Write-Host "Total tests: $TotalTests" -ForegroundColor White
405
- Write-Host "Tests passed: " -NoNewline -ForegroundColor White
406
- Write-Host "$PassedTests" -ForegroundColor Green
407
- Write-Host "Tests failed: " -NoNewline -ForegroundColor White
408
- Write-Host "$FailedTests" -ForegroundColor $(if($FailedTests -gt 0){"Red"}else{"Green"})
409
- Write-Host "Success rate: " -NoNewline -ForegroundColor White
410
- Write-Host "$SuccessRate%" -ForegroundColor $(if($SuccessRate -eq 100){"Green"}elseif($SuccessRate -ge 80){"Yellow"}else{"Red"})
411
-
412
- Write-Host ""
413
-
414
- if ($FailedTests -eq 0) {
415
- Write-Host "════════════════════════════════════════════════════════" -ForegroundColor Green
416
- Write-Host " ✓ ALL SESSION MANAGEMENT TESTS PASSED!" -ForegroundColor Green
417
- Write-Host "════════════════════════════════════════════════════════" -ForegroundColor Green
418
- exit 0
419
- } else {
420
- Write-Host "════════════════════════════════════════════════════════" -ForegroundColor Yellow
421
- Write-Host " ⚠ SOME SESSION TESTS FAILED" -ForegroundColor Yellow
422
- Write-Host "════════════════════════════════════════════════════════" -ForegroundColor Yellow
423
- Write-Host ""
424
- Write-Host "See details above to identify the issues." -ForegroundColor Yellow
425
- exit 1
426
- }
1
+ #!/usr/bin/env pwsh
2
+ #Requires -Version 5.1
3
+
4
+ <#
5
+ .SYNOPSIS
6
+ Session management testing script for NotebookLM MCP HTTP Server API
7
+
8
+ .DESCRIPTION
9
+ Tests session management endpoints and behavior:
10
+ - GET /sessions (list sessions)
11
+ - DELETE /sessions/:id (close session)
12
+ - POST /sessions/:id/reset (reset session)
13
+ - Session error handling
14
+
15
+ .PARAMETER BaseUrl
16
+ Base URL of the server (default: http://localhost:3000)
17
+
18
+ .EXAMPLE
19
+ .\test-sessions.ps1
20
+ Runs all session management tests
21
+
22
+ .NOTES
23
+ Prerequisite: The server must be started
24
+ #>
25
+
26
+ param(
27
+ [string]$BaseUrl = "http://localhost:3000"
28
+ )
29
+
30
+ # Colors for logs
31
+ function Write-TestHeader {
32
+ param([string]$Message, [int]$Number, [int]$Total)
33
+ Write-Host "`n" -NoNewline
34
+ Write-Host "═══════════════════════════════════════════════════════" -ForegroundColor Magenta
35
+ Write-Host " [$Number/$Total] $Message" -ForegroundColor Cyan
36
+ Write-Host "═══════════════════════════════════════════════════════" -ForegroundColor Magenta
37
+ }
38
+
39
+ function Write-Success {
40
+ param([string]$Message)
41
+ Write-Host "✓ $Message" -ForegroundColor Green
42
+ }
43
+
44
+ function Write-Info {
45
+ param([string]$Message)
46
+ Write-Host "ℹ $Message" -ForegroundColor Yellow
47
+ }
48
+
49
+ function Write-ErrorExpected {
50
+ param([string]$Message)
51
+ Write-Host "✓ Expected error: $Message" -ForegroundColor Green
52
+ }
53
+
54
+ function Write-ErrorUnexpected {
55
+ param([string]$Message)
56
+ Write-Host "✗ $Message" -ForegroundColor Red
57
+ }
58
+
59
+ # Banner
60
+ Clear-Host
61
+ Write-Host "`n" -NoNewline
62
+ Write-Host "╔════════════════════════════════════════════════════════╗" -ForegroundColor Magenta
63
+ Write-Host "║ ║" -ForegroundColor Magenta
64
+ Write-Host "║ SESSION MANAGEMENT TESTS - HTTP API ║" -ForegroundColor Cyan
65
+ Write-Host "║ ║" -ForegroundColor Magenta
66
+ Write-Host "╚════════════════════════════════════════════════════════╝" -ForegroundColor Magenta
67
+ Write-Host ""
68
+
69
+ # Check that the server is accessible
70
+ Write-Host "Checking connection to server..." -ForegroundColor Yellow
71
+ try {
72
+ $null = Invoke-RestMethod -Uri "$BaseUrl/health" -TimeoutSec 5
73
+ Write-Success "Server accessible at $BaseUrl"
74
+ } catch {
75
+ Write-ErrorUnexpected "Unable to connect to server at $BaseUrl"
76
+ Write-Host "Make sure the server is started" -ForegroundColor Yellow
77
+ exit 1
78
+ }
79
+
80
+ $TotalTests = 10
81
+ $PassedTests = 0
82
+ $FailedTests = 0
83
+
84
+ # =============================================================================
85
+ # TEST 1: GET /sessions - List sessions (should return array)
86
+ # =============================================================================
87
+ Write-TestHeader "GET /sessions - List active sessions" 1 $TotalTests
88
+
89
+ try {
90
+ $result = Invoke-RestMethod -Uri "$BaseUrl/sessions" -TimeoutSec 10
91
+
92
+ if ($result.success -eq $true -and $null -ne $result.data) {
93
+ $sessions = $result.data.sessions
94
+ if ($null -ne $sessions -and $sessions -is [Array]) {
95
+ Write-Success "Sessions list returned successfully"
96
+ Write-Info "Active sessions: $($sessions.Count)"
97
+ $PassedTests++
98
+ } else {
99
+ Write-ErrorUnexpected "Sessions data not in expected format"
100
+ $FailedTests++
101
+ }
102
+ } else {
103
+ Write-ErrorUnexpected "Failed to list sessions: $($result.error)"
104
+ $FailedTests++
105
+ }
106
+ } catch {
107
+ Write-ErrorUnexpected "Exception: $($_.Exception.Message)"
108
+ $FailedTests++
109
+ }
110
+
111
+ # =============================================================================
112
+ # TEST 2: GET /sessions - Response contains required fields
113
+ # =============================================================================
114
+ Write-TestHeader "GET /sessions - Response structure validation" 2 $TotalTests
115
+
116
+ try {
117
+ $result = Invoke-RestMethod -Uri "$BaseUrl/sessions" -TimeoutSec 10
118
+
119
+ if ($result.success -eq $true) {
120
+ $data = $result.data
121
+
122
+ # Check for session count info
123
+ $hasCount = $null -ne $data.total_count -or $null -ne $data.sessions
124
+
125
+ if ($hasCount) {
126
+ Write-Success "Response contains session information"
127
+ if ($data.total_count) { Write-Info "Total count: $($data.total_count)" }
128
+ if ($data.max_sessions) { Write-Info "Max sessions: $($data.max_sessions)" }
129
+ $PassedTests++
130
+ } else {
131
+ Write-ErrorUnexpected "Missing session count information"
132
+ $FailedTests++
133
+ }
134
+ } else {
135
+ Write-ErrorUnexpected "Request failed: $($result.error)"
136
+ $FailedTests++
137
+ }
138
+ } catch {
139
+ Write-ErrorUnexpected "Exception: $($_.Exception.Message)"
140
+ $FailedTests++
141
+ }
142
+
143
+ # =============================================================================
144
+ # TEST 3: DELETE /sessions/:id - Non-existent session
145
+ # =============================================================================
146
+ Write-TestHeader "DELETE /sessions/:id - Non-existent session" 3 $TotalTests
147
+
148
+ $fakeSessionId = "session-does-not-exist-12345"
149
+
150
+ try {
151
+ $result = Invoke-RestMethod -Uri "$BaseUrl/sessions/$fakeSessionId" -Method Delete -TimeoutSec 10
152
+
153
+ if ($result.success -eq $false) {
154
+ if ($result.error -like "*not found*" -or $result.error -like "*introuvable*") {
155
+ Write-ErrorExpected "$($result.error)"
156
+ $PassedTests++
157
+ } else {
158
+ Write-ErrorUnexpected "Unexpected error message: $($result.error)"
159
+ $FailedTests++
160
+ }
161
+ } else {
162
+ Write-ErrorUnexpected "Should return error for non-existent session"
163
+ $FailedTests++
164
+ }
165
+ } catch {
166
+ $errorResponse = $_.ErrorDetails.Message | ConvertFrom-Json
167
+ if ($errorResponse.error -like "*not found*" -or $errorResponse.error -like "*introuvable*") {
168
+ Write-ErrorExpected "$($errorResponse.error)"
169
+ $PassedTests++
170
+ } else {
171
+ Write-ErrorUnexpected "Unexpected error: $($errorResponse.error)"
172
+ $FailedTests++
173
+ }
174
+ }
175
+
176
+ # =============================================================================
177
+ # TEST 4: POST /sessions/:id/reset - Non-existent session
178
+ # =============================================================================
179
+ Write-TestHeader "POST /sessions/:id/reset - Non-existent session" 4 $TotalTests
180
+
181
+ try {
182
+ $result = Invoke-RestMethod -Uri "$BaseUrl/sessions/$fakeSessionId/reset" -Method Post -TimeoutSec 10
183
+
184
+ if ($result.success -eq $false) {
185
+ if ($result.error -like "*not found*" -or $result.error -like "*introuvable*") {
186
+ Write-ErrorExpected "$($result.error)"
187
+ $PassedTests++
188
+ } else {
189
+ Write-ErrorUnexpected "Unexpected error message: $($result.error)"
190
+ $FailedTests++
191
+ }
192
+ } else {
193
+ Write-ErrorUnexpected "Should return error for non-existent session"
194
+ $FailedTests++
195
+ }
196
+ } catch {
197
+ $errorResponse = $_.ErrorDetails.Message | ConvertFrom-Json
198
+ if ($errorResponse.error -like "*not found*" -or $errorResponse.error -like "*introuvable*") {
199
+ Write-ErrorExpected "$($errorResponse.error)"
200
+ $PassedTests++
201
+ } else {
202
+ Write-ErrorUnexpected "Unexpected error: $($errorResponse.error)"
203
+ $FailedTests++
204
+ }
205
+ }
206
+
207
+ # =============================================================================
208
+ # TEST 5: DELETE /sessions/:id - Empty session ID
209
+ # =============================================================================
210
+ Write-TestHeader "DELETE /sessions/ - Empty session ID (should 404)" 5 $TotalTests
211
+
212
+ try {
213
+ # This should hit the /sessions endpoint with GET semantics or 404
214
+ $response = Invoke-WebRequest -Uri "$BaseUrl/sessions/" -Method Delete -TimeoutSec 10
215
+
216
+ # If we get here with 200, check what happened
217
+ Write-Info "Got response with status $($response.StatusCode)"
218
+ # Empty ID might be treated differently by Express
219
+ $PassedTests++
220
+ } catch {
221
+ $statusCode = $_.Exception.Response.StatusCode
222
+
223
+ if ($statusCode -eq 404 -or $statusCode -eq 'NotFound') {
224
+ Write-Success "Empty session ID correctly returns 404"
225
+ $PassedTests++
226
+ } elseif ($statusCode -eq 405 -or $statusCode -eq 'MethodNotAllowed') {
227
+ Write-Success "Empty session ID correctly returns 405 (Method Not Allowed)"
228
+ $PassedTests++
229
+ } else {
230
+ # Any error response is acceptable here
231
+ Write-Success "Server handled empty session ID appropriately"
232
+ $PassedTests++
233
+ }
234
+ }
235
+
236
+ # =============================================================================
237
+ # TEST 6: DELETE /sessions/:id - Special characters in ID
238
+ # =============================================================================
239
+ Write-TestHeader "DELETE /sessions/:id - Special characters in ID" 6 $TotalTests
240
+
241
+ $specialId = "session%20with%20spaces"
242
+
243
+ try {
244
+ $result = Invoke-RestMethod -Uri "$BaseUrl/sessions/$specialId" -Method Delete -TimeoutSec 10
245
+
246
+ if ($result.success -eq $false) {
247
+ Write-Success "Server handled special characters in session ID"
248
+ Write-Info "Error: $($result.error.Substring(0, [Math]::Min(50, $result.error.Length)))..."
249
+ $PassedTests++
250
+ } else {
251
+ Write-Info "Unexpected success (session might exist?)"
252
+ $PassedTests++
253
+ }
254
+ } catch {
255
+ Write-Success "Server handled special characters appropriately"
256
+ $PassedTests++
257
+ }
258
+
259
+ # =============================================================================
260
+ # TEST 7: POST /sessions/:id/reset - Special characters in ID
261
+ # =============================================================================
262
+ Write-TestHeader "POST /sessions/:id/reset - Special characters in ID" 7 $TotalTests
263
+
264
+ try {
265
+ $result = Invoke-RestMethod -Uri "$BaseUrl/sessions/$specialId/reset" -Method Post -TimeoutSec 10
266
+
267
+ if ($result.success -eq $false) {
268
+ Write-Success "Server handled special characters in reset request"
269
+ $PassedTests++
270
+ } else {
271
+ Write-Info "Unexpected success"
272
+ $PassedTests++
273
+ }
274
+ } catch {
275
+ Write-Success "Server handled special characters appropriately"
276
+ $PassedTests++
277
+ }
278
+
279
+ # =============================================================================
280
+ # TEST 8: GET /sessions - Multiple rapid requests
281
+ # =============================================================================
282
+ Write-TestHeader "GET /sessions - Multiple rapid requests (rate limiting)" 8 $TotalTests
283
+
284
+ try {
285
+ $successCount = 0
286
+ $errorCount = 0
287
+
288
+ for ($i = 1; $i -le 5; $i++) {
289
+ try {
290
+ $result = Invoke-RestMethod -Uri "$BaseUrl/sessions" -TimeoutSec 5
291
+ if ($result.success -eq $true) {
292
+ $successCount++
293
+ } else {
294
+ $errorCount++
295
+ }
296
+ } catch {
297
+ $errorCount++
298
+ }
299
+ }
300
+
301
+ if ($successCount -ge 3) {
302
+ Write-Success "Server handled rapid requests ($successCount/5 successful)"
303
+ $PassedTests++
304
+ } else {
305
+ Write-ErrorUnexpected "Too many failures in rapid requests ($errorCount/5 failed)"
306
+ $FailedTests++
307
+ }
308
+ } catch {
309
+ Write-ErrorUnexpected "Exception during rapid requests: $($_.Exception.Message)"
310
+ $FailedTests++
311
+ }
312
+
313
+ # =============================================================================
314
+ # TEST 9: Session info structure (if sessions exist)
315
+ # =============================================================================
316
+ Write-TestHeader "Session info - Validate session object structure" 9 $TotalTests
317
+
318
+ try {
319
+ $result = Invoke-RestMethod -Uri "$BaseUrl/sessions" -TimeoutSec 10
320
+
321
+ if ($result.success -eq $true) {
322
+ $sessions = $result.data.sessions
323
+
324
+ if ($sessions.Count -gt 0) {
325
+ $session = $sessions[0]
326
+
327
+ # Check for expected session fields
328
+ $hasId = $null -ne $session.id
329
+ $hasCreated = $null -ne $session.created_at -or $null -ne $session.createdAt
330
+ $hasActivity = $null -ne $session.last_activity -or $null -ne $session.lastActivity
331
+
332
+ if ($hasId) {
333
+ Write-Success "Session object has required 'id' field"
334
+ Write-Info "Session ID: $($session.id)"
335
+ if ($hasCreated) { Write-Info "Has created_at timestamp" }
336
+ if ($hasActivity) { Write-Info "Has last_activity timestamp" }
337
+ $PassedTests++
338
+ } else {
339
+ Write-ErrorUnexpected "Session object missing 'id' field"
340
+ $FailedTests++
341
+ }
342
+ } else {
343
+ Write-Info "No active sessions to validate structure"
344
+ Write-Info "Test passed (no sessions to check)"
345
+ $PassedTests++
346
+ }
347
+ } else {
348
+ Write-ErrorUnexpected "Failed to get sessions: $($result.error)"
349
+ $FailedTests++
350
+ }
351
+ } catch {
352
+ Write-ErrorUnexpected "Exception: $($_.Exception.Message)"
353
+ $FailedTests++
354
+ }
355
+
356
+ # =============================================================================
357
+ # TEST 10: Session count consistency
358
+ # =============================================================================
359
+ Write-TestHeader "Session count - Verify count matches array length" 10 $TotalTests
360
+
361
+ try {
362
+ $result = Invoke-RestMethod -Uri "$BaseUrl/sessions" -TimeoutSec 10
363
+
364
+ if ($result.success -eq $true) {
365
+ $sessions = $result.data.sessions
366
+ $reportedCount = $result.data.total_count
367
+
368
+ $actualCount = if ($sessions) { $sessions.Count } else { 0 }
369
+
370
+ if ($null -eq $reportedCount) {
371
+ Write-Info "No total_count field (using array length)"
372
+ Write-Success "Sessions array has $actualCount items"
373
+ $PassedTests++
374
+ } elseif ($reportedCount -eq $actualCount) {
375
+ Write-Success "Session count matches: $reportedCount"
376
+ $PassedTests++
377
+ } else {
378
+ Write-ErrorUnexpected "Count mismatch: reported=$reportedCount, actual=$actualCount"
379
+ $FailedTests++
380
+ }
381
+ } else {
382
+ Write-ErrorUnexpected "Failed to get sessions: $($result.error)"
383
+ $FailedTests++
384
+ }
385
+ } catch {
386
+ Write-ErrorUnexpected "Exception: $($_.Exception.Message)"
387
+ $FailedTests++
388
+ }
389
+
390
+ # =============================================================================
391
+ # FINAL SUMMARY
392
+ # =============================================================================
393
+ Write-Host "`n" -NoNewline
394
+ Write-Host "╔════════════════════════════════════════════════════════╗" -ForegroundColor Magenta
395
+ Write-Host "║ ║" -ForegroundColor Magenta
396
+ Write-Host "║ SESSION MANAGEMENT TEST SUMMARY ║" -ForegroundColor Cyan
397
+ Write-Host "║ ║" -ForegroundColor Magenta
398
+ Write-Host "╚════════════════════════════════════════════════════════╝" -ForegroundColor Magenta
399
+ Write-Host ""
400
+
401
+ $TotalExecuted = $PassedTests + $FailedTests
402
+ $SuccessRate = if ($TotalExecuted -gt 0) { [math]::Round(($PassedTests / $TotalExecuted) * 100, 1) } else { 0 }
403
+
404
+ Write-Host "Total tests: $TotalTests" -ForegroundColor White
405
+ Write-Host "Tests passed: " -NoNewline -ForegroundColor White
406
+ Write-Host "$PassedTests" -ForegroundColor Green
407
+ Write-Host "Tests failed: " -NoNewline -ForegroundColor White
408
+ Write-Host "$FailedTests" -ForegroundColor $(if($FailedTests -gt 0){"Red"}else{"Green"})
409
+ Write-Host "Success rate: " -NoNewline -ForegroundColor White
410
+ Write-Host "$SuccessRate%" -ForegroundColor $(if($SuccessRate -eq 100){"Green"}elseif($SuccessRate -ge 80){"Yellow"}else{"Red"})
411
+
412
+ Write-Host ""
413
+
414
+ if ($FailedTests -eq 0) {
415
+ Write-Host "════════════════════════════════════════════════════════" -ForegroundColor Green
416
+ Write-Host " ✓ ALL SESSION MANAGEMENT TESTS PASSED!" -ForegroundColor Green
417
+ Write-Host "════════════════════════════════════════════════════════" -ForegroundColor Green
418
+ exit 0
419
+ } else {
420
+ Write-Host "════════════════════════════════════════════════════════" -ForegroundColor Yellow
421
+ Write-Host " ⚠ SOME SESSION TESTS FAILED" -ForegroundColor Yellow
422
+ Write-Host "════════════════════════════════════════════════════════" -ForegroundColor Yellow
423
+ Write-Host ""
424
+ Write-Host "See details above to identify the issues." -ForegroundColor Yellow
425
+ exit 1
426
+ }