@ucptools/validator 1.0.0 → 1.1.0

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 (330) hide show
  1. package/dist/auth/config.d.ts +20 -0
  2. package/dist/auth/config.d.ts.map +1 -0
  3. package/dist/auth/config.js +114 -0
  4. package/dist/auth/config.js.map +1 -0
  5. package/dist/auth/index.d.ts +5 -0
  6. package/dist/auth/index.d.ts.map +1 -0
  7. package/dist/auth/index.js +17 -0
  8. package/dist/auth/index.js.map +1 -0
  9. package/dist/auth/middleware.d.ts +45 -0
  10. package/dist/auth/middleware.d.ts.map +1 -0
  11. package/dist/auth/middleware.js +170 -0
  12. package/dist/auth/middleware.js.map +1 -0
  13. package/dist/auth/service.d.ts +80 -0
  14. package/dist/auth/service.d.ts.map +1 -0
  15. package/dist/auth/service.js +298 -0
  16. package/dist/auth/service.js.map +1 -0
  17. package/dist/cli/index.d.ts +6 -0
  18. package/dist/cli/index.d.ts.map +1 -0
  19. package/dist/cli/index.js +375 -0
  20. package/dist/cli/index.js.map +1 -0
  21. package/dist/cli/mock-server.d.ts +20 -0
  22. package/dist/cli/mock-server.d.ts.map +1 -0
  23. package/dist/cli/mock-server.js +261 -0
  24. package/dist/cli/mock-server.js.map +1 -0
  25. package/dist/compliance/compliance-generator.d.ts +34 -0
  26. package/dist/compliance/compliance-generator.d.ts.map +1 -0
  27. package/dist/compliance/compliance-generator.js +320 -0
  28. package/dist/compliance/compliance-generator.js.map +1 -0
  29. package/dist/compliance/index.d.ts +8 -0
  30. package/dist/compliance/index.d.ts.map +1 -0
  31. package/dist/compliance/index.js +17 -0
  32. package/dist/compliance/index.js.map +1 -0
  33. package/dist/compliance/templates.d.ts +34 -0
  34. package/dist/compliance/templates.d.ts.map +1 -0
  35. package/{src/compliance/templates.ts → dist/compliance/templates.js} +117 -155
  36. package/dist/compliance/templates.js.map +1 -0
  37. package/dist/compliance/types.d.ts +64 -0
  38. package/dist/compliance/types.d.ts.map +1 -0
  39. package/dist/compliance/types.js +64 -0
  40. package/dist/compliance/types.js.map +1 -0
  41. package/dist/db/index.d.ts +17 -0
  42. package/dist/db/index.d.ts.map +1 -0
  43. package/dist/db/index.js +80 -0
  44. package/dist/db/index.js.map +1 -0
  45. package/dist/db/schema.d.ts +3886 -0
  46. package/dist/db/schema.d.ts.map +1 -0
  47. package/dist/db/schema.js +425 -0
  48. package/dist/db/schema.js.map +1 -0
  49. package/dist/db/utils.d.ts +252 -0
  50. package/dist/db/utils.d.ts.map +1 -0
  51. package/dist/db/utils.js +295 -0
  52. package/dist/db/utils.js.map +1 -0
  53. package/dist/feed-analyzer/feed-analyzer.d.ts +26 -0
  54. package/dist/feed-analyzer/feed-analyzer.d.ts.map +1 -0
  55. package/{src/feed-analyzer/feed-analyzer.ts → dist/feed-analyzer/feed-analyzer.js} +856 -726
  56. package/dist/feed-analyzer/feed-analyzer.js.map +1 -0
  57. package/dist/feed-analyzer/index.d.ts +8 -0
  58. package/dist/feed-analyzer/index.d.ts.map +1 -0
  59. package/dist/feed-analyzer/index.js +19 -0
  60. package/dist/feed-analyzer/index.js.map +1 -0
  61. package/dist/feed-analyzer/types.d.ts +285 -0
  62. package/dist/feed-analyzer/types.d.ts.map +1 -0
  63. package/dist/feed-analyzer/types.js +175 -0
  64. package/dist/feed-analyzer/types.js.map +1 -0
  65. package/{src/generator/index.ts → dist/generator/index.d.ts} +1 -1
  66. package/dist/generator/index.d.ts.map +1 -0
  67. package/dist/generator/index.js +13 -0
  68. package/dist/generator/index.js.map +1 -0
  69. package/dist/generator/key-generator.d.ts +24 -0
  70. package/dist/generator/key-generator.d.ts.map +1 -0
  71. package/dist/generator/key-generator.js +144 -0
  72. package/dist/generator/key-generator.js.map +1 -0
  73. package/dist/generator/profile-builder.d.ts +15 -0
  74. package/dist/generator/profile-builder.d.ts.map +1 -0
  75. package/dist/generator/profile-builder.js +338 -0
  76. package/dist/generator/profile-builder.js.map +1 -0
  77. package/dist/hosting/artifacts-generator.d.ts +10 -0
  78. package/dist/hosting/artifacts-generator.d.ts.map +1 -0
  79. package/{src/hosting/artifacts-generator.ts → dist/hosting/artifacts-generator.js} +191 -241
  80. package/dist/hosting/artifacts-generator.js.map +1 -0
  81. package/{src/hosting/index.ts → dist/hosting/index.d.ts} +1 -1
  82. package/dist/hosting/index.d.ts.map +1 -0
  83. package/dist/hosting/index.js +10 -0
  84. package/dist/hosting/index.js.map +1 -0
  85. package/dist/index.d.ts +18 -0
  86. package/dist/index.d.ts.map +1 -0
  87. package/dist/index.js +78 -0
  88. package/dist/index.js.map +1 -0
  89. package/dist/lib/analytics.d.ts +337 -0
  90. package/dist/lib/analytics.d.ts.map +1 -0
  91. package/dist/lib/analytics.js +188 -0
  92. package/dist/lib/analytics.js.map +1 -0
  93. package/{src/security/index.ts → dist/security/index.d.ts} +8 -15
  94. package/dist/security/index.d.ts.map +1 -0
  95. package/dist/security/index.js +12 -0
  96. package/dist/security/index.js.map +1 -0
  97. package/dist/security/security-scanner.d.ts +10 -0
  98. package/dist/security/security-scanner.d.ts.map +1 -0
  99. package/dist/security/security-scanner.js +669 -0
  100. package/dist/security/security-scanner.js.map +1 -0
  101. package/dist/security/types.d.ts +80 -0
  102. package/dist/security/types.d.ts.map +1 -0
  103. package/dist/security/types.js +21 -0
  104. package/dist/security/types.js.map +1 -0
  105. package/dist/services/analytics.d.ts +114 -0
  106. package/dist/services/analytics.d.ts.map +1 -0
  107. package/dist/services/analytics.js +862 -0
  108. package/dist/services/analytics.js.map +1 -0
  109. package/dist/services/badge.d.ts +31 -0
  110. package/dist/services/badge.d.ts.map +1 -0
  111. package/dist/services/badge.js +152 -0
  112. package/dist/services/badge.js.map +1 -0
  113. package/dist/services/cron.d.ts +125 -0
  114. package/dist/services/cron.d.ts.map +1 -0
  115. package/dist/services/cron.js +613 -0
  116. package/dist/services/cron.js.map +1 -0
  117. package/dist/services/directory.d.ts +106 -0
  118. package/dist/services/directory.d.ts.map +1 -0
  119. package/dist/services/directory.js +351 -0
  120. package/dist/services/directory.js.map +1 -0
  121. package/dist/services/email.d.ts +112 -0
  122. package/dist/services/email.d.ts.map +1 -0
  123. package/dist/services/email.js +772 -0
  124. package/dist/services/email.js.map +1 -0
  125. package/dist/services/hosted-profiles.d.ts +77 -0
  126. package/dist/services/hosted-profiles.d.ts.map +1 -0
  127. package/dist/services/hosted-profiles.js +433 -0
  128. package/dist/services/hosted-profiles.js.map +1 -0
  129. package/dist/services/latency.d.ts +67 -0
  130. package/dist/services/latency.d.ts.map +1 -0
  131. package/dist/services/latency.js +274 -0
  132. package/dist/services/latency.js.map +1 -0
  133. package/dist/services/manifest-compliance.d.ts +64 -0
  134. package/dist/services/manifest-compliance.d.ts.map +1 -0
  135. package/dist/services/manifest-compliance.js +271 -0
  136. package/dist/services/manifest-compliance.js.map +1 -0
  137. package/dist/services/monitoring-diff.d.ts +31 -0
  138. package/dist/services/monitoring-diff.d.ts.map +1 -0
  139. package/dist/services/monitoring-diff.js +189 -0
  140. package/dist/services/monitoring-diff.js.map +1 -0
  141. package/dist/services/notifications.d.ts +46 -0
  142. package/dist/services/notifications.d.ts.map +1 -0
  143. package/dist/services/notifications.js +88 -0
  144. package/dist/services/notifications.js.map +1 -0
  145. package/dist/services/stripe.d.ts +93 -0
  146. package/dist/services/stripe.d.ts.map +1 -0
  147. package/dist/services/stripe.js +490 -0
  148. package/dist/services/stripe.js.map +1 -0
  149. package/dist/services/validation-history.d.ts +99 -0
  150. package/dist/services/validation-history.d.ts.map +1 -0
  151. package/dist/services/validation-history.js +344 -0
  152. package/dist/services/validation-history.js.map +1 -0
  153. package/dist/services/validation-logging.d.ts +103 -0
  154. package/dist/services/validation-logging.d.ts.map +1 -0
  155. package/dist/services/validation-logging.js +210 -0
  156. package/dist/services/validation-logging.js.map +1 -0
  157. package/dist/services/validation.d.ts +119 -0
  158. package/dist/services/validation.d.ts.map +1 -0
  159. package/dist/services/validation.js +1185 -0
  160. package/dist/services/validation.js.map +1 -0
  161. package/dist/simulator/agent-simulator.d.ts +69 -0
  162. package/dist/simulator/agent-simulator.d.ts.map +1 -0
  163. package/dist/simulator/agent-simulator.js +870 -0
  164. package/dist/simulator/agent-simulator.js.map +1 -0
  165. package/{src/simulator/index.ts → dist/simulator/index.d.ts} +7 -7
  166. package/dist/simulator/index.d.ts.map +1 -0
  167. package/dist/simulator/index.js +23 -0
  168. package/dist/simulator/index.js.map +1 -0
  169. package/{src/simulator/types.ts → dist/simulator/types.d.ts} +171 -170
  170. package/dist/simulator/types.d.ts.map +1 -0
  171. package/dist/simulator/types.js +18 -0
  172. package/dist/simulator/types.js.map +1 -0
  173. package/dist/types/acp-validation.d.ts +87 -0
  174. package/dist/types/acp-validation.d.ts.map +1 -0
  175. package/dist/types/acp-validation.js +40 -0
  176. package/dist/types/acp-validation.js.map +1 -0
  177. package/dist/types/analytics.d.ts +182 -0
  178. package/dist/types/analytics.d.ts.map +1 -0
  179. package/dist/types/analytics.js +7 -0
  180. package/dist/types/analytics.js.map +1 -0
  181. package/dist/types/generator.d.ts +106 -0
  182. package/dist/types/generator.d.ts.map +1 -0
  183. package/dist/types/generator.js +6 -0
  184. package/dist/types/generator.js.map +1 -0
  185. package/{src/types/index.ts → dist/types/index.d.ts} +1 -1
  186. package/dist/types/index.d.ts.map +1 -0
  187. package/dist/types/index.js +23 -0
  188. package/dist/types/index.js.map +1 -0
  189. package/dist/types/ucp-profile.d.ts +111 -0
  190. package/dist/types/ucp-profile.d.ts.map +1 -0
  191. package/dist/types/ucp-profile.js +45 -0
  192. package/dist/types/ucp-profile.js.map +1 -0
  193. package/dist/types/validation.d.ts +76 -0
  194. package/dist/types/validation.d.ts.map +1 -0
  195. package/dist/types/validation.js +42 -0
  196. package/dist/types/validation.js.map +1 -0
  197. package/dist/validator/acp/index.d.ts +31 -0
  198. package/dist/validator/acp/index.d.ts.map +1 -0
  199. package/dist/validator/acp/index.js +574 -0
  200. package/dist/validator/acp/index.js.map +1 -0
  201. package/dist/validator/index.d.ts +26 -0
  202. package/dist/validator/index.d.ts.map +1 -0
  203. package/dist/validator/index.js +161 -0
  204. package/dist/validator/index.js.map +1 -0
  205. package/dist/validator/network-validator.d.ts +28 -0
  206. package/dist/validator/network-validator.d.ts.map +1 -0
  207. package/dist/validator/network-validator.js +319 -0
  208. package/dist/validator/network-validator.js.map +1 -0
  209. package/dist/validator/rules-validator.d.ts +19 -0
  210. package/dist/validator/rules-validator.d.ts.map +1 -0
  211. package/dist/validator/rules-validator.js +306 -0
  212. package/dist/validator/rules-validator.js.map +1 -0
  213. package/dist/validator/sdk-validator.d.ts +58 -0
  214. package/dist/validator/sdk-validator.d.ts.map +1 -0
  215. package/{src/validator/sdk-validator.ts → dist/validator/sdk-validator.js} +273 -330
  216. package/dist/validator/sdk-validator.js.map +1 -0
  217. package/dist/validator/structural-validator.d.ts +11 -0
  218. package/dist/validator/structural-validator.d.ts.map +1 -0
  219. package/dist/validator/structural-validator.js +549 -0
  220. package/dist/validator/structural-validator.js.map +1 -0
  221. package/dist/validator/utils.d.ts +51 -0
  222. package/dist/validator/utils.d.ts.map +1 -0
  223. package/dist/validator/utils.js +132 -0
  224. package/dist/validator/utils.js.map +1 -0
  225. package/package.json +44 -12
  226. package/CLAUDE.md +0 -109
  227. package/api/analyze-feed.js +0 -140
  228. package/api/badge.js +0 -185
  229. package/api/benchmark.js +0 -177
  230. package/api/directory-stats.ts +0 -29
  231. package/api/directory.ts +0 -73
  232. package/api/generate-compliance.js +0 -143
  233. package/api/generate-schema.js +0 -457
  234. package/api/generate.js +0 -132
  235. package/api/security-scan.js +0 -133
  236. package/api/simulate.js +0 -187
  237. package/api/tsconfig.json +0 -10
  238. package/api/validate.js +0 -1351
  239. package/apify-actor/.actor/actor.json +0 -68
  240. package/apify-actor/.actor/input_schema.json +0 -32
  241. package/apify-actor/APIFY-STORE-LISTING.md +0 -412
  242. package/apify-actor/Dockerfile +0 -8
  243. package/apify-actor/README.md +0 -166
  244. package/apify-actor/main.ts +0 -111
  245. package/apify-actor/package.json +0 -17
  246. package/apify-actor/src/main.js +0 -199
  247. package/docs/BRAND-IDENTITY.md +0 -238
  248. package/docs/BRAND-STYLE-GUIDE.md +0 -356
  249. package/drizzle/0000_black_king_cobra.sql +0 -39
  250. package/drizzle/meta/0000_snapshot.json +0 -309
  251. package/drizzle/meta/_journal.json +0 -13
  252. package/drizzle.config.ts +0 -10
  253. package/public/.well-known/ucp +0 -25
  254. package/public/android-chrome-192x192.png +0 -0
  255. package/public/android-chrome-512x512.png +0 -0
  256. package/public/apple-touch-icon.png +0 -0
  257. package/public/brand.css +0 -321
  258. package/public/directory.html +0 -701
  259. package/public/favicon-16x16.png +0 -0
  260. package/public/favicon-32x32.png +0 -0
  261. package/public/favicon.ico +0 -0
  262. package/public/guides/bigcommerce.html +0 -743
  263. package/public/guides/fastucp.html +0 -838
  264. package/public/guides/magento.html +0 -779
  265. package/public/guides/shopify.html +0 -726
  266. package/public/guides/squarespace.html +0 -749
  267. package/public/guides/wix.html +0 -747
  268. package/public/guides/woocommerce.html +0 -733
  269. package/public/index.html +0 -3835
  270. package/public/learn.html +0 -396
  271. package/public/logo.jpeg +0 -0
  272. package/public/og-image-icon.png +0 -0
  273. package/public/og-image.png +0 -0
  274. package/public/robots.txt +0 -6
  275. package/public/site.webmanifest +0 -31
  276. package/public/sitemap.xml +0 -69
  277. package/public/social/linkedin-banner-1128x191.png +0 -0
  278. package/public/social/temp.PNG +0 -0
  279. package/public/social/x-header-1500x500.png +0 -0
  280. package/public/verify.html +0 -410
  281. package/scripts/generate-favicons.js +0 -44
  282. package/scripts/generate-ico.js +0 -23
  283. package/scripts/generate-og-image.js +0 -45
  284. package/scripts/reset-db.ts +0 -77
  285. package/scripts/seed-db.ts +0 -71
  286. package/scripts/setup-benchmark-db.js +0 -70
  287. package/src/api/server.ts +0 -266
  288. package/src/cli/index.ts +0 -302
  289. package/src/compliance/compliance-generator.ts +0 -452
  290. package/src/compliance/index.ts +0 -28
  291. package/src/compliance/types.ts +0 -170
  292. package/src/db/index.ts +0 -28
  293. package/src/db/schema.ts +0 -84
  294. package/src/feed-analyzer/index.ts +0 -34
  295. package/src/feed-analyzer/types.ts +0 -354
  296. package/src/generator/key-generator.ts +0 -124
  297. package/src/generator/profile-builder.ts +0 -402
  298. package/src/index.ts +0 -105
  299. package/src/security/security-scanner.ts +0 -604
  300. package/src/security/types.ts +0 -55
  301. package/src/services/directory.ts +0 -434
  302. package/src/simulator/agent-simulator.ts +0 -941
  303. package/src/types/generator.ts +0 -140
  304. package/src/types/ucp-profile.ts +0 -140
  305. package/src/types/validation.ts +0 -89
  306. package/src/validator/index.ts +0 -194
  307. package/src/validator/network-validator.ts +0 -417
  308. package/src/validator/rules-validator.ts +0 -297
  309. package/src/validator/structural-validator.ts +0 -476
  310. package/tests/fixtures/non-compliant-profile.json +0 -25
  311. package/tests/fixtures/official-sample-profile.json +0 -75
  312. package/tests/integration/benchmark.test.ts +0 -207
  313. package/tests/integration/database.test.ts +0 -163
  314. package/tests/integration/directory-api.test.ts +0 -268
  315. package/tests/integration/simulate-api.test.ts +0 -230
  316. package/tests/integration/validate-api.test.ts +0 -269
  317. package/tests/setup.ts +0 -15
  318. package/tests/unit/agent-simulator.test.ts +0 -575
  319. package/tests/unit/compliance-generator.test.ts +0 -374
  320. package/tests/unit/directory-service.test.ts +0 -272
  321. package/tests/unit/feed-analyzer.test.ts +0 -517
  322. package/tests/unit/lint-suggestions.test.ts +0 -423
  323. package/tests/unit/official-samples.test.ts +0 -211
  324. package/tests/unit/pdf-report.test.ts +0 -390
  325. package/tests/unit/sdk-validator.test.ts +0 -531
  326. package/tests/unit/security-scanner.test.ts +0 -410
  327. package/tests/unit/validation.test.ts +0 -390
  328. package/tsconfig.json +0 -20
  329. package/vercel.json +0 -34
  330. package/vitest.config.ts +0 -22
@@ -1,230 +0,0 @@
1
- /**
2
- * Integration tests for the AI Agent Simulation API
3
- */
4
-
5
- import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
6
-
7
- // Mock profile for testing
8
- const mockProfile = {
9
- ucp: {
10
- version: '2026-01-11',
11
- services: {
12
- 'dev.ucp.shopping': {
13
- version: '2026-01-11',
14
- spec: 'https://ucp.dev/specs/shopping',
15
- rest: {
16
- schema: 'https://example.com/api/openapi.json',
17
- endpoint: 'https://example.com/api',
18
- },
19
- },
20
- },
21
- capabilities: [
22
- {
23
- name: 'dev.ucp.shopping.checkout',
24
- version: '2026-01-11',
25
- spec: 'https://ucp.dev/specs/shopping/checkout',
26
- schema: 'https://ucp.dev/schemas/shopping/checkout.json',
27
- },
28
- ],
29
- },
30
- signing_keys: [
31
- {
32
- kty: 'EC',
33
- crv: 'P-256',
34
- x: 'test-x',
35
- y: 'test-y',
36
- kid: 'key-1',
37
- },
38
- ],
39
- };
40
-
41
- // Mock fetch
42
- const originalFetch = global.fetch;
43
-
44
- describe('Simulate API', () => {
45
- beforeEach(() => {
46
- // Reset fetch mock
47
- global.fetch = vi.fn();
48
- });
49
-
50
- afterEach(() => {
51
- global.fetch = originalFetch;
52
- vi.restoreAllMocks();
53
- });
54
-
55
- describe('simulateAgentInteraction function', () => {
56
- it('should simulate agent interaction for valid domain', async () => {
57
- const mockFetch = global.fetch as ReturnType<typeof vi.fn>;
58
-
59
- // Mock successful profile fetch
60
- mockFetch.mockImplementation((url: string) => {
61
- if (url.includes('.well-known/ucp')) {
62
- return Promise.resolve({
63
- ok: true,
64
- status: 200,
65
- headers: new Map([['content-type', 'application/json']]),
66
- json: () => Promise.resolve(mockProfile),
67
- });
68
- }
69
- // Default to success for other URLs
70
- return Promise.resolve({
71
- ok: true,
72
- status: 200,
73
- headers: new Map([['content-type', 'application/json']]),
74
- json: () => Promise.resolve({ properties: { checkout_id: {} } }),
75
- });
76
- });
77
-
78
- const { simulateAgentInteraction } = await import('../../src/simulator/index.js');
79
- const result = await simulateAgentInteraction('example.com', { timeoutMs: 10000 });
80
-
81
- expect(result.ok).toBe(true);
82
- expect(result.domain).toBe('example.com');
83
- expect(result.discovery.success).toBe(true);
84
- expect(result.overallScore).toBeGreaterThan(0);
85
- });
86
-
87
- it('should return low score for unreachable domain', async () => {
88
- const mockFetch = global.fetch as ReturnType<typeof vi.fn>;
89
-
90
- mockFetch.mockResolvedValue({
91
- ok: false,
92
- status: 404,
93
- });
94
-
95
- const { simulateAgentInteraction } = await import('../../src/simulator/index.js');
96
- const result = await simulateAgentInteraction('nonexistent.example.com', { timeoutMs: 5000 });
97
-
98
- expect(result.ok).toBe(false);
99
- expect(result.overallScore).toBe(0);
100
- expect(result.recommendations).toContain('Ensure UCP profile is accessible at /.well-known/ucp or /.well-known/ucp.json');
101
- });
102
-
103
- it('should detect missing checkout capability', async () => {
104
- const mockFetch = global.fetch as ReturnType<typeof vi.fn>;
105
-
106
- const profileWithoutCheckout = {
107
- ucp: {
108
- version: '2026-01-11',
109
- services: {
110
- 'dev.ucp.shopping': {
111
- version: '2026-01-11',
112
- spec: 'https://ucp.dev/specs/shopping',
113
- rest: {
114
- schema: 'https://example.com/api/openapi.json',
115
- endpoint: 'https://example.com/api',
116
- },
117
- },
118
- },
119
- capabilities: [],
120
- },
121
- };
122
-
123
- mockFetch.mockImplementation((url: string) => {
124
- if (url.includes('.well-known/ucp')) {
125
- return Promise.resolve({
126
- ok: true,
127
- status: 200,
128
- headers: new Map([['content-type', 'application/json']]),
129
- json: () => Promise.resolve(profileWithoutCheckout),
130
- });
131
- }
132
- return Promise.resolve({ ok: true, status: 200 });
133
- });
134
-
135
- const { simulateAgentInteraction } = await import('../../src/simulator/index.js');
136
- const result = await simulateAgentInteraction('example.com', { timeoutMs: 10000 });
137
-
138
- expect(result.checkout?.canCreateCheckout).toBe(false);
139
- expect(result.recommendations).toContain('Add checkout capability (dev.ucp.shopping.checkout) to enable purchases');
140
- });
141
-
142
- it('should include all simulation phases', async () => {
143
- const mockFetch = global.fetch as ReturnType<typeof vi.fn>;
144
-
145
- mockFetch.mockImplementation((url: string) => {
146
- if (url.includes('.well-known/ucp')) {
147
- return Promise.resolve({
148
- ok: true,
149
- status: 200,
150
- headers: new Map([['content-type', 'application/json']]),
151
- json: () => Promise.resolve(mockProfile),
152
- });
153
- }
154
- return Promise.resolve({
155
- ok: true,
156
- status: 200,
157
- headers: new Map([['content-type', 'application/json']]),
158
- json: () => Promise.resolve({}),
159
- });
160
- });
161
-
162
- const { simulateAgentInteraction } = await import('../../src/simulator/index.js');
163
- const result = await simulateAgentInteraction('example.com', {
164
- timeoutMs: 10000,
165
- testCheckoutFlow: true,
166
- });
167
-
168
- // Check all phases are present
169
- expect(result.discovery).toBeDefined();
170
- expect(result.capabilities).toBeDefined();
171
- expect(result.services).toBeDefined();
172
- expect(result.restApi).toBeDefined();
173
- expect(result.checkout).toBeDefined();
174
- expect(result.payment).toBeDefined();
175
- expect(result.summary).toBeDefined();
176
- });
177
- });
178
-
179
- describe('API response structure', () => {
180
- it('should generate correct grade from score', async () => {
181
- const mockFetch = global.fetch as ReturnType<typeof vi.fn>;
182
-
183
- mockFetch.mockImplementation((url: string) => {
184
- if (url.includes('.well-known/ucp')) {
185
- return Promise.resolve({
186
- ok: true,
187
- status: 200,
188
- headers: new Map([['content-type', 'application/json']]),
189
- json: () => Promise.resolve(mockProfile),
190
- });
191
- }
192
- return Promise.resolve({
193
- ok: true,
194
- status: 200,
195
- headers: new Map([['content-type', 'application/json']]),
196
- json: () => Promise.resolve({ properties: { checkout_id: {} } }),
197
- });
198
- });
199
-
200
- const { simulateAgentInteraction } = await import('../../src/simulator/index.js');
201
- const result = await simulateAgentInteraction('example.com', { timeoutMs: 10000 });
202
-
203
- // Score should be between 0-100
204
- expect(result.overallScore).toBeGreaterThanOrEqual(0);
205
- expect(result.overallScore).toBeLessThanOrEqual(100);
206
- });
207
-
208
- it('should include timing information', async () => {
209
- const mockFetch = global.fetch as ReturnType<typeof vi.fn>;
210
-
211
- mockFetch.mockImplementation((url: string) => {
212
- if (url.includes('.well-known/ucp')) {
213
- return Promise.resolve({
214
- ok: true,
215
- status: 200,
216
- headers: new Map([['content-type', 'application/json']]),
217
- json: () => Promise.resolve(mockProfile),
218
- });
219
- }
220
- return Promise.resolve({ ok: true, status: 200 });
221
- });
222
-
223
- const { simulateAgentInteraction } = await import('../../src/simulator/index.js');
224
- const result = await simulateAgentInteraction('example.com', { timeoutMs: 10000 });
225
-
226
- expect(result.simulatedAt).toBeDefined();
227
- expect(result.durationMs).toBeGreaterThanOrEqual(0);
228
- });
229
- });
230
- });
@@ -1,269 +0,0 @@
1
- /**
2
- * Integration Tests for Validate API - Lint Suggestions (Issue #9)
3
- * Tests that the validate endpoint returns lint_suggestions in the response
4
- */
5
-
6
- import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
7
-
8
- // Mock validation response structure
9
- interface ValidationResponse {
10
- domain: string;
11
- ucp: {
12
- found: boolean;
13
- issues: Array<{ code: string; message: string; severity: string }>;
14
- };
15
- schema: {
16
- found: boolean;
17
- issues: Array<{ code: string; message: string; severity: string; category?: string }>;
18
- stats: {
19
- products: number;
20
- returnPolicies: number;
21
- organizations: number;
22
- };
23
- };
24
- ai_readiness: {
25
- score: number;
26
- grade: string;
27
- label: string;
28
- };
29
- lint_suggestions?: Array<{
30
- severity: string;
31
- title: string;
32
- code: string;
33
- impact: string;
34
- fix?: string;
35
- codeSnippet?: string;
36
- docLink?: string;
37
- generatorLink?: string;
38
- }>;
39
- }
40
-
41
- // Since we can't easily test the actual API endpoint in unit tests,
42
- // we'll test the lint_suggestions structure requirements
43
-
44
- describe('Validate API - Lint Suggestions Response (Issue #9)', () => {
45
- describe('Response Structure', () => {
46
- it('should include lint_suggestions array in response', () => {
47
- // Mock a typical response with issues
48
- const mockResponse: ValidationResponse = {
49
- domain: 'example.com',
50
- ucp: {
51
- found: false,
52
- issues: [{ code: 'UCP_FETCH_FAILED', message: 'No UCP profile found', severity: 'error' }]
53
- },
54
- schema: {
55
- found: true,
56
- issues: [
57
- { code: 'SCHEMA_NO_RETURN_POLICY', message: 'No return policy', severity: 'error', category: 'schema' }
58
- ],
59
- stats: { products: 5, returnPolicies: 0, organizations: 1 }
60
- },
61
- ai_readiness: {
62
- score: 45,
63
- grade: 'F',
64
- label: 'Not Ready'
65
- },
66
- lint_suggestions: [
67
- {
68
- severity: 'critical',
69
- title: 'Create a UCP Profile',
70
- code: 'UCP_FETCH_FAILED',
71
- impact: 'AI shopping agents cannot discover your store without a UCP profile',
72
- docLink: 'https://ucp.dev/docs/getting-started',
73
- generatorLink: '/generate'
74
- },
75
- {
76
- severity: 'critical',
77
- title: 'Add MerchantReturnPolicy Schema',
78
- code: 'SCHEMA_NO_RETURN_POLICY',
79
- impact: 'Required for AI commerce eligibility (Jan 2026 deadline)',
80
- docLink: 'https://schema.org/MerchantReturnPolicy',
81
- generatorLink: '/generate?tab=schema'
82
- }
83
- ]
84
- };
85
-
86
- // Verify structure
87
- expect(mockResponse.lint_suggestions).toBeDefined();
88
- expect(Array.isArray(mockResponse.lint_suggestions)).toBe(true);
89
- expect(mockResponse.lint_suggestions!.length).toBeGreaterThan(0);
90
- });
91
-
92
- it('each suggestion should have required fields', () => {
93
- const suggestion = {
94
- severity: 'critical',
95
- title: 'Create a UCP Profile',
96
- code: 'UCP_FETCH_FAILED',
97
- impact: 'AI shopping agents cannot discover your store without a UCP profile'
98
- };
99
-
100
- expect(suggestion).toHaveProperty('severity');
101
- expect(suggestion).toHaveProperty('title');
102
- expect(suggestion).toHaveProperty('code');
103
- expect(suggestion).toHaveProperty('impact');
104
- });
105
-
106
- it('severity should be valid enum value', () => {
107
- const validSeverities = ['critical', 'warning', 'info'];
108
-
109
- const suggestions = [
110
- { severity: 'critical', title: 'Test', code: 'TEST', impact: 'Test' },
111
- { severity: 'warning', title: 'Test', code: 'TEST', impact: 'Test' },
112
- { severity: 'info', title: 'Test', code: 'TEST', impact: 'Test' }
113
- ];
114
-
115
- suggestions.forEach(s => {
116
- expect(validSeverities).toContain(s.severity);
117
- });
118
- });
119
- });
120
-
121
- describe('Suggestion Content Quality', () => {
122
- it('should provide actionable fix guidance', () => {
123
- const suggestion = {
124
- severity: 'critical',
125
- title: 'Add UCP Version',
126
- code: 'UCP_MISSING_VERSION',
127
- impact: 'Agents cannot determine compatibility without a version',
128
- fix: 'Add a version field in YYYY-MM-DD format',
129
- codeSnippet: '"version": "2026-05-01"',
130
- docLink: 'https://ucp.dev/docs/versioning'
131
- };
132
-
133
- // Should have either fix text or code snippet
134
- expect(suggestion.fix || suggestion.codeSnippet).toBeDefined();
135
- });
136
-
137
- it('should include documentation link when available', () => {
138
- const suggestion = {
139
- severity: 'critical',
140
- title: 'Add MerchantReturnPolicy Schema',
141
- code: 'SCHEMA_NO_RETURN_POLICY',
142
- impact: 'Required for AI commerce eligibility',
143
- docLink: 'https://schema.org/MerchantReturnPolicy'
144
- };
145
-
146
- expect(suggestion.docLink).toMatch(/^https?:\/\//);
147
- });
148
-
149
- it('should include generator link for actionable issues', () => {
150
- const suggestion = {
151
- severity: 'critical',
152
- title: 'Create a UCP Profile',
153
- code: 'UCP_FETCH_FAILED',
154
- impact: 'AI shopping agents cannot discover your store',
155
- generatorLink: '/generate'
156
- };
157
-
158
- expect(suggestion.generatorLink).toBe('/generate');
159
- });
160
- });
161
-
162
- describe('Issue Code Mapping', () => {
163
- const knownIssueCodes = [
164
- // UCP Critical
165
- 'UCP_FETCH_FAILED',
166
- 'UCP_MISSING_ROOT',
167
- 'UCP_MISSING_VERSION',
168
- 'UCP_INVALID_VERSION',
169
- 'UCP_MISSING_SERVICES',
170
- 'UCP_MISSING_CAPABILITIES',
171
- 'UCP_MISSING_KEYS',
172
- 'UCP_ENDPOINT_NOT_HTTPS',
173
- 'UCP_NS_MISMATCH',
174
- // Schema Critical
175
- 'SCHEMA_NO_RETURN_POLICY',
176
- 'SCHEMA_NO_SHIPPING',
177
- // UCP Warnings
178
- 'UCP_NO_TRANSPORT',
179
- 'UCP_TRAILING_SLASH',
180
- 'UCP_ORPHAN_EXT',
181
- // Schema Warnings
182
- 'SCHEMA_NO_ORG',
183
- 'ORG_NO_NAME',
184
- 'SCHEMA_RETURN_NO_COUNTRY',
185
- 'SCHEMA_RETURN_NO_CATEGORY',
186
- // Product Warnings
187
- 'PRODUCT_NO_DESCRIPTION',
188
- 'PRODUCT_NO_IMAGE',
189
- // Contextual
190
- 'SUGGESTION_ADD_CHECKOUT',
191
- 'SUGGESTION_ADD_PRODUCTS',
192
- ];
193
-
194
- it('should have mappings for all known issue codes', () => {
195
- // This test ensures we have coverage for all common issues
196
- expect(knownIssueCodes.length).toBeGreaterThan(20);
197
- });
198
-
199
- it('critical issues should be sorted first', () => {
200
- const suggestions = [
201
- { severity: 'warning', title: 'Warning', code: 'WARN1', impact: 'Test' },
202
- { severity: 'critical', title: 'Critical', code: 'CRIT1', impact: 'Test' },
203
- { severity: 'info', title: 'Info', code: 'INFO1', impact: 'Test' },
204
- ];
205
-
206
- // Sort by severity
207
- const severityOrder: Record<string, number> = { critical: 0, warning: 1, info: 2 };
208
- const sorted = [...suggestions].sort((a, b) => severityOrder[a.severity] - severityOrder[b.severity]);
209
-
210
- expect(sorted[0].severity).toBe('critical');
211
- expect(sorted[1].severity).toBe('warning');
212
- expect(sorted[2].severity).toBe('info');
213
- });
214
- });
215
- });
216
-
217
- describe('Validate API - PDF Report Data (Issue #7)', () => {
218
- describe('Response Data for PDF Generation', () => {
219
- it('should include all data needed for PDF report', () => {
220
- const mockResponse: ValidationResponse = {
221
- domain: 'example.com',
222
- ucp: {
223
- found: true,
224
- issues: []
225
- },
226
- schema: {
227
- found: true,
228
- issues: [],
229
- stats: { products: 10, returnPolicies: 1, organizations: 1 }
230
- },
231
- ai_readiness: {
232
- score: 85,
233
- grade: 'B',
234
- label: 'Partially Ready'
235
- },
236
- lint_suggestions: []
237
- };
238
-
239
- // Required for PDF header
240
- expect(mockResponse.domain).toBeDefined();
241
- expect(mockResponse.ai_readiness.grade).toBeDefined();
242
- expect(mockResponse.ai_readiness.score).toBeDefined();
243
- expect(mockResponse.ai_readiness.label).toBeDefined();
244
-
245
- // Required for PDF sections
246
- expect(mockResponse.ucp).toBeDefined();
247
- expect(mockResponse.ucp.found).toBeDefined();
248
- expect(mockResponse.schema).toBeDefined();
249
- expect(mockResponse.schema.stats).toBeDefined();
250
-
251
- // Required for recommendations
252
- expect(mockResponse.lint_suggestions).toBeDefined();
253
- });
254
-
255
- it('should have grade within valid range A-F', () => {
256
- const validGrades = ['A', 'B', 'C', 'D', 'F'];
257
- const grade = 'B';
258
-
259
- expect(validGrades).toContain(grade);
260
- });
261
-
262
- it('should have score within 0-100 range', () => {
263
- const score = 85;
264
-
265
- expect(score).toBeGreaterThanOrEqual(0);
266
- expect(score).toBeLessThanOrEqual(100);
267
- });
268
- });
269
- });
package/tests/setup.ts DELETED
@@ -1,15 +0,0 @@
1
- /**
2
- * Vitest Test Setup
3
- * Runs before all tests
4
- */
5
-
6
- import { config } from 'dotenv';
7
- import { resolve } from 'path';
8
-
9
- // Load environment variables from .env.local
10
- config({ path: resolve(process.cwd(), '.env.local') });
11
-
12
- // Verify DATABASE_URL is set for integration tests
13
- if (!process.env.DATABASE_URL) {
14
- console.warn('⚠️ DATABASE_URL not set - integration tests will be skipped');
15
- }