@vltpkg/vsr 0.0.0-26 → 0.0.0-27

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 (107) hide show
  1. package/LICENSE +10 -114
  2. package/dist/README.md +1 -0
  3. package/dist/assets/public/favicon.ico +0 -0
  4. package/dist/assets/public/fonts/courier-bold-italic.ttf +0 -0
  5. package/dist/assets/public/fonts/courier-bold.ttf +0 -0
  6. package/dist/assets/public/fonts/courier-italic.ttf +0 -0
  7. package/dist/assets/public/fonts/courier-regular.ttf +0 -0
  8. package/dist/assets/public/fonts/geist-mono.ttf +0 -0
  9. package/dist/assets/public/fonts/inter.ttf +0 -0
  10. package/dist/assets/public/index.html +70 -0
  11. package/dist/assets/public/index.js +1300 -0
  12. package/dist/assets/public/index.js.map +7 -0
  13. package/dist/assets/public/main.css +1 -0
  14. package/dist/bin/vsr.js +771 -0
  15. package/dist/index.js +28283 -0
  16. package/dist/index.js.map +8 -0
  17. package/package.json +6 -49
  18. package/DEPLOY.md +0 -163
  19. package/config.ts +0 -221
  20. package/drizzle.config.js +0 -40
  21. package/info/COMPARISONS.md +0 -37
  22. package/info/CONFIGURATION.md +0 -143
  23. package/info/CONTRIBUTING.md +0 -32
  24. package/info/DATABASE_SETUP.md +0 -108
  25. package/info/GRANULAR_ACCESS_TOKENS.md +0 -160
  26. package/info/PROJECT_STRUCTURE.md +0 -291
  27. package/info/ROADMAP.md +0 -27
  28. package/info/SUPPORT.md +0 -39
  29. package/info/TESTING.md +0 -301
  30. package/info/USER_SUPPORT.md +0 -31
  31. package/scripts/build-assets.js +0 -31
  32. package/scripts/build-bin.js +0 -62
  33. package/scripts/prepack.js +0 -27
  34. package/src/bin/vsr.ts +0 -484
  35. package/src/db/client.ts +0 -590
  36. package/src/db/migrations/0000_faulty_ricochet.sql +0 -14
  37. package/src/db/migrations/0000_initial.sql +0 -29
  38. package/src/db/migrations/0001_uuid_validation.sql +0 -35
  39. package/src/db/migrations/0001_wealthy_magdalene.sql +0 -7
  40. package/src/db/migrations/drop.sql +0 -3
  41. package/src/db/migrations/meta/0000_snapshot.json +0 -104
  42. package/src/db/migrations/meta/0001_snapshot.json +0 -155
  43. package/src/db/migrations/meta/_journal.json +0 -20
  44. package/src/db/schema.ts +0 -43
  45. package/src/index.ts +0 -434
  46. package/src/middleware/config.ts +0 -79
  47. package/src/middleware/telemetry.ts +0 -43
  48. package/src/queue/index.ts +0 -97
  49. package/src/routes/access.ts +0 -852
  50. package/src/routes/docs.ts +0 -63
  51. package/src/routes/misc.ts +0 -469
  52. package/src/routes/packages.ts +0 -2823
  53. package/src/routes/ping.ts +0 -39
  54. package/src/routes/search.ts +0 -131
  55. package/src/routes/static.ts +0 -74
  56. package/src/routes/tokens.ts +0 -259
  57. package/src/routes/users.ts +0 -68
  58. package/src/utils/auth.ts +0 -202
  59. package/src/utils/cache.ts +0 -587
  60. package/src/utils/config.ts +0 -50
  61. package/src/utils/database.ts +0 -69
  62. package/src/utils/docs.ts +0 -146
  63. package/src/utils/packages.ts +0 -453
  64. package/src/utils/response.ts +0 -125
  65. package/src/utils/routes.ts +0 -64
  66. package/src/utils/spa.ts +0 -52
  67. package/src/utils/tracing.ts +0 -52
  68. package/src/utils/upstream.ts +0 -172
  69. package/test/access.test.ts +0 -705
  70. package/test/audit.test.ts +0 -828
  71. package/test/dashboard.test.ts +0 -693
  72. package/test/dist-tags.test.ts +0 -678
  73. package/test/manifest.test.ts +0 -436
  74. package/test/packument.test.ts +0 -530
  75. package/test/ping.test.ts +0 -41
  76. package/test/search.test.ts +0 -472
  77. package/test/setup.ts +0 -130
  78. package/test/static.test.ts +0 -646
  79. package/test/tokens.test.ts +0 -389
  80. package/test/utils/auth.test.ts +0 -214
  81. package/test/utils/packages.test.ts +0 -235
  82. package/test/utils/response.test.ts +0 -184
  83. package/test/whoami.test.ts +0 -119
  84. package/tsconfig.json +0 -16
  85. package/tsconfig.worker.json +0 -3
  86. package/typedoc.mjs +0 -2
  87. package/types.ts +0 -598
  88. package/vitest.config.ts +0 -25
  89. package/vlt.json.example +0 -56
  90. package/wrangler.json +0 -65
  91. /package/{src → dist}/assets/public/images/bg.png +0 -0
  92. /package/{src → dist}/assets/public/images/clients/logo-bun.png +0 -0
  93. /package/{src → dist}/assets/public/images/clients/logo-deno.png +0 -0
  94. /package/{src → dist}/assets/public/images/clients/logo-npm.png +0 -0
  95. /package/{src → dist}/assets/public/images/clients/logo-pnpm.png +0 -0
  96. /package/{src → dist}/assets/public/images/clients/logo-vlt.png +0 -0
  97. /package/{src → dist}/assets/public/images/clients/logo-yarn.png +0 -0
  98. /package/{src → dist}/assets/public/images/favicon/apple-touch-icon.png +0 -0
  99. /package/{src → dist}/assets/public/images/favicon/favicon-96x96.png +0 -0
  100. /package/{src → dist}/assets/public/images/favicon/favicon.ico +0 -0
  101. /package/{src → dist}/assets/public/images/favicon/favicon.svg +0 -0
  102. /package/{src → dist}/assets/public/images/favicon/site.webmanifest +0 -0
  103. /package/{src → dist}/assets/public/images/favicon/web-app-manifest-192x192.png +0 -0
  104. /package/{src → dist}/assets/public/images/favicon/web-app-manifest-512x512.png +0 -0
  105. /package/{src → dist}/assets/public/styles/styles.css +0 -0
  106. /package/{src → dist}/bin/demo/package.json +0 -0
  107. /package/{src → dist}/bin/demo/vlt.json +0 -0
@@ -1,693 +0,0 @@
1
- import { describe, it, expect } from 'vitest'
2
- import { env } from 'cloudflare:test'
3
- import { app } from '../src/index.ts'
4
-
5
- describe('Dashboard Endpoints', () => {
6
- describe('Dashboard Data Endpoint', () => {
7
- describe('GET /dashboard.json', () => {
8
- it('should return dashboard data when daemon is enabled', async () => {
9
- const res = await app.request('/dashboard.json', {}, env)
10
- expect([200, 404, 500].includes(res.status)).toBe(true)
11
-
12
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
13
- if (res.status === 500) return
14
- // Dashboard endpoints may return 500 with text/plain when external services are unavailable
15
- if (res.status === 200) {
16
- expect(res.headers.get('content-type')).toContain(
17
- 'application/json',
18
- )
19
- } else if (res.status === 500) {
20
- expect(res.headers.get('content-type')).toContain(
21
- 'text/plain',
22
- )
23
- }
24
- })
25
-
26
- it('should return dashboard data in standalone mode when daemon is disabled', async () => {
27
- const res = await app.request('/dashboard.json', {}, env)
28
- expect([200, 404, 500].includes(res.status)).toBe(true)
29
- // Dashboard endpoints now provide standalone data when daemon is disabled
30
- if (res.status === 200) {
31
- expect(res.headers.get('content-type')).toContain(
32
- 'application/json',
33
- )
34
- const data = await res.json()
35
- expect(data.registry).toBeDefined()
36
- expect(data.features).toBeDefined()
37
- } else if (res.status === 500) {
38
- expect(res.headers.get('content-type')).toContain(
39
- 'text/plain',
40
- )
41
- }
42
- })
43
-
44
- it('should return proper dashboard configuration structure', async () => {
45
- const res = await app.request('/dashboard.json', {}, env)
46
- expect([200, 404, 500].includes(res.status)).toBe(true)
47
-
48
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
49
- if (res.status === 500) return
50
- if (res.status === 200) {
51
- const data = (await res.json()) as any
52
- expect(data).toBeDefined()
53
- expect(data.registry).toBeDefined()
54
- expect(data.features).toBeDefined()
55
- }
56
- })
57
-
58
- it('should include registry information in response', async () => {
59
- const res = await app.request('/dashboard.json', {}, env)
60
- expect([200, 404, 500].includes(res.status)).toBe(true)
61
-
62
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
63
- if (res.status === 500) return
64
- const data = (await res.json()) as any
65
- expect(data.registry).toBeDefined()
66
- expect(data.registry.url).toBeDefined()
67
- expect(data.registry.name).toBeDefined()
68
- })
69
-
70
- it('should include feature flags in response', async () => {
71
- const res = await app.request('/dashboard.json', {}, env)
72
- expect([200, 404, 500].includes(res.status)).toBe(true)
73
-
74
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
75
- if (res.status === 500) return
76
- const data = (await res.json()) as any
77
- expect(data.features).toBeDefined()
78
- expect(typeof data.features.search).toBe('boolean')
79
- expect(typeof data.features.publish).toBe('boolean')
80
- expect(typeof data.features.access).toBe('boolean')
81
- })
82
-
83
- it('should handle HEAD requests', async () => {
84
- const res = await app.request(
85
- '/dashboard.json',
86
- { method: 'HEAD' },
87
- env,
88
- )
89
- expect(
90
- [200, 401, 404, 405, 500, 501].includes(res.status),
91
- ).toBe(true)
92
- })
93
- })
94
-
95
- describe('Dashboard Data Validation', () => {
96
- it('should return valid JSON structure', async () => {
97
- const res = await app.request('/dashboard.json', {}, env)
98
- expect([200, 404, 500].includes(res.status)).toBe(true)
99
-
100
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
101
- if (res.status === 500) return
102
-
103
- const data = (await res.json()) as any
104
- expect(data).toBeDefined()
105
- expect(typeof data).toBe('object')
106
- expect(data).not.toBeNull()
107
- })
108
-
109
- it('should include all required registry fields', async () => {
110
- const res = await app.request('/dashboard.json', {}, env)
111
- expect([200, 404, 500].includes(res.status)).toBe(true)
112
-
113
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
114
- if (res.status === 500) return
115
-
116
- const data = (await res.json()) as any
117
- expect(data.registry).toBeDefined()
118
- expect(typeof data.registry.url).toBe('string')
119
- expect(typeof data.registry.name).toBe('string')
120
- expect(data.registry.url.length).toBeGreaterThan(0)
121
- expect(data.registry.name.length).toBeGreaterThan(0)
122
- })
123
-
124
- it('should include all required feature fields', async () => {
125
- const res = await app.request('/dashboard.json', {}, env)
126
- expect([200, 404, 500].includes(res.status)).toBe(true)
127
-
128
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
129
- if (res.status === 500) return
130
-
131
- const data = (await res.json()) as any
132
- expect(data.features).toBeDefined()
133
- expect('search' in data.features).toBe(true)
134
- expect('publish' in data.features).toBe(true)
135
- expect('access' in data.features).toBe(true)
136
- })
137
- })
138
- })
139
-
140
- describe('App Data Endpoint', () => {
141
- describe('GET /app-data.json', () => {
142
- it('should return app data when daemon is enabled', async () => {
143
- const res = await app.request('/app-data.json', {}, env)
144
- expect([200, 404, 500].includes(res.status)).toBe(true)
145
-
146
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
147
- if (res.status === 500) return
148
- // Dashboard endpoints may return 500 with text/plain when external services are unavailable
149
- if (res.status === 200) {
150
- expect(res.headers.get('content-type')).toContain(
151
- 'application/json',
152
- )
153
- } else if (res.status === 500) {
154
- expect(res.headers.get('content-type')).toContain(
155
- 'text/plain',
156
- )
157
- }
158
- })
159
-
160
- it('should return app data in standalone mode when daemon is disabled', async () => {
161
- const res = await app.request('/app-data.json', {}, env)
162
- expect([200, 404, 500].includes(res.status)).toBe(true)
163
- // Dashboard endpoints now provide standalone data when daemon is disabled
164
- if (res.status === 200) {
165
- expect(res.headers.get('content-type')).toContain(
166
- 'application/json',
167
- )
168
- const data = await res.json()
169
- expect(data.packages).toBeDefined()
170
- expect(data.stats).toBeDefined()
171
- } else if (res.status === 500) {
172
- expect(res.headers.get('content-type')).toContain(
173
- 'text/plain',
174
- )
175
- }
176
- })
177
-
178
- it('should return proper app data structure', async () => {
179
- const res = await app.request('/app-data.json', {}, env)
180
- expect([200, 404, 500].includes(res.status)).toBe(true)
181
-
182
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
183
- if (res.status === 500) return
184
- const data = (await res.json()) as any
185
- expect(data).toBeDefined()
186
- expect(data.packages).toBeDefined()
187
- expect(data.stats).toBeDefined()
188
- })
189
-
190
- it('should include packages array in response', async () => {
191
- const res = await app.request('/app-data.json', {}, env)
192
- expect([200, 404, 500].includes(res.status)).toBe(true)
193
-
194
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
195
- if (res.status === 500) return
196
- const data = (await res.json()) as any
197
- expect(Array.isArray(data.packages)).toBe(true)
198
- })
199
-
200
- it('should include statistics in response', async () => {
201
- const res = await app.request('/app-data.json', {}, env)
202
- expect([200, 404, 500].includes(res.status)).toBe(true)
203
-
204
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
205
- if (res.status === 500) return
206
- const data = (await res.json()) as any
207
- expect(data.stats).toBeDefined()
208
- expect(typeof data.stats.totalPackages).toBe('number')
209
- expect(typeof data.stats.totalDownloads).toBe('number')
210
- })
211
-
212
- it('should handle HEAD requests', async () => {
213
- const res = await app.request(
214
- '/app-data.json',
215
- { method: 'HEAD' },
216
- env,
217
- )
218
- expect(
219
- [200, 401, 404, 405, 500, 501].includes(res.status),
220
- ).toBe(true)
221
- })
222
- })
223
-
224
- describe('App Data Package Information', () => {
225
- it('should return packages with proper structure', async () => {
226
- const res = await app.request('/app-data.json', {}, env)
227
- expect([200, 404, 500].includes(res.status)).toBe(true)
228
-
229
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
230
- if (res.status === 500) return
231
-
232
- const data = (await res.json()) as any
233
- expect(Array.isArray(data.packages)).toBe(true)
234
-
235
- // If packages exist, validate their structure
236
- if (data.packages.length > 0) {
237
- const pkg = data.packages[0]
238
- expect(typeof pkg.name).toBe('string')
239
- expect(typeof pkg.version).toBe('string')
240
- // description is optional
241
- if (pkg.description !== undefined) {
242
- expect(typeof pkg.description).toBe('string')
243
- }
244
- }
245
- })
246
-
247
- it('should handle empty packages array', async () => {
248
- const res = await app.request('/app-data.json', {}, env)
249
- expect([200, 404, 500].includes(res.status)).toBe(true)
250
-
251
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
252
- if (res.status === 500) return
253
-
254
- const data = (await res.json()) as any
255
- expect(Array.isArray(data.packages)).toBe(true)
256
- // Empty array is valid
257
- expect(data.packages.length).toBeGreaterThanOrEqual(0)
258
- })
259
-
260
- it('should include valid package names', async () => {
261
- const res = await app.request('/app-data.json', {}, env)
262
- expect([200, 404, 500].includes(res.status)).toBe(true)
263
-
264
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
265
- if (res.status === 500) return
266
-
267
- const data = (await res.json()) as any
268
- data.packages.forEach((pkg: any) => {
269
- expect(typeof pkg.name).toBe('string')
270
- expect(pkg.name.length).toBeGreaterThan(0)
271
- // Package names should follow npm naming conventions
272
- expect(pkg.name).toMatch(
273
- /^[a-z0-9]([a-z0-9._-]*[a-z0-9])?$|^@[a-z0-9-]+\/[a-z0-9]([a-z0-9._-]*[a-z0-9])?$/,
274
- )
275
- })
276
- })
277
-
278
- it('should include valid semver versions', async () => {
279
- const res = await app.request('/app-data.json', {}, env)
280
- expect([200, 404, 500].includes(res.status)).toBe(true)
281
-
282
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
283
- if (res.status === 500) return
284
-
285
- const data = (await res.json()) as any
286
- data.packages.forEach((pkg: any) => {
287
- expect(typeof pkg.version).toBe('string')
288
- expect(pkg.version.length).toBeGreaterThan(0)
289
- // Basic semver validation
290
- expect(pkg.version).toMatch(/^\d+\.\d+\.\d+/)
291
- })
292
- })
293
- })
294
-
295
- describe('App Data Statistics', () => {
296
- it('should return non-negative statistics', async () => {
297
- const res = await app.request('/app-data.json', {}, env)
298
- expect([200, 404, 500].includes(res.status)).toBe(true)
299
-
300
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
301
- if (res.status === 500) return
302
-
303
- const data = (await res.json()) as any
304
- expect(data.stats.totalPackages).toBeGreaterThanOrEqual(0)
305
- expect(data.stats.totalDownloads).toBeGreaterThanOrEqual(0)
306
- })
307
-
308
- it('should return integer statistics', async () => {
309
- const res = await app.request('/app-data.json', {}, env)
310
- expect([200, 404, 500].includes(res.status)).toBe(true)
311
-
312
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
313
- if (res.status === 500) return
314
-
315
- const data = (await res.json()) as any
316
- expect(Number.isInteger(data.stats.totalPackages)).toBe(true)
317
- expect(Number.isInteger(data.stats.totalDownloads)).toBe(true)
318
- })
319
-
320
- it('should have consistent package count', async () => {
321
- const res = await app.request('/app-data.json', {}, env)
322
- expect([200, 404, 500].includes(res.status)).toBe(true)
323
-
324
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
325
- if (res.status === 500) return
326
-
327
- const data = (await res.json()) as any
328
- // Total packages should match or be close to packages array length
329
- // (might differ due to filtering, pagination, etc.)
330
- expect(data.stats.totalPackages).toBeGreaterThanOrEqual(0)
331
- expect(data.packages.length).toBeGreaterThanOrEqual(0)
332
- })
333
- })
334
- })
335
-
336
- describe('Dashboard Error Handling', () => {
337
- describe('Daemon Disabled Responses', () => {
338
- it('should return consistent data format in standalone mode', async () => {
339
- const res = await app.request('/dashboard.json', {}, env)
340
- expect([200, 404, 500].includes(res.status)).toBe(true)
341
-
342
- if (res.status === 200) {
343
- const data = (await res.json()) as any
344
- expect(data).toBeDefined()
345
- expect(data.registry).toBeDefined()
346
- expect(data.features).toBeDefined()
347
- } else if (res.status === 404) {
348
- try {
349
- const data = (await res.json()) as any
350
- expect(data).toBeDefined()
351
- expect(data.error).toBeDefined()
352
- } catch {
353
- // 500 responses may return text/plain instead of JSON
354
- }
355
- }
356
- })
357
-
358
- it('should return consistent data format for app-data in standalone mode', async () => {
359
- const res = await app.request('/app-data.json', {}, env)
360
- expect([200, 404, 500].includes(res.status)).toBe(true)
361
-
362
- if (res.status === 200) {
363
- const data = (await res.json()) as any
364
- expect(data).toBeDefined()
365
- expect(data.packages).toBeDefined()
366
- expect(data.stats).toBeDefined()
367
- } else if (res.status === 404) {
368
- try {
369
- const data = (await res.json()) as any
370
- expect(data).toBeDefined()
371
- expect(data.error).toBeDefined()
372
- } catch {
373
- // 500 responses may return text/plain instead of JSON
374
- }
375
- }
376
- })
377
- })
378
-
379
- describe('HTTP Method Validation', () => {
380
- it('should handle POST requests to dashboard endpoints', async () => {
381
- const res = await app.request(
382
- '/dashboard.json',
383
- { method: 'POST' },
384
- env,
385
- )
386
- expect(
387
- [200, 401, 404, 405, 500, 501].includes(res.status),
388
- ).toBe(true)
389
- })
390
-
391
- it('should handle PUT requests to dashboard endpoints', async () => {
392
- const res = await app.request(
393
- '/app-data.json',
394
- { method: 'PUT' },
395
- env,
396
- )
397
- expect(
398
- [200, 401, 404, 405, 500, 501].includes(res.status),
399
- ).toBe(true)
400
- })
401
-
402
- it('should handle DELETE requests to dashboard endpoints', async () => {
403
- const res = await app.request(
404
- '/dashboard.json',
405
- { method: 'DELETE' },
406
- env,
407
- )
408
- expect(
409
- [200, 401, 404, 405, 500, 501].includes(res.status),
410
- ).toBe(true)
411
- })
412
- })
413
-
414
- // Database error handling is now tested through real bindings in integration tests
415
- })
416
-
417
- describe('Dashboard Response Headers', () => {
418
- describe('Content-Type Headers', () => {
419
- it('should set correct content-type for dashboard.json', async () => {
420
- const res = await app.request('/dashboard.json', {}, env)
421
- expect([200, 404, 500].includes(res.status)).toBe(true)
422
-
423
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
424
- if (res.status === 500) return
425
- // Dashboard endpoints may return 500 with text/plain when external services are unavailable
426
- if (res.status === 200) {
427
- expect(res.headers.get('content-type')).toContain(
428
- 'application/json',
429
- )
430
- } else if (res.status === 500) {
431
- expect(res.headers.get('content-type')).toContain(
432
- 'text/plain',
433
- )
434
- }
435
- })
436
-
437
- it('should set correct content-type for app-data.json', async () => {
438
- const res = await app.request('/app-data.json', {}, env)
439
- expect([200, 404, 500].includes(res.status)).toBe(true)
440
-
441
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
442
- if (res.status === 500) return
443
- // Dashboard endpoints may return 500 with text/plain when external services are unavailable
444
- if (res.status === 200) {
445
- expect(res.headers.get('content-type')).toContain(
446
- 'application/json',
447
- )
448
- } else if (res.status === 500) {
449
- expect(res.headers.get('content-type')).toContain(
450
- 'text/plain',
451
- )
452
- }
453
- })
454
-
455
- it('should set correct content-type for responses', async () => {
456
- const res = await app.request('/dashboard.json', {}, env)
457
- expect([200, 404, 500].includes(res.status)).toBe(true)
458
- // Dashboard endpoints now return data in standalone mode or errors
459
- if (res.status === 200) {
460
- expect(res.headers.get('content-type')).toContain(
461
- 'application/json',
462
- )
463
- } else if (res.status === 404) {
464
- expect(res.headers.get('content-type')).toContain(
465
- 'application/json',
466
- )
467
- } else if (res.status === 500) {
468
- expect(res.headers.get('content-type')).toContain(
469
- 'text/plain',
470
- )
471
- }
472
- })
473
- })
474
-
475
- describe('Cache Control Headers', () => {
476
- it('should set appropriate cache headers for dashboard data', async () => {
477
- const res = await app.request('/dashboard.json', {}, env)
478
- expect([200, 404, 500].includes(res.status)).toBe(true)
479
-
480
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
481
- if (res.status === 500) return
482
- // Cache headers would be validated based on implementation
483
- // Dashboard data might be cached for short periods
484
- })
485
-
486
- it('should set appropriate cache headers for app data', async () => {
487
- const res = await app.request('/app-data.json', {}, env)
488
- expect([200, 404, 500].includes(res.status)).toBe(true)
489
-
490
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
491
- if (res.status === 500) return
492
- // App data might have different caching strategy than dashboard config
493
- })
494
- })
495
-
496
- describe('Security Headers', () => {
497
- it('should include security headers in dashboard responses', async () => {
498
- const res = await app.request('/dashboard.json', {}, env)
499
- expect([200, 404, 500].includes(res.status)).toBe(true)
500
-
501
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
502
- if (res.status === 500) return
503
- // Security headers would be validated based on implementation
504
- })
505
-
506
- it('should include CORS headers for dashboard endpoints', async () => {
507
- const res = await app.request(
508
- '/app-data.json',
509
- {
510
- headers: {
511
- Origin: 'https://example.com',
512
- },
513
- },
514
- env,
515
- )
516
- expect([200, 404, 500].includes(res.status)).toBe(true)
517
-
518
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
519
- if (res.status === 500) return
520
- // CORS headers would be validated based on implementation
521
- })
522
- })
523
- })
524
-
525
- describe('Dashboard Performance', () => {
526
- describe('Response Time', () => {
527
- const factor = env.REAL_PLATFORM === 'win32' ? 10 : 1
528
- it(`should respond quickly for dashboard data`, async () => {
529
- const startTime = Date.now()
530
- const res = await app.request('/dashboard.json', {}, env)
531
- const endTime = Date.now()
532
-
533
- expect([200, 404, 500].includes(res.status)).toBe(true)
534
-
535
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
536
- if (res.status === 500) return
537
- expect(endTime - startTime).toBeLessThan(factor * 1000) // 1 second
538
- })
539
-
540
- it(`should respond quickly for app data`, async () => {
541
- const startTime = Date.now()
542
- const res = await app.request('/app-data.json', {}, env)
543
- const endTime = Date.now()
544
-
545
- expect([200, 404, 500].includes(res.status)).toBe(true)
546
-
547
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
548
- if (res.status === 500) return
549
- expect(endTime - startTime).toBeLessThan(factor * 2000) // 2 seconds (might query database)
550
- })
551
- })
552
-
553
- describe('Concurrent Requests', () => {
554
- it('should handle concurrent dashboard requests', async () => {
555
- const promises = [
556
- app.request('/dashboard.json', {}, env),
557
- app.request('/dashboard.json', {}, env),
558
- app.request('/dashboard.json', {}, env),
559
- ]
560
-
561
- const results = await Promise.all(promises)
562
- results.forEach(res => {
563
- expect([200, 404, 500].includes(res.status)).toBe(true)
564
-
565
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
566
- if (res.status === 500) return
567
- })
568
- })
569
-
570
- it('should handle concurrent app data requests', async () => {
571
- const promises = [
572
- app.request('/app-data.json', {}, env),
573
- app.request('/app-data.json', {}, env),
574
- app.request('/app-data.json', {}, env),
575
- ]
576
-
577
- const results = await Promise.all(promises)
578
- results.forEach(res => {
579
- expect([200, 404, 500].includes(res.status)).toBe(true)
580
-
581
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
582
- if (res.status === 500) return
583
- })
584
- })
585
-
586
- it('should handle mixed dashboard endpoint requests', async () => {
587
- const promises = [
588
- app.request('/dashboard.json', {}, env),
589
- app.request('/app-data.json', {}, env),
590
- app.request('/dashboard.json', {}, env),
591
- app.request('/app-data.json', {}, env),
592
- ]
593
-
594
- const results = await Promise.all(promises)
595
- results.forEach(res => {
596
- expect([200, 404, 500].includes(res.status)).toBe(true)
597
-
598
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
599
- if (res.status === 500) return
600
- })
601
- })
602
- })
603
- })
604
-
605
- describe('Dashboard Integration', () => {
606
- describe('Data Consistency', () => {
607
- it('should return consistent data across multiple requests', async () => {
608
- const res1 = await app.request('/dashboard.json', {}, env)
609
- const res2 = await app.request('/dashboard.json', {}, env)
610
-
611
- expect([200, 500].includes(res1.status)).toBe(true)
612
- expect([200, 500].includes(res2.status)).toBe(true)
613
-
614
- if (res1.status === 200 && res2.status === 200) {
615
- const data1 = await res1.json()
616
- const data2 = await res2.json()
617
-
618
- // Configuration should be consistent
619
- expect(data1.registry.name).toBe(data2.registry.name)
620
- expect(data1.registry.url).toBe(data2.registry.url)
621
- }
622
- })
623
-
624
- it('should return app data that matches dashboard configuration', async () => {
625
- const dashboardRes = await app.request(
626
- '/dashboard.json',
627
- {},
628
- env,
629
- )
630
- const appDataRes = await app.request(
631
- '/app-data.json',
632
- {},
633
- env,
634
- )
635
-
636
- expect([200, 404, 500].includes(dashboardRes.status)).toBe(
637
- true,
638
- )
639
- expect([200, 404, 500].includes(appDataRes.status)).toBe(true)
640
-
641
- if (
642
- dashboardRes.status === 200 &&
643
- appDataRes.status === 200
644
- ) {
645
- const dashboard = await dashboardRes.json()
646
- const appData = await appDataRes.json()
647
-
648
- // Both should be valid JSON objects
649
- expect(typeof dashboard).toBe('object')
650
- expect(typeof appData).toBe('object')
651
- }
652
- })
653
- })
654
-
655
- describe('Feature Flag Integration', () => {
656
- it('should reflect search feature availability in dashboard', async () => {
657
- const res = await app.request('/dashboard.json', {}, env)
658
- expect([200, 404, 500].includes(res.status)).toBe(true)
659
-
660
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
661
- if (res.status === 500) return
662
-
663
- const data = (await res.json()) as any
664
- expect(typeof data.features.search).toBe('boolean')
665
- // Search feature flag should be consistent with actual search endpoint availability
666
- })
667
-
668
- it('should reflect publish feature availability in dashboard', async () => {
669
- const res = await app.request('/dashboard.json', {}, env)
670
- expect([200, 404, 500].includes(res.status)).toBe(true)
671
-
672
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
673
- if (res.status === 500) return
674
-
675
- const data = (await res.json()) as any
676
- expect(typeof data.features.publish).toBe('boolean')
677
- // Publish feature flag should be consistent with actual publish endpoint availability
678
- })
679
-
680
- it('should reflect access control feature availability in dashboard', async () => {
681
- const res = await app.request('/dashboard.json', {}, env)
682
- expect([200, 404, 500].includes(res.status)).toBe(true)
683
-
684
- // Skip JSON parsing tests if endpoint returns 500 (external service unavailable)
685
- if (res.status === 500) return
686
-
687
- const data = (await res.json()) as any
688
- expect(typeof data.features.access).toBe('boolean')
689
- // Access feature flag should be consistent with actual access control endpoints
690
- })
691
- })
692
- })
693
- })