Skip to content

Commit a2679a6

Browse files
authored
Merge pull request #308 from objectstack-ai/copilot/build-objectstack-msw-env
2 parents 6e868de + fb2d8b4 commit a2679a6

23 files changed

+2561
-4
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
9+
10+
node_modules
11+
dist
12+
dist-ssr
13+
*.local
14+
15+
# Editor directories and files
16+
.vscode/*
17+
!.vscode/extensions.json
18+
.idea
19+
.DS_Store
20+
*.suo
21+
*.ntvs*
22+
*.njsproj
23+
*.sln
24+
*.sw?
25+
26+
# MSW
27+
public/mockServiceWorker.js

examples/msw-object-form/README.md

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
# MSW ObjectForm Example
2+
3+
This example demonstrates a complete **ObjectForm** integration with **Mock Service Worker (MSW)** for testing and development. It runs a real ObjectStack Runtime in the browser using an in-memory driver, allowing you to develop and test forms without a backend server.
4+
5+
## 🏗️ Architecture
6+
7+
This example uses the same architecture as the [msw-react-crud](https://github.com/objectstack-ai/spec/tree/main/examples/msw-react-crud) reference implementation:
8+
9+
```mermaid
10+
graph TD
11+
ObjectForm["ObjectForm Component"] -->|Data Operations| DataSource["ObjectStackDataSource"]
12+
DataSource -->|REST API Calls| Network["Browser Network Layer"]
13+
Network -->|Intercepted by| SW["Service Worker <br/> MockServiceWorker"]
14+
SW -->|Delegates to| Kernel["ObjectStack Kernel <br/> (Running in Browser)"]
15+
Kernel -->|Uses| MemoryDriver["In-Memory Driver"]
16+
17+
Kernel -.->|Reads| Config["objectstack.config.ts <br/> Schema Definitions"]
18+
```
19+
20+
## 🎯 Key Features
21+
22+
- **ObjectForm Component**: Smart form component that auto-generates forms from ObjectStack schemas
23+
- **MSW Integration**: Complete ObjectStack runtime running in the browser via Service Worker
24+
- **Full CRUD Operations**: Create, Read, Update, Delete contacts with validation
25+
- **Real Logic**: Schema validation, defaults, and field types enforced by ObjectStack Kernel
26+
- **Testing Support**: MSW server setup for Node.js test environment
27+
- **Zero Backend**: Develop and test frontend forms before backend exists
28+
29+
## 📦 What's Inside
30+
31+
### Core Files
32+
33+
- **`src/App.tsx`** - Main application component with ObjectForm integration
34+
- **`src/components/ContactList.tsx`** - Contact list component with edit/delete
35+
- **`src/dataSource.ts`** - ObjectStack DataSource adapter for ObjectForm
36+
- **`src/mocks/browser.ts`** - MSW setup with ObjectStack Kernel (for browser)
37+
- **`src/mocks/server.ts`** - MSW setup for Node.js testing environment
38+
- **`objectstack.config.ts`** - Contact object schema definition
39+
40+
### Test Files
41+
42+
- **`src/__tests__/MSWServer.test.tsx`** - ✅ **Working Tests** - MSW server integration tests
43+
- **`src/__tests__/ObjectFormUnit.test.tsx`** - Unit tests with mock DataSource (partial)
44+
- **`src/__tests__/ObjectForm.test.tsx`** - Integration tests (requires HTTP interception setup)
45+
46+
## 🚀 Getting Started
47+
48+
### Installation
49+
50+
```bash
51+
# Install dependencies (from repository root)
52+
pnpm install
53+
54+
# Navigate to example directory
55+
cd examples/msw-object-form
56+
```
57+
58+
### Development
59+
60+
```bash
61+
# Start development server
62+
pnpm dev
63+
```
64+
65+
Open [http://localhost:5173](http://localhost:5173) to view the app. You can:
66+
- Create new contacts using the form
67+
- Edit existing contacts
68+
- Delete contacts
69+
- See data persist in browser memory
70+
71+
### Testing
72+
73+
```bash
74+
# Run all tests
75+
pnpm test
76+
77+
# Run specific test file
78+
pnpm test MSWServer.test.tsx
79+
80+
# Run tests in watch mode
81+
pnpm test:watch
82+
83+
# Run tests with UI
84+
pnpm test:ui
85+
```
86+
87+
### Build
88+
89+
```bash
90+
# Build for production
91+
pnpm build
92+
93+
# Preview production build
94+
pnpm preview
95+
```
96+
97+
## 📝 Usage Example
98+
99+
### Basic ObjectForm Integration
100+
101+
```tsx
102+
import { ObjectForm } from '@object-ui/plugin-form';
103+
import { ObjectStackDataSource } from './dataSource';
104+
import { ObjectStackClient } from '@objectstack/client';
105+
106+
// Initialize client and data source
107+
const client = new ObjectStackClient({ baseUrl: '' });
108+
await client.connect();
109+
const dataSource = new ObjectStackDataSource(client);
110+
111+
// Render ObjectForm
112+
<ObjectForm
113+
schema={{
114+
type: 'object-form',
115+
objectName: 'contact',
116+
mode: 'create', // or 'edit' or 'view'
117+
fields: ['name', 'email', 'phone', 'company'],
118+
layout: 'vertical',
119+
onSuccess: (data) => console.log('Created:', data),
120+
}}
121+
dataSource={dataSource}
122+
/>
123+
```
124+
125+
### Testing with MSW Server
126+
127+
```tsx
128+
import { startMockServer, stopMockServer, getDriver } from './mocks/server';
129+
130+
// Start MSW server for tests
131+
beforeAll(async () => {
132+
await startMockServer();
133+
});
134+
135+
afterAll(() => {
136+
stopMockServer();
137+
});
138+
139+
// Test with direct driver access
140+
it('should initialize with data', async () => {
141+
const driver = getDriver();
142+
const contacts = await driver!.find('contact', {});
143+
expect(contacts).toHaveLength(3);
144+
});
145+
```
146+
147+
## 🔧 Customization
148+
149+
### Modify the Schema
150+
151+
Edit `objectstack.config.ts` to add/remove fields or change object properties:
152+
153+
```typescript
154+
export const ContactObject = {
155+
name: 'contact',
156+
fields: {
157+
// Add your custom fields here
158+
custom_field: {
159+
name: 'custom_field',
160+
label: 'Custom Field',
161+
type: 'text'
162+
},
163+
}
164+
};
165+
```
166+
167+
### Add Custom Validation
168+
169+
Implement custom validation in the ObjectForm schema:
170+
171+
```tsx
172+
<ObjectForm
173+
schema={{
174+
customFields: [
175+
{
176+
name: 'email',
177+
label: 'Email',
178+
type: 'email',
179+
validation: {
180+
pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
181+
message: 'Invalid email format'
182+
}
183+
}
184+
]
185+
}}
186+
/>
187+
```
188+
189+
## 📚 Learn More
190+
191+
- [ObjectForm Documentation](../../packages/plugin-form/README.md)
192+
- [ObjectStack Documentation](https://objectstack.dev)
193+
- [MSW Documentation](https://mswjs.io/)
194+
- [Reference Example](https://github.com/objectstack-ai/spec/tree/main/examples/msw-react-crud)
195+
196+
## 🧪 Test Coverage
197+
198+
### ✅ Working Tests
199+
200+
**MSW Server Integration** (`MSWServer.test.tsx`):
201+
- ✅ MSW server initialization with data
202+
- ✅ Direct driver CRUD operations
203+
- ✅ Data persistence
204+
205+
### 🔨 In Progress
206+
207+
**ObjectForm Unit Tests** (`ObjectFormUnit.test.tsx`):
208+
- ✅ Form rendering with different field types
209+
- ✅ Field type detection
210+
- ⚠️ Form submission (needs adjustment for react-hook-form)
211+
- ⚠️ Callbacks (requires proper event handling)
212+
213+
**ObjectForm Integration** (`ObjectForm.test.tsx`):
214+
- ⚠️ Requires HTTP interception setup in test environment
215+
216+
## 📝 Notes
217+
218+
- The app works perfectly in the browser with MSW worker
219+
- MSW server setup works great for Node.js test environment
220+
- Direct driver access is tested and working
221+
- HTTP interception in tests requires additional configuration with happy-dom
222+
223+
## 📄 License
224+
225+
MIT © ObjectStack Inc.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>MSW ObjectForm Example - ObjectUI</title>
8+
</head>
9+
<body>
10+
<div id="root"></div>
11+
<script type="module" src="/src/main.tsx"></script>
12+
</body>
13+
</html>

0 commit comments

Comments
 (0)