@cloudstreamsoftware/claude-tools 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 (189) hide show
  1. package/README.md +152 -37
  2. package/agents/INDEX.md +183 -0
  3. package/agents/architect.md +247 -0
  4. package/agents/build-error-resolver.md +555 -0
  5. package/agents/catalyst-deployer.md +132 -0
  6. package/agents/code-reviewer.md +121 -0
  7. package/agents/compliance-auditor.md +148 -0
  8. package/agents/creator-architect.md +395 -0
  9. package/agents/deluge-reviewer.md +98 -0
  10. package/agents/doc-updater.md +471 -0
  11. package/agents/e2e-runner.md +711 -0
  12. package/agents/planner.md +122 -0
  13. package/agents/refactor-cleaner.md +309 -0
  14. package/agents/security-reviewer.md +582 -0
  15. package/agents/tdd-guide.md +302 -0
  16. package/config/versions.json +63 -0
  17. package/dist/hooks/hooks.json +209 -0
  18. package/dist/index.js +47 -0
  19. package/dist/lib/asset-value.js +609 -0
  20. package/dist/lib/client-manager.js +300 -0
  21. package/dist/lib/command-matcher.js +242 -0
  22. package/dist/lib/cross-session-patterns.js +754 -0
  23. package/dist/lib/intent-classifier.js +1075 -0
  24. package/dist/lib/package-manager.js +374 -0
  25. package/dist/lib/recommendation-engine.js +597 -0
  26. package/dist/lib/session-memory.js +489 -0
  27. package/dist/lib/skill-effectiveness.js +486 -0
  28. package/dist/lib/skill-matcher.js +595 -0
  29. package/dist/lib/tutorial-metrics.js +242 -0
  30. package/dist/lib/tutorial-progress.js +209 -0
  31. package/dist/lib/tutorial-renderer.js +431 -0
  32. package/dist/lib/utils.js +380 -0
  33. package/dist/lib/verify-formatter.js +143 -0
  34. package/dist/lib/workflow-state.js +249 -0
  35. package/hooks/hooks.json +209 -0
  36. package/package.json +5 -1
  37. package/scripts/aggregate-sessions.js +290 -0
  38. package/scripts/branch-name-validator.js +291 -0
  39. package/scripts/build.js +101 -0
  40. package/scripts/commands/client-switch.js +231 -0
  41. package/scripts/deprecate-skill.js +610 -0
  42. package/scripts/diagnose.js +324 -0
  43. package/scripts/doc-freshness.js +168 -0
  44. package/scripts/generate-weekly-digest.js +393 -0
  45. package/scripts/health-check.js +270 -0
  46. package/scripts/hooks/credential-check.js +101 -0
  47. package/scripts/hooks/evaluate-session.js +81 -0
  48. package/scripts/hooks/pre-compact.js +66 -0
  49. package/scripts/hooks/prompt-analyzer.js +276 -0
  50. package/scripts/hooks/prompt-router.js +422 -0
  51. package/scripts/hooks/quality-gate-enforcer.js +371 -0
  52. package/scripts/hooks/session-end.js +156 -0
  53. package/scripts/hooks/session-start.js +195 -0
  54. package/scripts/hooks/skill-injector.js +333 -0
  55. package/scripts/hooks/suggest-compact.js +58 -0
  56. package/scripts/lib/asset-value.js +609 -0
  57. package/scripts/lib/client-manager.js +300 -0
  58. package/scripts/lib/command-matcher.js +242 -0
  59. package/scripts/lib/cross-session-patterns.js +754 -0
  60. package/scripts/lib/intent-classifier.js +1075 -0
  61. package/scripts/lib/package-manager.js +374 -0
  62. package/scripts/lib/recommendation-engine.js +597 -0
  63. package/scripts/lib/session-memory.js +489 -0
  64. package/scripts/lib/skill-effectiveness.js +486 -0
  65. package/scripts/lib/skill-matcher.js +595 -0
  66. package/scripts/lib/tutorial-metrics.js +242 -0
  67. package/scripts/lib/tutorial-progress.js +209 -0
  68. package/scripts/lib/tutorial-renderer.js +431 -0
  69. package/scripts/lib/utils.js +380 -0
  70. package/scripts/lib/verify-formatter.js +143 -0
  71. package/scripts/lib/workflow-state.js +249 -0
  72. package/scripts/onboard.js +363 -0
  73. package/scripts/quarterly-report.js +692 -0
  74. package/scripts/setup-package-manager.js +204 -0
  75. package/scripts/sync-upstream.js +391 -0
  76. package/scripts/test.js +108 -0
  77. package/scripts/tutorial-runner.js +351 -0
  78. package/scripts/validate-all.js +201 -0
  79. package/scripts/verifiers/agents.js +245 -0
  80. package/scripts/verifiers/config.js +186 -0
  81. package/scripts/verifiers/environment.js +123 -0
  82. package/scripts/verifiers/hooks.js +188 -0
  83. package/scripts/verifiers/index.js +38 -0
  84. package/scripts/verifiers/persistence.js +140 -0
  85. package/scripts/verifiers/plugin.js +215 -0
  86. package/scripts/verifiers/skills.js +209 -0
  87. package/scripts/verify-setup.js +164 -0
  88. package/skills/INDEX.md +157 -0
  89. package/skills/backend-patterns/SKILL.md +586 -0
  90. package/skills/backend-patterns/catalyst-patterns.md +128 -0
  91. package/skills/bigquery-patterns/SKILL.md +27 -0
  92. package/skills/bigquery-patterns/performance-optimization.md +518 -0
  93. package/skills/bigquery-patterns/query-patterns.md +372 -0
  94. package/skills/bigquery-patterns/schema-design.md +78 -0
  95. package/skills/cloudstream-project-template/SKILL.md +20 -0
  96. package/skills/cloudstream-project-template/structure.md +65 -0
  97. package/skills/coding-standards/SKILL.md +524 -0
  98. package/skills/coding-standards/deluge-standards.md +83 -0
  99. package/skills/compliance-patterns/SKILL.md +28 -0
  100. package/skills/compliance-patterns/hipaa/audit-requirements.md +251 -0
  101. package/skills/compliance-patterns/hipaa/baa-process.md +298 -0
  102. package/skills/compliance-patterns/hipaa/data-archival-strategy.md +387 -0
  103. package/skills/compliance-patterns/hipaa/phi-handling.md +52 -0
  104. package/skills/compliance-patterns/pci-dss/saq-a-requirements.md +307 -0
  105. package/skills/compliance-patterns/pci-dss/tokenization-patterns.md +382 -0
  106. package/skills/compliance-patterns/pci-dss/zoho-checkout-patterns.md +56 -0
  107. package/skills/compliance-patterns/soc2/access-controls.md +344 -0
  108. package/skills/compliance-patterns/soc2/audit-logging.md +458 -0
  109. package/skills/compliance-patterns/soc2/change-management.md +403 -0
  110. package/skills/compliance-patterns/soc2/deluge-execution-logging.md +407 -0
  111. package/skills/consultancy-workflows/SKILL.md +19 -0
  112. package/skills/consultancy-workflows/client-isolation.md +21 -0
  113. package/skills/consultancy-workflows/documentation-automation.md +454 -0
  114. package/skills/consultancy-workflows/handoff-procedures.md +257 -0
  115. package/skills/consultancy-workflows/knowledge-capture.md +513 -0
  116. package/skills/consultancy-workflows/time-tracking.md +26 -0
  117. package/skills/continuous-learning/SKILL.md +84 -0
  118. package/skills/continuous-learning/config.json +18 -0
  119. package/skills/continuous-learning/evaluate-session.sh +60 -0
  120. package/skills/continuous-learning-v2/SKILL.md +126 -0
  121. package/skills/continuous-learning-v2/config.json +61 -0
  122. package/skills/frontend-patterns/SKILL.md +635 -0
  123. package/skills/frontend-patterns/zoho-widget-patterns.md +103 -0
  124. package/skills/gcp-data-engineering/SKILL.md +36 -0
  125. package/skills/gcp-data-engineering/bigquery/performance-optimization.md +337 -0
  126. package/skills/gcp-data-engineering/dataflow/error-handling.md +496 -0
  127. package/skills/gcp-data-engineering/dataflow/pipeline-patterns.md +444 -0
  128. package/skills/gcp-data-engineering/dbt/model-organization.md +63 -0
  129. package/skills/gcp-data-engineering/dbt/testing-patterns.md +503 -0
  130. package/skills/gcp-data-engineering/medallion-architecture/bronze-layer.md +60 -0
  131. package/skills/gcp-data-engineering/medallion-architecture/gold-layer.md +311 -0
  132. package/skills/gcp-data-engineering/medallion-architecture/layer-transitions.md +517 -0
  133. package/skills/gcp-data-engineering/medallion-architecture/silver-layer.md +305 -0
  134. package/skills/gcp-data-engineering/zoho-to-gcp/data-extraction.md +543 -0
  135. package/skills/gcp-data-engineering/zoho-to-gcp/real-time-vs-batch.md +337 -0
  136. package/skills/security-review/SKILL.md +498 -0
  137. package/skills/security-review/compliance-checklist.md +53 -0
  138. package/skills/strategic-compact/SKILL.md +67 -0
  139. package/skills/tdd-workflow/SKILL.md +413 -0
  140. package/skills/tdd-workflow/zoho-testing.md +124 -0
  141. package/skills/tutorial/SKILL.md +249 -0
  142. package/skills/tutorial/docs/ACCESSIBILITY.md +169 -0
  143. package/skills/tutorial/lessons/00-philosophy-and-workflow.md +198 -0
  144. package/skills/tutorial/lessons/01-basics.md +81 -0
  145. package/skills/tutorial/lessons/02-training.md +86 -0
  146. package/skills/tutorial/lessons/03-commands.md +109 -0
  147. package/skills/tutorial/lessons/04-workflows.md +115 -0
  148. package/skills/tutorial/lessons/05-compliance.md +116 -0
  149. package/skills/tutorial/lessons/06-zoho.md +121 -0
  150. package/skills/tutorial/lessons/07-hooks-system.md +277 -0
  151. package/skills/tutorial/lessons/08-mcp-servers.md +316 -0
  152. package/skills/tutorial/lessons/09-client-management.md +215 -0
  153. package/skills/tutorial/lessons/10-testing-e2e.md +260 -0
  154. package/skills/tutorial/lessons/11-skills-deep-dive.md +272 -0
  155. package/skills/tutorial/lessons/12-rules-system.md +326 -0
  156. package/skills/tutorial/lessons/13-golden-standard-graduation.md +213 -0
  157. package/skills/tutorial/lessons/14-fork-setup-and-sync.md +312 -0
  158. package/skills/tutorial/lessons/15-living-examples-system.md +221 -0
  159. package/skills/tutorial/tracks/accelerated/README.md +134 -0
  160. package/skills/tutorial/tracks/accelerated/assessment/checkpoint-1.md +161 -0
  161. package/skills/tutorial/tracks/accelerated/assessment/checkpoint-2.md +175 -0
  162. package/skills/tutorial/tracks/accelerated/day-1-core-concepts.md +234 -0
  163. package/skills/tutorial/tracks/accelerated/day-2-essential-commands.md +270 -0
  164. package/skills/tutorial/tracks/accelerated/day-3-workflow-mastery.md +305 -0
  165. package/skills/tutorial/tracks/accelerated/day-4-compliance-zoho.md +304 -0
  166. package/skills/tutorial/tracks/accelerated/day-5-hooks-skills.md +344 -0
  167. package/skills/tutorial/tracks/accelerated/day-6-client-testing.md +386 -0
  168. package/skills/tutorial/tracks/accelerated/day-7-graduation.md +369 -0
  169. package/skills/zoho-patterns/CHANGELOG.md +108 -0
  170. package/skills/zoho-patterns/SKILL.md +446 -0
  171. package/skills/zoho-patterns/analytics/dashboard-patterns.md +352 -0
  172. package/skills/zoho-patterns/analytics/zoho-to-bigquery-pipeline.md +427 -0
  173. package/skills/zoho-patterns/catalyst/appsail-deployment.md +349 -0
  174. package/skills/zoho-patterns/catalyst/context-close-patterns.md +354 -0
  175. package/skills/zoho-patterns/catalyst/cron-batch-processing.md +374 -0
  176. package/skills/zoho-patterns/catalyst/function-patterns.md +439 -0
  177. package/skills/zoho-patterns/creator/form-design.md +304 -0
  178. package/skills/zoho-patterns/creator/publish-api-patterns.md +313 -0
  179. package/skills/zoho-patterns/creator/widget-integration.md +306 -0
  180. package/skills/zoho-patterns/creator/workflow-automation.md +253 -0
  181. package/skills/zoho-patterns/deluge/api-patterns.md +468 -0
  182. package/skills/zoho-patterns/deluge/batch-processing.md +403 -0
  183. package/skills/zoho-patterns/deluge/cross-app-integration.md +356 -0
  184. package/skills/zoho-patterns/deluge/error-handling.md +423 -0
  185. package/skills/zoho-patterns/deluge/syntax-reference.md +65 -0
  186. package/skills/zoho-patterns/integration/cors-proxy-architecture.md +426 -0
  187. package/skills/zoho-patterns/integration/crm-books-native-sync.md +277 -0
  188. package/skills/zoho-patterns/integration/oauth-token-management.md +461 -0
  189. package/skills/zoho-patterns/integration/zoho-flow-patterns.md +334 -0
@@ -0,0 +1,413 @@
1
+ ---
2
+ name: tdd-workflow
3
+ description: Use this skill when writing new features, fixing bugs, or refactoring code. Enforces test-driven development with 80%+ coverage including unit, integration, and E2E tests.
4
+ version: 1.0.0
5
+ status: active
6
+ introduced: 1.0.0
7
+ lastUpdated: 2026-01-25
8
+ ---
9
+
10
+ # Test-Driven Development Workflow
11
+
12
+ This skill ensures all code development follows TDD principles with comprehensive test coverage.
13
+
14
+ ## When to Activate
15
+
16
+ - Writing new features or functionality
17
+ - Fixing bugs or issues
18
+ - Refactoring existing code
19
+ - Adding API endpoints
20
+ - Creating new components
21
+
22
+ ## Core Principles
23
+
24
+ ### 1. Tests BEFORE Code
25
+ ALWAYS write tests first, then implement code to make tests pass.
26
+
27
+ ### 2. Coverage Requirements
28
+ - Minimum 80% coverage (unit + integration + E2E)
29
+ - All edge cases covered
30
+ - Error scenarios tested
31
+ - Boundary conditions verified
32
+
33
+ ### 3. Test Types
34
+
35
+ #### Unit Tests
36
+ - Individual functions and utilities
37
+ - Component logic
38
+ - Pure functions
39
+ - Helpers and utilities
40
+
41
+ #### Integration Tests
42
+ - API endpoints
43
+ - Database operations
44
+ - Service interactions
45
+ - External API calls
46
+
47
+ #### E2E Tests (Playwright)
48
+ - Critical user flows
49
+ - Complete workflows
50
+ - Browser automation
51
+ - UI interactions
52
+
53
+ ## TDD Workflow Steps
54
+
55
+ ### Step 1: Write User Journeys
56
+ ```
57
+ As a [role], I want to [action], so that [benefit]
58
+
59
+ Example:
60
+ As a user, I want to search for markets semantically,
61
+ so that I can find relevant markets even without exact keywords.
62
+ ```
63
+
64
+ ### Step 2: Generate Test Cases
65
+ For each user journey, create comprehensive test cases:
66
+
67
+ ```typescript
68
+ describe('Semantic Search', () => {
69
+ it('returns relevant markets for query', async () => {
70
+ // Test implementation
71
+ })
72
+
73
+ it('handles empty query gracefully', async () => {
74
+ // Test edge case
75
+ })
76
+
77
+ it('falls back to substring search when Redis unavailable', async () => {
78
+ // Test fallback behavior
79
+ })
80
+
81
+ it('sorts results by similarity score', async () => {
82
+ // Test sorting logic
83
+ })
84
+ })
85
+ ```
86
+
87
+ ### Step 3: Run Tests (They Should Fail)
88
+ ```bash
89
+ npm test
90
+ # Tests should fail - we haven't implemented yet
91
+ ```
92
+
93
+ ### Step 4: Implement Code
94
+ Write minimal code to make tests pass:
95
+
96
+ ```typescript
97
+ // Implementation guided by tests
98
+ export async function searchMarkets(query: string) {
99
+ // Implementation here
100
+ }
101
+ ```
102
+
103
+ ### Step 5: Run Tests Again
104
+ ```bash
105
+ npm test
106
+ # Tests should now pass
107
+ ```
108
+
109
+ ### Step 6: Refactor
110
+ Improve code quality while keeping tests green:
111
+ - Remove duplication
112
+ - Improve naming
113
+ - Optimize performance
114
+ - Enhance readability
115
+
116
+ ### Step 7: Verify Coverage
117
+ ```bash
118
+ npm run test:coverage
119
+ # Verify 80%+ coverage achieved
120
+ ```
121
+
122
+ ## Testing Patterns
123
+
124
+ ### Unit Test Pattern (Jest/Vitest)
125
+ ```typescript
126
+ import { render, screen, fireEvent } from '@testing-library/react'
127
+ import { Button } from './Button'
128
+
129
+ describe('Button Component', () => {
130
+ it('renders with correct text', () => {
131
+ render(<Button>Click me</Button>)
132
+ expect(screen.getByText('Click me')).toBeInTheDocument()
133
+ })
134
+
135
+ it('calls onClick when clicked', () => {
136
+ const handleClick = jest.fn()
137
+ render(<Button onClick={handleClick}>Click</Button>)
138
+
139
+ fireEvent.click(screen.getByRole('button'))
140
+
141
+ expect(handleClick).toHaveBeenCalledTimes(1)
142
+ })
143
+
144
+ it('is disabled when disabled prop is true', () => {
145
+ render(<Button disabled>Click</Button>)
146
+ expect(screen.getByRole('button')).toBeDisabled()
147
+ })
148
+ })
149
+ ```
150
+
151
+ ### API Integration Test Pattern
152
+ ```typescript
153
+ import { NextRequest } from 'next/server'
154
+ import { GET } from './route'
155
+
156
+ describe('GET /api/markets', () => {
157
+ it('returns markets successfully', async () => {
158
+ const request = new NextRequest('http://localhost/api/markets')
159
+ const response = await GET(request)
160
+ const data = await response.json()
161
+
162
+ expect(response.status).toBe(200)
163
+ expect(data.success).toBe(true)
164
+ expect(Array.isArray(data.data)).toBe(true)
165
+ })
166
+
167
+ it('validates query parameters', async () => {
168
+ const request = new NextRequest('http://localhost/api/markets?limit=invalid')
169
+ const response = await GET(request)
170
+
171
+ expect(response.status).toBe(400)
172
+ })
173
+
174
+ it('handles database errors gracefully', async () => {
175
+ // Mock database failure
176
+ const request = new NextRequest('http://localhost/api/markets')
177
+ // Test error handling
178
+ })
179
+ })
180
+ ```
181
+
182
+ ### E2E Test Pattern (Playwright)
183
+ ```typescript
184
+ import { test, expect } from '@playwright/test'
185
+
186
+ test('user can search and filter markets', async ({ page }) => {
187
+ // Navigate to markets page
188
+ await page.goto('/')
189
+ await page.click('a[href="/markets"]')
190
+
191
+ // Verify page loaded
192
+ await expect(page.locator('h1')).toContainText('Markets')
193
+
194
+ // Search for markets
195
+ await page.fill('input[placeholder="Search markets"]', 'election')
196
+
197
+ // Wait for debounce and results
198
+ await page.waitForTimeout(600)
199
+
200
+ // Verify search results displayed
201
+ const results = page.locator('[data-testid="market-card"]')
202
+ await expect(results).toHaveCount(5, { timeout: 5000 })
203
+
204
+ // Verify results contain search term
205
+ const firstResult = results.first()
206
+ await expect(firstResult).toContainText('election', { ignoreCase: true })
207
+
208
+ // Filter by status
209
+ await page.click('button:has-text("Active")')
210
+
211
+ // Verify filtered results
212
+ await expect(results).toHaveCount(3)
213
+ })
214
+
215
+ test('user can create a new market', async ({ page }) => {
216
+ // Login first
217
+ await page.goto('/creator-dashboard')
218
+
219
+ // Fill market creation form
220
+ await page.fill('input[name="name"]', 'Test Market')
221
+ await page.fill('textarea[name="description"]', 'Test description')
222
+ await page.fill('input[name="endDate"]', '2025-12-31')
223
+
224
+ // Submit form
225
+ await page.click('button[type="submit"]')
226
+
227
+ // Verify success message
228
+ await expect(page.locator('text=Market created successfully')).toBeVisible()
229
+
230
+ // Verify redirect to market page
231
+ await expect(page).toHaveURL(/\/markets\/test-market/)
232
+ })
233
+ ```
234
+
235
+ ## Test File Organization
236
+
237
+ ```
238
+ src/
239
+ ├── components/
240
+ │ ├── Button/
241
+ │ │ ├── Button.tsx
242
+ │ │ ├── Button.test.tsx # Unit tests
243
+ │ │ └── Button.stories.tsx # Storybook
244
+ │ └── MarketCard/
245
+ │ ├── MarketCard.tsx
246
+ │ └── MarketCard.test.tsx
247
+ ├── app/
248
+ │ └── api/
249
+ │ └── markets/
250
+ │ ├── route.ts
251
+ │ └── route.test.ts # Integration tests
252
+ └── e2e/
253
+ ├── markets.spec.ts # E2E tests
254
+ ├── trading.spec.ts
255
+ └── auth.spec.ts
256
+ ```
257
+
258
+ ## Mocking External Services
259
+
260
+ ### Supabase Mock
261
+ ```typescript
262
+ jest.mock('@/lib/supabase', () => ({
263
+ supabase: {
264
+ from: jest.fn(() => ({
265
+ select: jest.fn(() => ({
266
+ eq: jest.fn(() => Promise.resolve({
267
+ data: [{ id: 1, name: 'Test Market' }],
268
+ error: null
269
+ }))
270
+ }))
271
+ }))
272
+ }
273
+ }))
274
+ ```
275
+
276
+ ### Redis Mock
277
+ ```typescript
278
+ jest.mock('@/lib/redis', () => ({
279
+ searchMarketsByVector: jest.fn(() => Promise.resolve([
280
+ { slug: 'test-market', similarity_score: 0.95 }
281
+ ])),
282
+ checkRedisHealth: jest.fn(() => Promise.resolve({ connected: true }))
283
+ }))
284
+ ```
285
+
286
+ ### OpenAI Mock
287
+ ```typescript
288
+ jest.mock('@/lib/openai', () => ({
289
+ generateEmbedding: jest.fn(() => Promise.resolve(
290
+ new Array(1536).fill(0.1) // Mock 1536-dim embedding
291
+ ))
292
+ }))
293
+ ```
294
+
295
+ ## Test Coverage Verification
296
+
297
+ ### Run Coverage Report
298
+ ```bash
299
+ npm run test:coverage
300
+ ```
301
+
302
+ ### Coverage Thresholds
303
+ ```json
304
+ {
305
+ "jest": {
306
+ "coverageThresholds": {
307
+ "global": {
308
+ "branches": 80,
309
+ "functions": 80,
310
+ "lines": 80,
311
+ "statements": 80
312
+ }
313
+ }
314
+ }
315
+ }
316
+ ```
317
+
318
+ ## Common Testing Mistakes to Avoid
319
+
320
+ ### ❌ WRONG: Testing Implementation Details
321
+ ```typescript
322
+ // Don't test internal state
323
+ expect(component.state.count).toBe(5)
324
+ ```
325
+
326
+ ### ✅ CORRECT: Test User-Visible Behavior
327
+ ```typescript
328
+ // Test what users see
329
+ expect(screen.getByText('Count: 5')).toBeInTheDocument()
330
+ ```
331
+
332
+ ### ❌ WRONG: Brittle Selectors
333
+ ```typescript
334
+ // Breaks easily
335
+ await page.click('.css-class-xyz')
336
+ ```
337
+
338
+ ### ✅ CORRECT: Semantic Selectors
339
+ ```typescript
340
+ // Resilient to changes
341
+ await page.click('button:has-text("Submit")')
342
+ await page.click('[data-testid="submit-button"]')
343
+ ```
344
+
345
+ ### ❌ WRONG: No Test Isolation
346
+ ```typescript
347
+ // Tests depend on each other
348
+ test('creates user', () => { /* ... */ })
349
+ test('updates same user', () => { /* depends on previous test */ })
350
+ ```
351
+
352
+ ### ✅ CORRECT: Independent Tests
353
+ ```typescript
354
+ // Each test sets up its own data
355
+ test('creates user', () => {
356
+ const user = createTestUser()
357
+ // Test logic
358
+ })
359
+
360
+ test('updates user', () => {
361
+ const user = createTestUser()
362
+ // Update logic
363
+ })
364
+ ```
365
+
366
+ ## Continuous Testing
367
+
368
+ ### Watch Mode During Development
369
+ ```bash
370
+ npm test -- --watch
371
+ # Tests run automatically on file changes
372
+ ```
373
+
374
+ ### Pre-Commit Hook
375
+ ```bash
376
+ # Runs before every commit
377
+ npm test && npm run lint
378
+ ```
379
+
380
+ ### CI/CD Integration
381
+ ```yaml
382
+ # GitHub Actions
383
+ - name: Run Tests
384
+ run: npm test -- --coverage
385
+ - name: Upload Coverage
386
+ uses: codecov/codecov-action@v3
387
+ ```
388
+
389
+ ## Best Practices
390
+
391
+ 1. **Write Tests First** - Always TDD
392
+ 2. **One Assert Per Test** - Focus on single behavior
393
+ 3. **Descriptive Test Names** - Explain what's tested
394
+ 4. **Arrange-Act-Assert** - Clear test structure
395
+ 5. **Mock External Dependencies** - Isolate unit tests
396
+ 6. **Test Edge Cases** - Null, undefined, empty, large
397
+ 7. **Test Error Paths** - Not just happy paths
398
+ 8. **Keep Tests Fast** - Unit tests < 50ms each
399
+ 9. **Clean Up After Tests** - No side effects
400
+ 10. **Review Coverage Reports** - Identify gaps
401
+
402
+ ## Success Metrics
403
+
404
+ - 80%+ code coverage achieved
405
+ - All tests passing (green)
406
+ - No skipped or disabled tests
407
+ - Fast test execution (< 30s for unit tests)
408
+ - E2E tests cover critical user flows
409
+ - Tests catch bugs before production
410
+
411
+ ---
412
+
413
+ **Remember**: Tests are not optional. They are the safety net that enables confident refactoring, rapid development, and production reliability.
@@ -0,0 +1,124 @@
1
+ # Zoho Testing Patterns
2
+
3
+ ## Widget Unit Testing (Vitest/Jest)
4
+
5
+ ### Setup: Mock ZOHO SDK
6
+ ```javascript
7
+ // tests/setup.js
8
+ global.ZOHO = {
9
+ CREATOR: {
10
+ init: jest.fn().mockResolvedValue(true),
11
+ API: {
12
+ getAllRecords: jest.fn(),
13
+ addRecord: jest.fn(),
14
+ updateRecord: jest.fn(),
15
+ deleteRecord: jest.fn(),
16
+ setFieldValue: jest.fn(),
17
+ onFormSubmit: jest.fn()
18
+ }
19
+ }
20
+ };
21
+ ```
22
+
23
+ ### Widget Component Test
24
+ ```javascript
25
+ import { render, screen, waitFor } from '@testing-library/react';
26
+ import ZohoWidget from '../src/ZohoWidget';
27
+
28
+ describe('ZohoWidget', () => {
29
+ beforeEach(() => {
30
+ ZOHO.CREATOR.init.mockResolvedValue(true);
31
+ });
32
+
33
+ it('initializes SDK and renders content', async () => {
34
+ render(<ZohoWidget />);
35
+
36
+ await waitFor(() => {
37
+ expect(ZOHO.CREATOR.init).toHaveBeenCalled();
38
+ expect(screen.queryByText('Loading...')).not.toBeInTheDocument();
39
+ });
40
+ });
41
+ });
42
+ ```
43
+
44
+ ## Catalyst Function Testing
45
+
46
+ ### Mock Context Object
47
+ ```javascript
48
+ const mockContext = {
49
+ close: jest.fn(),
50
+ environment: 'development',
51
+ catalystApp: { id: 'test-app' }
52
+ };
53
+
54
+ const mockBasicIO = {
55
+ getArgument: jest.fn(),
56
+ write: jest.fn()
57
+ };
58
+ ```
59
+
60
+ ### Function Test
61
+ ```javascript
62
+ const handler = require('../functions/myFunction');
63
+
64
+ describe('myFunction', () => {
65
+ beforeEach(() => {
66
+ jest.clearAllMocks();
67
+ });
68
+
69
+ it('processes valid input', async () => {
70
+ mockBasicIO.getArgument.mockReturnValue(JSON.stringify({ id: '123' }));
71
+
72
+ await handler(mockContext, mockBasicIO);
73
+
74
+ expect(mockBasicIO.write).toHaveBeenCalledWith(
75
+ expect.stringContaining('"status":"success"')
76
+ );
77
+ expect(mockContext.close).toHaveBeenCalled(); // ALWAYS verify this
78
+ });
79
+
80
+ it('handles errors gracefully', async () => {
81
+ mockBasicIO.getArgument.mockReturnValue('invalid json');
82
+
83
+ await handler(mockContext, mockBasicIO);
84
+
85
+ expect(mockBasicIO.write).toHaveBeenCalledWith(
86
+ expect.stringContaining('"status":"error"')
87
+ );
88
+ expect(mockContext.close).toHaveBeenCalled(); // Even on error
89
+ });
90
+ });
91
+ ```
92
+
93
+ ## Deluge Testing Checklist (No Unit Framework)
94
+
95
+ Since Deluge has no unit testing framework, use this manual checklist:
96
+
97
+ - [ ] Test with null input values
98
+ - [ ] Test with empty strings
99
+ - [ ] Test with maximum-length strings
100
+ - [ ] Test pagination (> 200 records)
101
+ - [ ] Test invokeUrl timeout handling
102
+ - [ ] Test with invalid connection names
103
+ - [ ] Verify statement count stays under 5000
104
+ - [ ] Test error response format
105
+ - [ ] Verify audit logging fires correctly
106
+ - [ ] Test with concurrent executions (if applicable)
107
+
108
+ ## Integration Testing (Playwright)
109
+
110
+ For standalone widgets (not Zoho-embedded):
111
+ ```javascript
112
+ import { test, expect } from '@playwright/test';
113
+
114
+ test('widget loads and displays data', async ({ page }) => {
115
+ await page.goto('http://localhost:3000');
116
+
117
+ // Wait for widget initialization
118
+ await page.waitForSelector('[data-testid="widget-loaded"]');
119
+
120
+ // Verify data display
121
+ const records = await page.locator('.record-item').count();
122
+ expect(records).toBeGreaterThan(0);
123
+ });
124
+ ```