Skip to content

Commit 97e62a6

Browse files
committed
fix: enhance MSW plugin configuration with robust manual handlers for API endpoints
1 parent 5b3324c commit 97e62a6

File tree

1 file changed

+82
-27
lines changed

1 file changed

+82
-27
lines changed

.storybook/msw-browser.ts

Lines changed: 82 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -42,33 +42,82 @@ export async function startMockServer() {
4242
console.error('❌ CRM Config is missing! Skipping AppPlugin.');
4343
}
4444

45-
mswPlugin = new MSWPlugin({
46-
enableBrowser: false, // Disable auto-start, let msw-storybook-addon handle it
47-
baseUrl: '/api/v1',
48-
logRequests: true,
49-
customHandlers: [
50-
// Handle /api/v1 for ObjectStackClient.connect()
51-
http.get('/api/v1', async () => {
52-
return HttpResponse.json({
53-
version: '1.0',
54-
objects: ['contact', 'opportunity', 'account'],
55-
endpoints: {
56-
data: '/api/v1/data',
57-
metadata: '/api/v1/metadata'
58-
}
59-
});
60-
}),
61-
http.get('/api/v1/', async () => {
62-
return HttpResponse.json({
63-
version: '1.0',
64-
objects: ['contact', 'opportunity', 'account'],
65-
endpoints: {
66-
data: '/api/v1/data',
67-
metadata: '/api/v1/metadata'
68-
}
45+
46+
// Create handlers manually, similar to console app tests
47+
const protocol = kernel.getService('protocol') as any;
48+
49+
// We override mswPlugin handlers or just add ours.
50+
// Since we are not using startServer(), we need to pass handlers to msw-storybook-addon via context
51+
// But this function returns kernel.
52+
// The msw-browser handles customHandlers inside MSWPlugin initialization?
53+
// No, we passed them in constructor.
54+
55+
// Let's redefine handlers to be robust
56+
const manualHandlers = [
57+
// Discovery endpoint
58+
http.get('/api/v1', async () => {
59+
const response = await protocol.getDiscovery();
60+
return HttpResponse.json(response);
61+
}),
62+
http.get('/api/v1/', async () => {
63+
const response = await protocol.getDiscovery();
64+
return HttpResponse.json(response);
65+
}),
66+
67+
// Metadata endpoints
68+
http.get('/api/v1/metadata/object/:objectName', async ({ params }) => {
69+
console.log('[MSW] Get Meta:', params.objectName);
70+
try {
71+
const response = await protocol.getMetaItem({
72+
type: 'object',
73+
name: params.objectName as string
6974
});
70-
}),
71-
http.get('/api/bootstrap', async () => {
75+
const payload = (response && response.item) ? response.item : response;
76+
return HttpResponse.json(payload || { error: 'Not found' }, { status: payload ? 200 : 404 });
77+
} catch (e) {
78+
return HttpResponse.json({ error: String(e) }, { status: 500 });
79+
}
80+
}),
81+
82+
// Data List
83+
http.get('/api/v1/data/:objectName', async ({ params, request }) => {
84+
console.log('[MSW] Find:', params.objectName);
85+
try {
86+
const url = new URL(request.url);
87+
const query: any = {};
88+
// Simple query parsing if needed, but for now just pass to driver
89+
const records = await driver.find(params.objectName as string, {});
90+
91+
// Wrap if protocol expects it (OData style often matches { value: [] })
92+
// But Protocol service might do this.
93+
// If we bypass protocol and go to driver, we get raw array.
94+
// Client expects { value: [] } usually?
95+
// Let's check console mock: It returns { value: response }
96+
return HttpResponse.json({ value: records }, { status: 200 });
97+
} catch (e) {
98+
return HttpResponse.json({ error: String(e) }, { status: 500 });
99+
}
100+
}),
101+
102+
// Data Detail
103+
http.get('/api/v1/data/:objectName/:id', async ({ params }) => {
104+
console.log('[MSW] FindOne:', params.objectName, params.id);
105+
try {
106+
// For InMemoryDriver, findOne might need exact ID match.
107+
// Console mock used driver.find with where clause.
108+
// Let's use findOne if available or scan.
109+
const record = await driver.findOne(params.objectName as string, params.id as string);
110+
if (record) return HttpResponse.json(record);
111+
112+
// Fallback to find
113+
const records = await driver.find(params.objectName as string, {});
114+
const found = records.find((r: any) => r._id === params.id || r.id === params.id);
115+
return HttpResponse.json(found || { error: 'Not Found' }, { status: found ? 200 : 404 });
116+
} catch (e) {
117+
return HttpResponse.json({ error: String(e) }, { status: 500 });
118+
}
119+
}),
120+
http.get('/api/bootstrap', async () => {
72121
const contacts = await driver.find('contact', { object: 'contact' });
73122
const stats = { revenue: 125000, leads: 45, deals: 12 };
74123
return HttpResponse.json({
@@ -77,7 +126,13 @@ export async function startMockServer() {
77126
contacts: contacts || []
78127
});
79128
})
80-
]
129+
];
130+
131+
mswPlugin = new MSWPlugin({
132+
enableBrowser: false,
133+
baseUrl: '/api/v1',
134+
logRequests: true,
135+
customHandlers: manualHandlers
81136
});
82137

83138
kernel.use(mswPlugin);

0 commit comments

Comments
 (0)