@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.
- package/dist/auth/config.d.ts +20 -0
- package/dist/auth/config.d.ts.map +1 -0
- package/dist/auth/config.js +114 -0
- package/dist/auth/config.js.map +1 -0
- package/dist/auth/index.d.ts +5 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +17 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/middleware.d.ts +45 -0
- package/dist/auth/middleware.d.ts.map +1 -0
- package/dist/auth/middleware.js +170 -0
- package/dist/auth/middleware.js.map +1 -0
- package/dist/auth/service.d.ts +80 -0
- package/dist/auth/service.d.ts.map +1 -0
- package/dist/auth/service.js +298 -0
- package/dist/auth/service.js.map +1 -0
- package/dist/cli/index.d.ts +6 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +375 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/mock-server.d.ts +20 -0
- package/dist/cli/mock-server.d.ts.map +1 -0
- package/dist/cli/mock-server.js +261 -0
- package/dist/cli/mock-server.js.map +1 -0
- package/dist/compliance/compliance-generator.d.ts +34 -0
- package/dist/compliance/compliance-generator.d.ts.map +1 -0
- package/dist/compliance/compliance-generator.js +320 -0
- package/dist/compliance/compliance-generator.js.map +1 -0
- package/dist/compliance/index.d.ts +8 -0
- package/dist/compliance/index.d.ts.map +1 -0
- package/dist/compliance/index.js +17 -0
- package/dist/compliance/index.js.map +1 -0
- package/dist/compliance/templates.d.ts +34 -0
- package/dist/compliance/templates.d.ts.map +1 -0
- package/{src/compliance/templates.ts → dist/compliance/templates.js} +117 -155
- package/dist/compliance/templates.js.map +1 -0
- package/dist/compliance/types.d.ts +64 -0
- package/dist/compliance/types.d.ts.map +1 -0
- package/dist/compliance/types.js +64 -0
- package/dist/compliance/types.js.map +1 -0
- package/dist/db/index.d.ts +17 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +80 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/schema.d.ts +3886 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +425 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/db/utils.d.ts +252 -0
- package/dist/db/utils.d.ts.map +1 -0
- package/dist/db/utils.js +295 -0
- package/dist/db/utils.js.map +1 -0
- package/dist/feed-analyzer/feed-analyzer.d.ts +26 -0
- package/dist/feed-analyzer/feed-analyzer.d.ts.map +1 -0
- package/{src/feed-analyzer/feed-analyzer.ts → dist/feed-analyzer/feed-analyzer.js} +856 -726
- package/dist/feed-analyzer/feed-analyzer.js.map +1 -0
- package/dist/feed-analyzer/index.d.ts +8 -0
- package/dist/feed-analyzer/index.d.ts.map +1 -0
- package/dist/feed-analyzer/index.js +19 -0
- package/dist/feed-analyzer/index.js.map +1 -0
- package/dist/feed-analyzer/types.d.ts +285 -0
- package/dist/feed-analyzer/types.d.ts.map +1 -0
- package/dist/feed-analyzer/types.js +175 -0
- package/dist/feed-analyzer/types.js.map +1 -0
- package/{src/generator/index.ts → dist/generator/index.d.ts} +1 -1
- package/dist/generator/index.d.ts.map +1 -0
- package/dist/generator/index.js +13 -0
- package/dist/generator/index.js.map +1 -0
- package/dist/generator/key-generator.d.ts +24 -0
- package/dist/generator/key-generator.d.ts.map +1 -0
- package/dist/generator/key-generator.js +144 -0
- package/dist/generator/key-generator.js.map +1 -0
- package/dist/generator/profile-builder.d.ts +15 -0
- package/dist/generator/profile-builder.d.ts.map +1 -0
- package/dist/generator/profile-builder.js +338 -0
- package/dist/generator/profile-builder.js.map +1 -0
- package/dist/hosting/artifacts-generator.d.ts +10 -0
- package/dist/hosting/artifacts-generator.d.ts.map +1 -0
- package/{src/hosting/artifacts-generator.ts → dist/hosting/artifacts-generator.js} +191 -241
- package/dist/hosting/artifacts-generator.js.map +1 -0
- package/{src/hosting/index.ts → dist/hosting/index.d.ts} +1 -1
- package/dist/hosting/index.d.ts.map +1 -0
- package/dist/hosting/index.js +10 -0
- package/dist/hosting/index.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +78 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/analytics.d.ts +337 -0
- package/dist/lib/analytics.d.ts.map +1 -0
- package/dist/lib/analytics.js +188 -0
- package/dist/lib/analytics.js.map +1 -0
- package/{src/security/index.ts → dist/security/index.d.ts} +8 -15
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +12 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/security-scanner.d.ts +10 -0
- package/dist/security/security-scanner.d.ts.map +1 -0
- package/dist/security/security-scanner.js +669 -0
- package/dist/security/security-scanner.js.map +1 -0
- package/dist/security/types.d.ts +80 -0
- package/dist/security/types.d.ts.map +1 -0
- package/dist/security/types.js +21 -0
- package/dist/security/types.js.map +1 -0
- package/dist/services/analytics.d.ts +114 -0
- package/dist/services/analytics.d.ts.map +1 -0
- package/dist/services/analytics.js +862 -0
- package/dist/services/analytics.js.map +1 -0
- package/dist/services/badge.d.ts +31 -0
- package/dist/services/badge.d.ts.map +1 -0
- package/dist/services/badge.js +152 -0
- package/dist/services/badge.js.map +1 -0
- package/dist/services/cron.d.ts +125 -0
- package/dist/services/cron.d.ts.map +1 -0
- package/dist/services/cron.js +613 -0
- package/dist/services/cron.js.map +1 -0
- package/dist/services/directory.d.ts +106 -0
- package/dist/services/directory.d.ts.map +1 -0
- package/dist/services/directory.js +351 -0
- package/dist/services/directory.js.map +1 -0
- package/dist/services/email.d.ts +112 -0
- package/dist/services/email.d.ts.map +1 -0
- package/dist/services/email.js +772 -0
- package/dist/services/email.js.map +1 -0
- package/dist/services/hosted-profiles.d.ts +77 -0
- package/dist/services/hosted-profiles.d.ts.map +1 -0
- package/dist/services/hosted-profiles.js +433 -0
- package/dist/services/hosted-profiles.js.map +1 -0
- package/dist/services/latency.d.ts +67 -0
- package/dist/services/latency.d.ts.map +1 -0
- package/dist/services/latency.js +274 -0
- package/dist/services/latency.js.map +1 -0
- package/dist/services/manifest-compliance.d.ts +64 -0
- package/dist/services/manifest-compliance.d.ts.map +1 -0
- package/dist/services/manifest-compliance.js +271 -0
- package/dist/services/manifest-compliance.js.map +1 -0
- package/dist/services/monitoring-diff.d.ts +31 -0
- package/dist/services/monitoring-diff.d.ts.map +1 -0
- package/dist/services/monitoring-diff.js +189 -0
- package/dist/services/monitoring-diff.js.map +1 -0
- package/dist/services/notifications.d.ts +46 -0
- package/dist/services/notifications.d.ts.map +1 -0
- package/dist/services/notifications.js +88 -0
- package/dist/services/notifications.js.map +1 -0
- package/dist/services/stripe.d.ts +93 -0
- package/dist/services/stripe.d.ts.map +1 -0
- package/dist/services/stripe.js +490 -0
- package/dist/services/stripe.js.map +1 -0
- package/dist/services/validation-history.d.ts +99 -0
- package/dist/services/validation-history.d.ts.map +1 -0
- package/dist/services/validation-history.js +344 -0
- package/dist/services/validation-history.js.map +1 -0
- package/dist/services/validation-logging.d.ts +103 -0
- package/dist/services/validation-logging.d.ts.map +1 -0
- package/dist/services/validation-logging.js +210 -0
- package/dist/services/validation-logging.js.map +1 -0
- package/dist/services/validation.d.ts +119 -0
- package/dist/services/validation.d.ts.map +1 -0
- package/dist/services/validation.js +1185 -0
- package/dist/services/validation.js.map +1 -0
- package/dist/simulator/agent-simulator.d.ts +69 -0
- package/dist/simulator/agent-simulator.d.ts.map +1 -0
- package/dist/simulator/agent-simulator.js +870 -0
- package/dist/simulator/agent-simulator.js.map +1 -0
- package/{src/simulator/index.ts → dist/simulator/index.d.ts} +7 -7
- package/dist/simulator/index.d.ts.map +1 -0
- package/dist/simulator/index.js +23 -0
- package/dist/simulator/index.js.map +1 -0
- package/{src/simulator/types.ts → dist/simulator/types.d.ts} +171 -170
- package/dist/simulator/types.d.ts.map +1 -0
- package/dist/simulator/types.js +18 -0
- package/dist/simulator/types.js.map +1 -0
- package/dist/types/acp-validation.d.ts +87 -0
- package/dist/types/acp-validation.d.ts.map +1 -0
- package/dist/types/acp-validation.js +40 -0
- package/dist/types/acp-validation.js.map +1 -0
- package/dist/types/analytics.d.ts +182 -0
- package/dist/types/analytics.d.ts.map +1 -0
- package/dist/types/analytics.js +7 -0
- package/dist/types/analytics.js.map +1 -0
- package/dist/types/generator.d.ts +106 -0
- package/dist/types/generator.d.ts.map +1 -0
- package/dist/types/generator.js +6 -0
- package/dist/types/generator.js.map +1 -0
- package/{src/types/index.ts → dist/types/index.d.ts} +1 -1
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +23 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/ucp-profile.d.ts +111 -0
- package/dist/types/ucp-profile.d.ts.map +1 -0
- package/dist/types/ucp-profile.js +45 -0
- package/dist/types/ucp-profile.js.map +1 -0
- package/dist/types/validation.d.ts +76 -0
- package/dist/types/validation.d.ts.map +1 -0
- package/dist/types/validation.js +42 -0
- package/dist/types/validation.js.map +1 -0
- package/dist/validator/acp/index.d.ts +31 -0
- package/dist/validator/acp/index.d.ts.map +1 -0
- package/dist/validator/acp/index.js +574 -0
- package/dist/validator/acp/index.js.map +1 -0
- package/dist/validator/index.d.ts +26 -0
- package/dist/validator/index.d.ts.map +1 -0
- package/dist/validator/index.js +161 -0
- package/dist/validator/index.js.map +1 -0
- package/dist/validator/network-validator.d.ts +28 -0
- package/dist/validator/network-validator.d.ts.map +1 -0
- package/dist/validator/network-validator.js +319 -0
- package/dist/validator/network-validator.js.map +1 -0
- package/dist/validator/rules-validator.d.ts +19 -0
- package/dist/validator/rules-validator.d.ts.map +1 -0
- package/dist/validator/rules-validator.js +306 -0
- package/dist/validator/rules-validator.js.map +1 -0
- package/dist/validator/sdk-validator.d.ts +58 -0
- package/dist/validator/sdk-validator.d.ts.map +1 -0
- package/{src/validator/sdk-validator.ts → dist/validator/sdk-validator.js} +273 -330
- package/dist/validator/sdk-validator.js.map +1 -0
- package/dist/validator/structural-validator.d.ts +11 -0
- package/dist/validator/structural-validator.d.ts.map +1 -0
- package/dist/validator/structural-validator.js +549 -0
- package/dist/validator/structural-validator.js.map +1 -0
- package/dist/validator/utils.d.ts +51 -0
- package/dist/validator/utils.d.ts.map +1 -0
- package/dist/validator/utils.js +132 -0
- package/dist/validator/utils.js.map +1 -0
- package/package.json +44 -12
- package/CLAUDE.md +0 -109
- package/api/analyze-feed.js +0 -140
- package/api/badge.js +0 -185
- package/api/benchmark.js +0 -177
- package/api/directory-stats.ts +0 -29
- package/api/directory.ts +0 -73
- package/api/generate-compliance.js +0 -143
- package/api/generate-schema.js +0 -457
- package/api/generate.js +0 -132
- package/api/security-scan.js +0 -133
- package/api/simulate.js +0 -187
- package/api/tsconfig.json +0 -10
- package/api/validate.js +0 -1351
- package/apify-actor/.actor/actor.json +0 -68
- package/apify-actor/.actor/input_schema.json +0 -32
- package/apify-actor/APIFY-STORE-LISTING.md +0 -412
- package/apify-actor/Dockerfile +0 -8
- package/apify-actor/README.md +0 -166
- package/apify-actor/main.ts +0 -111
- package/apify-actor/package.json +0 -17
- package/apify-actor/src/main.js +0 -199
- package/docs/BRAND-IDENTITY.md +0 -238
- package/docs/BRAND-STYLE-GUIDE.md +0 -356
- package/drizzle/0000_black_king_cobra.sql +0 -39
- package/drizzle/meta/0000_snapshot.json +0 -309
- package/drizzle/meta/_journal.json +0 -13
- package/drizzle.config.ts +0 -10
- package/public/.well-known/ucp +0 -25
- package/public/android-chrome-192x192.png +0 -0
- package/public/android-chrome-512x512.png +0 -0
- package/public/apple-touch-icon.png +0 -0
- package/public/brand.css +0 -321
- package/public/directory.html +0 -701
- package/public/favicon-16x16.png +0 -0
- package/public/favicon-32x32.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/guides/bigcommerce.html +0 -743
- package/public/guides/fastucp.html +0 -838
- package/public/guides/magento.html +0 -779
- package/public/guides/shopify.html +0 -726
- package/public/guides/squarespace.html +0 -749
- package/public/guides/wix.html +0 -747
- package/public/guides/woocommerce.html +0 -733
- package/public/index.html +0 -3835
- package/public/learn.html +0 -396
- package/public/logo.jpeg +0 -0
- package/public/og-image-icon.png +0 -0
- package/public/og-image.png +0 -0
- package/public/robots.txt +0 -6
- package/public/site.webmanifest +0 -31
- package/public/sitemap.xml +0 -69
- package/public/social/linkedin-banner-1128x191.png +0 -0
- package/public/social/temp.PNG +0 -0
- package/public/social/x-header-1500x500.png +0 -0
- package/public/verify.html +0 -410
- package/scripts/generate-favicons.js +0 -44
- package/scripts/generate-ico.js +0 -23
- package/scripts/generate-og-image.js +0 -45
- package/scripts/reset-db.ts +0 -77
- package/scripts/seed-db.ts +0 -71
- package/scripts/setup-benchmark-db.js +0 -70
- package/src/api/server.ts +0 -266
- package/src/cli/index.ts +0 -302
- package/src/compliance/compliance-generator.ts +0 -452
- package/src/compliance/index.ts +0 -28
- package/src/compliance/types.ts +0 -170
- package/src/db/index.ts +0 -28
- package/src/db/schema.ts +0 -84
- package/src/feed-analyzer/index.ts +0 -34
- package/src/feed-analyzer/types.ts +0 -354
- package/src/generator/key-generator.ts +0 -124
- package/src/generator/profile-builder.ts +0 -402
- package/src/index.ts +0 -105
- package/src/security/security-scanner.ts +0 -604
- package/src/security/types.ts +0 -55
- package/src/services/directory.ts +0 -434
- package/src/simulator/agent-simulator.ts +0 -941
- package/src/types/generator.ts +0 -140
- package/src/types/ucp-profile.ts +0 -140
- package/src/types/validation.ts +0 -89
- package/src/validator/index.ts +0 -194
- package/src/validator/network-validator.ts +0 -417
- package/src/validator/rules-validator.ts +0 -297
- package/src/validator/structural-validator.ts +0 -476
- package/tests/fixtures/non-compliant-profile.json +0 -25
- package/tests/fixtures/official-sample-profile.json +0 -75
- package/tests/integration/benchmark.test.ts +0 -207
- package/tests/integration/database.test.ts +0 -163
- package/tests/integration/directory-api.test.ts +0 -268
- package/tests/integration/simulate-api.test.ts +0 -230
- package/tests/integration/validate-api.test.ts +0 -269
- package/tests/setup.ts +0 -15
- package/tests/unit/agent-simulator.test.ts +0 -575
- package/tests/unit/compliance-generator.test.ts +0 -374
- package/tests/unit/directory-service.test.ts +0 -272
- package/tests/unit/feed-analyzer.test.ts +0 -517
- package/tests/unit/lint-suggestions.test.ts +0 -423
- package/tests/unit/official-samples.test.ts +0 -211
- package/tests/unit/pdf-report.test.ts +0 -390
- package/tests/unit/sdk-validator.test.ts +0 -531
- package/tests/unit/security-scanner.test.ts +0 -410
- package/tests/unit/validation.test.ts +0 -390
- package/tsconfig.json +0 -20
- package/vercel.json +0 -34
- 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
|
-
}
|