@silverassist/agents-toolkit 2.0.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/LICENSE +135 -0
- package/README.md +388 -0
- package/bin/cli.js +940 -0
- package/package.json +52 -0
- package/src/index.js +58 -0
- package/templates/agents/AGENTS.codex.md +195 -0
- package/templates/agents/AGENTS.md +195 -0
- package/templates/agents/CLAUDE.md +213 -0
- package/templates/agents/copilot-instructions.md +83 -0
- package/templates/shared/instructions/css-styling.instructions.md +142 -0
- package/templates/shared/instructions/documentation-language.instructions.md +216 -0
- package/templates/shared/instructions/github-workflow.instructions.md +245 -0
- package/templates/shared/instructions/php-standards.instructions.md +293 -0
- package/templates/shared/instructions/react-components.instructions.md +196 -0
- package/templates/shared/instructions/server-actions.instructions.md +429 -0
- package/templates/shared/instructions/testing-standards.instructions.md +264 -0
- package/templates/shared/instructions/tests.instructions.md +103 -0
- package/templates/shared/instructions/typescript.instructions.md +106 -0
- package/templates/shared/instructions/wordpress-plugin-architecture.instructions.md +238 -0
- package/templates/shared/prompts/README.md +129 -0
- package/templates/shared/prompts/_partials/README.md +57 -0
- package/templates/shared/prompts/_partials/documentation.md +203 -0
- package/templates/shared/prompts/_partials/git-operations.md +171 -0
- package/templates/shared/prompts/_partials/github-integration.md +100 -0
- package/templates/shared/prompts/_partials/jira-integration.md +155 -0
- package/templates/shared/prompts/_partials/pr-template.md +216 -0
- package/templates/shared/prompts/_partials/validations.md +87 -0
- package/templates/shared/prompts/add-tests.prompt.md +151 -0
- package/templates/shared/prompts/analyze-github-issue.prompt.md +73 -0
- package/templates/shared/prompts/analyze-ticket.prompt.md +63 -0
- package/templates/shared/prompts/create-plan.prompt.md +118 -0
- package/templates/shared/prompts/create-pr.prompt.md +139 -0
- package/templates/shared/prompts/finalize-pr.prompt.md +150 -0
- package/templates/shared/prompts/fix-issues.prompt.md +92 -0
- package/templates/shared/prompts/new-wp-component.prompt.md +51 -0
- package/templates/shared/prompts/new-wp-plugin.prompt.md +46 -0
- package/templates/shared/prompts/prepare-pr.prompt.md +123 -0
- package/templates/shared/prompts/prepare-release.prompt.md +74 -0
- package/templates/shared/prompts/quality-check.prompt.md +45 -0
- package/templates/shared/prompts/review-code.prompt.md +81 -0
- package/templates/shared/prompts/work-github-issue.prompt.md +96 -0
- package/templates/shared/prompts/work-ticket.prompt.md +98 -0
- package/templates/shared/skills/README.md +53 -0
- package/templates/shared/skills/component-architecture/SKILL.md +321 -0
- package/templates/shared/skills/create-component/SKILL.md +714 -0
- package/templates/shared/skills/domain-driven-design/SKILL.md +277 -0
- package/templates/shared/skills/plugin-creation/SKILL.md +1094 -0
- package/templates/shared/skills/quality-checks/SKILL.md +493 -0
- package/templates/shared/skills/release-management/SKILL.md +649 -0
- package/templates/shared/skills/testing/SKILL.md +682 -0
- package/templates/shared/skills/testing-patterns/SKILL.md +243 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: testing-patterns
|
|
3
|
+
description: Guide for writing tests with Jest and React Testing Library. Use this when creating tests, debugging test failures, or implementing test patterns for Server Actions and Next.js 15.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Testing Patterns Skill
|
|
7
|
+
|
|
8
|
+
When writing tests in this project, follow these patterns specific to Next.js 15 and React 19.
|
|
9
|
+
|
|
10
|
+
## Critical Next.js 15 Testing Constraints
|
|
11
|
+
|
|
12
|
+
### ❌ Async Server Components - NOT Fully Supported
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
// ❌ CANNOT test async Server Components with Jest
|
|
16
|
+
export default async function ServerComponent() {
|
|
17
|
+
const data = await fetch('https://api.example.com/data');
|
|
18
|
+
return <div>{data.title}</div>;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// ❌ This will fail in Jest
|
|
22
|
+
describe('ServerComponent', () => {
|
|
23
|
+
it('should render', async () => {
|
|
24
|
+
const { container } = render(await ServerComponent()); // Error!
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// ✅ Solution: Use E2E tests (Playwright) for async components
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### ❌ API Routes - Avoid Testing in Jest
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
// ❌ Web API compatibility issues
|
|
35
|
+
import { POST } from '@/app/api/webhook/route';
|
|
36
|
+
|
|
37
|
+
describe('Webhook', () => {
|
|
38
|
+
it('should process', async () => {
|
|
39
|
+
const request = new NextRequest(...); // ❌ Error: Request not defined
|
|
40
|
+
await POST(request);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// ✅ Solution: Test Server Actions instead
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Mock Setup Order - CRITICAL
|
|
48
|
+
|
|
49
|
+
### Mocks MUST come BEFORE imports
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
// ✅ CORRECT: Mock first, then import
|
|
53
|
+
const mockStripeCreate = jest.fn();
|
|
54
|
+
|
|
55
|
+
jest.mock('stripe', () => {
|
|
56
|
+
return class MockStripe {
|
|
57
|
+
checkout = {
|
|
58
|
+
sessions: {
|
|
59
|
+
create: (...args: unknown[]) => mockStripeCreate(...args)
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// THEN import
|
|
66
|
+
import { createCheckoutSession } from '@/actions/checkout';
|
|
67
|
+
|
|
68
|
+
// ❌ INCORRECT: Import before mock
|
|
69
|
+
import { createCheckoutSession } from '@/actions/checkout'; // Too early!
|
|
70
|
+
|
|
71
|
+
jest.mock('stripe', () => ({
|
|
72
|
+
// Mock comes too late - already imported
|
|
73
|
+
}));
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Server Action Testing Pattern
|
|
77
|
+
|
|
78
|
+
### Basic Server Action Test
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
// 1. Setup mocks BEFORE imports
|
|
82
|
+
const mockCreateLead = jest.fn();
|
|
83
|
+
jest.mock('@/lib/salesforce', () => ({
|
|
84
|
+
createSalesforceRecord: mockCreateLead,
|
|
85
|
+
}));
|
|
86
|
+
|
|
87
|
+
// 2. Import AFTER mocks
|
|
88
|
+
import { submitWizardToSalesforce } from '@/actions/salesforce-wizard';
|
|
89
|
+
|
|
90
|
+
describe('submitWizardToSalesforce', () => {
|
|
91
|
+
beforeEach(() => {
|
|
92
|
+
jest.clearAllMocks();
|
|
93
|
+
|
|
94
|
+
mockCreateLead.mockResolvedValue({
|
|
95
|
+
id: 'a1B123ABC',
|
|
96
|
+
success: true,
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('should create Salesforce lead', async () => {
|
|
101
|
+
// 3. Create FormData
|
|
102
|
+
const formData = new FormData();
|
|
103
|
+
formData.append('email', 'test@example.com');
|
|
104
|
+
formData.append('firstName', 'John');
|
|
105
|
+
|
|
106
|
+
// 4. Call with prevState (useActionState signature)
|
|
107
|
+
const result = await submitWizardToSalesforce(
|
|
108
|
+
{ success: false, message: '', timestamp: 0 },
|
|
109
|
+
formData
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
// 5. Assert
|
|
113
|
+
expect(result.success).toBe(true);
|
|
114
|
+
expect(result.leadId).toBeDefined();
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### useActionState Signature - CRITICAL
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
// Server Actions for useActionState MUST have this signature:
|
|
123
|
+
export async function action(
|
|
124
|
+
prevState: ActionState, // First param: previous state
|
|
125
|
+
formData: FormData // Second param: form data
|
|
126
|
+
): Promise<ActionState> {
|
|
127
|
+
// Implementation
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// ❌ INCORRECT signature
|
|
131
|
+
export async function action(formData: FormData) { } // Missing prevState!
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Type Safety in Tests
|
|
135
|
+
|
|
136
|
+
### Type Check BEFORE Tests
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
# Type check only (no test execution)
|
|
140
|
+
npm run type-check
|
|
141
|
+
|
|
142
|
+
# Both type check + tests (CI mode)
|
|
143
|
+
npm run test:ci
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## beforeEach Pattern
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
describe('MyTests', () => {
|
|
150
|
+
beforeEach(() => {
|
|
151
|
+
// ✅ ALWAYS clear mocks
|
|
152
|
+
jest.clearAllMocks();
|
|
153
|
+
|
|
154
|
+
// Reset mock implementations
|
|
155
|
+
mockFunction.mockResolvedValue(defaultResponse);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
afterEach(() => {
|
|
159
|
+
jest.restoreAllMocks();
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Integration Testing Pattern
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
// src/__tests__/integration/flow.test.ts
|
|
168
|
+
|
|
169
|
+
// 1. MOCKS SETUP (before imports)
|
|
170
|
+
const mockStripeCreate = jest.fn();
|
|
171
|
+
jest.mock('stripe', () => class MockStripe {
|
|
172
|
+
checkout = { sessions: { create: mockStripeCreate } };
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// 2. IMPORTS (after mocks)
|
|
176
|
+
import { createCheckoutSessionAction } from '@/actions/create-checkout-session';
|
|
177
|
+
|
|
178
|
+
// 3. TEST SUITE
|
|
179
|
+
describe('Payment Flow Integration', () => {
|
|
180
|
+
beforeEach(() => {
|
|
181
|
+
jest.clearAllMocks();
|
|
182
|
+
|
|
183
|
+
mockStripeCreate.mockResolvedValue({
|
|
184
|
+
id: 'cs_test_123',
|
|
185
|
+
url: 'https://checkout.stripe.com/pay/cs_test_123',
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it('should complete full flow', async () => {
|
|
190
|
+
const formData = new FormData();
|
|
191
|
+
formData.append('email', 'test@example.com');
|
|
192
|
+
|
|
193
|
+
const result = await createCheckoutSessionAction(
|
|
194
|
+
{ success: false, url: '', error: '', timestamp: 0 },
|
|
195
|
+
formData
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
expect(result.success).toBe(true);
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Testing Checklist
|
|
204
|
+
|
|
205
|
+
Before committing tests:
|
|
206
|
+
|
|
207
|
+
- [ ] **Mock before import** - All mocks defined before imports
|
|
208
|
+
- [ ] **Clear mocks** - `jest.clearAllMocks()` in `beforeEach`
|
|
209
|
+
- [ ] **Test Server Actions** - Not API routes
|
|
210
|
+
- [ ] **Match actual types** - Assertions match real return types
|
|
211
|
+
- [ ] **Type check passes** - `npm run type-check` succeeds
|
|
212
|
+
- [ ] **All tests pass** - `npm test` succeeds
|
|
213
|
+
|
|
214
|
+
## Quick Commands
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
# Run all tests
|
|
218
|
+
npm test
|
|
219
|
+
|
|
220
|
+
# Run specific test file
|
|
221
|
+
npm test -- payment-flow-integration
|
|
222
|
+
|
|
223
|
+
# Run tests in watch mode
|
|
224
|
+
npm test -- --watch
|
|
225
|
+
|
|
226
|
+
# Type check without tests
|
|
227
|
+
npm run type-check
|
|
228
|
+
|
|
229
|
+
# Both type check and tests
|
|
230
|
+
npm run test:ci
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Common Pitfalls
|
|
234
|
+
|
|
235
|
+
### ❌ Testing Implementation Details
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
// ❌ BAD: Testing internal state
|
|
239
|
+
expect(component.state.isLoading).toBe(true);
|
|
240
|
+
|
|
241
|
+
// ✅ GOOD: Testing user-visible behavior
|
|
242
|
+
expect(screen.getByText('Loading...')).toBeInTheDocument();
|
|
243
|
+
```
|