sdd-mcp-server 2.2.1 → 3.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/README.md +92 -33
- package/dist/agents/AgentManager.d.ts +61 -0
- package/dist/agents/AgentManager.js +75 -0
- package/dist/agents/AgentManager.js.map +1 -0
- package/dist/agents/index.d.ts +1 -0
- package/dist/agents/index.js +3 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/cli/install-skills.d.ts +52 -9
- package/dist/cli/install-skills.js +324 -72
- package/dist/cli/install-skills.js.map +1 -1
- package/dist/cli/sdd-mcp-cli.js +0 -0
- package/dist/contexts/ContextManager.d.ts +53 -0
- package/dist/contexts/ContextManager.js +64 -0
- package/dist/contexts/ContextManager.js.map +1 -0
- package/dist/contexts/index.d.ts +1 -0
- package/dist/contexts/index.js +3 -0
- package/dist/contexts/index.js.map +1 -0
- package/dist/hooks/HookLoader.d.ts +67 -0
- package/dist/hooks/HookLoader.js +180 -0
- package/dist/hooks/HookLoader.js.map +1 -0
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/di/container.js +24 -0
- package/dist/infrastructure/di/container.js.map +1 -1
- package/dist/infrastructure/di/types.d.ts +4 -0
- package/dist/infrastructure/di/types.js +5 -0
- package/dist/infrastructure/di/types.js.map +1 -1
- package/dist/rules/RulesManager.d.ts +53 -0
- package/dist/rules/RulesManager.js +62 -0
- package/dist/rules/RulesManager.js.map +1 -0
- package/dist/rules/index.d.ts +1 -0
- package/dist/rules/index.js +3 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/shared/BaseManager.d.ts +130 -0
- package/dist/shared/BaseManager.js +274 -0
- package/dist/shared/BaseManager.js.map +1 -0
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.js +3 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/utils/sddPaths.d.ts +69 -0
- package/dist/utils/sddPaths.js +138 -0
- package/dist/utils/sddPaths.js.map +1 -0
- package/documentGenerator.js +1 -1
- package/mcp-server.js +39 -39
- package/package.json +1 -1
- package/skills/sdd-review/SKILL.md +191 -0
- package/skills/sdd-security-check/SKILL.md +193 -0
- package/skills/sdd-test-gen/SKILL.md +295 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sdd-security-check
|
|
3
|
+
description: Perform OWASP-aligned security audit of code. Checks for common vulnerabilities including injection, authentication flaws, sensitive data exposure, and more. Invoked via /sdd-security-check [file-path or scope].
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SDD Security Check
|
|
7
|
+
|
|
8
|
+
Perform comprehensive security audits aligned with OWASP Top 10 and security best practices. Identify vulnerabilities before they reach production.
|
|
9
|
+
|
|
10
|
+
## Security Philosophy
|
|
11
|
+
|
|
12
|
+
Security is not a feature—it's a requirement. Every code change should be reviewed through a security lens.
|
|
13
|
+
|
|
14
|
+
## OWASP Top 10 Checks (2021)
|
|
15
|
+
|
|
16
|
+
### A01: Broken Access Control
|
|
17
|
+
|
|
18
|
+
Check for:
|
|
19
|
+
- Missing authorization checks on endpoints
|
|
20
|
+
- Insecure Direct Object References (IDOR)
|
|
21
|
+
- Missing function-level access control
|
|
22
|
+
- CORS misconfiguration
|
|
23
|
+
- JWT validation bypass
|
|
24
|
+
|
|
25
|
+
**Pattern**: Ensure every endpoint has explicit authorization checks.
|
|
26
|
+
|
|
27
|
+
### A02: Cryptographic Failures
|
|
28
|
+
|
|
29
|
+
Check for:
|
|
30
|
+
- Sensitive data transmitted without TLS
|
|
31
|
+
- Weak or deprecated algorithms (MD5, SHA1, DES)
|
|
32
|
+
- Hardcoded secrets or API keys
|
|
33
|
+
- Insufficient key length
|
|
34
|
+
- Missing encryption at rest
|
|
35
|
+
|
|
36
|
+
**Pattern**: Use strong algorithms (bcrypt for passwords, AES-256 for data).
|
|
37
|
+
|
|
38
|
+
### A03: Injection
|
|
39
|
+
|
|
40
|
+
Check for:
|
|
41
|
+
- SQL injection (use parameterized queries)
|
|
42
|
+
- NoSQL injection (validate/sanitize inputs)
|
|
43
|
+
- Command injection (use execFile with array args, not string interpolation)
|
|
44
|
+
- LDAP injection
|
|
45
|
+
- Template injection
|
|
46
|
+
|
|
47
|
+
**Pattern**: Never interpolate user input into queries or commands.
|
|
48
|
+
|
|
49
|
+
### A04: Insecure Design
|
|
50
|
+
|
|
51
|
+
Check for:
|
|
52
|
+
- Missing rate limiting
|
|
53
|
+
- No brute force protection
|
|
54
|
+
- Predictable resource IDs
|
|
55
|
+
- Missing threat modeling
|
|
56
|
+
|
|
57
|
+
### A05: Security Misconfiguration
|
|
58
|
+
|
|
59
|
+
Check for:
|
|
60
|
+
- Debug mode in production
|
|
61
|
+
- Default credentials
|
|
62
|
+
- Unnecessary features enabled
|
|
63
|
+
- Missing security headers
|
|
64
|
+
- Verbose error messages in production
|
|
65
|
+
|
|
66
|
+
**Required Headers**: CSP, X-Frame-Options, X-Content-Type-Options, HSTS
|
|
67
|
+
|
|
68
|
+
### A06: Vulnerable Components
|
|
69
|
+
|
|
70
|
+
- Check dependencies with `npm audit`
|
|
71
|
+
- Review for known CVEs
|
|
72
|
+
- Verify component versions
|
|
73
|
+
|
|
74
|
+
### A07: Authentication Failures
|
|
75
|
+
|
|
76
|
+
Check for:
|
|
77
|
+
- Weak password requirements
|
|
78
|
+
- Missing MFA where required
|
|
79
|
+
- Session fixation vulnerabilities
|
|
80
|
+
- Credential stuffing exposure
|
|
81
|
+
- Insecure password recovery
|
|
82
|
+
|
|
83
|
+
**Session Config**: secure=true, httpOnly=true, sameSite='strict'
|
|
84
|
+
|
|
85
|
+
### A08: Software and Data Integrity Failures
|
|
86
|
+
|
|
87
|
+
Check for:
|
|
88
|
+
- Missing integrity verification on downloads
|
|
89
|
+
- Insecure CI/CD pipeline
|
|
90
|
+
- Unsigned code or packages
|
|
91
|
+
- Auto-update without verification
|
|
92
|
+
|
|
93
|
+
### A09: Security Logging and Monitoring Failures
|
|
94
|
+
|
|
95
|
+
Check for:
|
|
96
|
+
- No logging of security events
|
|
97
|
+
- Sensitive data in logs (never log passwords!)
|
|
98
|
+
- Missing audit trail
|
|
99
|
+
- Logs not protected from tampering
|
|
100
|
+
|
|
101
|
+
**Required Events**: Auth attempts, auth failures, admin actions, data access anomalies
|
|
102
|
+
|
|
103
|
+
### A10: Server-Side Request Forgery (SSRF)
|
|
104
|
+
|
|
105
|
+
Check for:
|
|
106
|
+
- User-controlled URLs in server requests
|
|
107
|
+
- Missing URL validation
|
|
108
|
+
- Internal network access possible
|
|
109
|
+
|
|
110
|
+
**Pattern**: Use URL allowlists for server-side requests.
|
|
111
|
+
|
|
112
|
+
## Security Check Workflow
|
|
113
|
+
|
|
114
|
+
### Step 1: Define Scope
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
/sdd-security-check src/api/ # Check API layer
|
|
118
|
+
/sdd-security-check src/auth/ # Focus on authentication
|
|
119
|
+
/sdd-security-check HEAD~5..HEAD # Check recent changes
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Step 2: Automated Scans
|
|
123
|
+
|
|
124
|
+
Run these checks:
|
|
125
|
+
```bash
|
|
126
|
+
# Dependency vulnerabilities
|
|
127
|
+
npm audit
|
|
128
|
+
|
|
129
|
+
# Secret detection
|
|
130
|
+
npx gitleaks detect
|
|
131
|
+
|
|
132
|
+
# SAST scan if configured
|
|
133
|
+
npx semgrep --config=p/security-audit
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Step 3: Manual Review
|
|
137
|
+
|
|
138
|
+
For each file, check:
|
|
139
|
+
1. Input validation
|
|
140
|
+
2. Output encoding
|
|
141
|
+
3. Authentication/Authorization
|
|
142
|
+
4. Data handling
|
|
143
|
+
5. Error handling
|
|
144
|
+
6. Logging practices
|
|
145
|
+
|
|
146
|
+
### Step 4: Generate Report
|
|
147
|
+
|
|
148
|
+
```markdown
|
|
149
|
+
# Security Audit Report: {scope}
|
|
150
|
+
|
|
151
|
+
## Summary
|
|
152
|
+
- 🔴 Critical: {count}
|
|
153
|
+
- 🟠 High: {count}
|
|
154
|
+
- 🟡 Medium: {count}
|
|
155
|
+
- 🟢 Low: {count}
|
|
156
|
+
|
|
157
|
+
## Critical Findings
|
|
158
|
+
|
|
159
|
+
### SEC-001: {Finding Title}
|
|
160
|
+
**Location**: {file:line}
|
|
161
|
+
**Risk**: Critical
|
|
162
|
+
**OWASP**: {category}
|
|
163
|
+
|
|
164
|
+
**Issue**: {description}
|
|
165
|
+
**Recommendation**: {fix}
|
|
166
|
+
|
|
167
|
+
## Remediation Priority
|
|
168
|
+
1. Critical findings - Fix immediately
|
|
169
|
+
2. High findings - Fix before deployment
|
|
170
|
+
3. Medium findings - Fix this sprint
|
|
171
|
+
4. Low findings - Track and schedule
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Quick Security Checklist
|
|
175
|
+
|
|
176
|
+
Before any deployment:
|
|
177
|
+
- [ ] No hardcoded secrets in code
|
|
178
|
+
- [ ] All inputs validated and sanitized
|
|
179
|
+
- [ ] All outputs properly encoded
|
|
180
|
+
- [ ] Authentication on all protected routes
|
|
181
|
+
- [ ] Authorization checks at function level
|
|
182
|
+
- [ ] Security headers configured
|
|
183
|
+
- [ ] Dependencies scanned for vulnerabilities
|
|
184
|
+
- [ ] Error messages don't leak sensitive info
|
|
185
|
+
- [ ] Security events are logged
|
|
186
|
+
- [ ] Rate limiting in place
|
|
187
|
+
|
|
188
|
+
## Integration with SDD Workflow
|
|
189
|
+
|
|
190
|
+
When checking implementation against spec:
|
|
191
|
+
1. Verify security NFRs from requirements.md are met
|
|
192
|
+
2. Check security considerations from design.md are implemented
|
|
193
|
+
3. Ensure security-related tasks in tasks.md are complete
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sdd-test-gen
|
|
3
|
+
description: Generate comprehensive tests following TDD methodology. Creates unit tests, integration tests, and edge case coverage. Works with existing test frameworks in the project. Invoked via /sdd-test-gen [file-path or function-name].
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# SDD Test Generation
|
|
7
|
+
|
|
8
|
+
Generate comprehensive tests following Test-Driven Development (TDD) methodology. Write tests that serve as living documentation and ensure code correctness.
|
|
9
|
+
|
|
10
|
+
## TDD Philosophy
|
|
11
|
+
|
|
12
|
+
> "Write a failing test before you write the code to make it pass."
|
|
13
|
+
|
|
14
|
+
Tests are not an afterthought—they're a design tool that:
|
|
15
|
+
1. **Document behavior** - Tests show how code is intended to be used
|
|
16
|
+
2. **Prevent regressions** - Catch bugs before they ship
|
|
17
|
+
3. **Enable refactoring** - Change with confidence
|
|
18
|
+
4. **Drive design** - Writing tests first leads to better interfaces
|
|
19
|
+
|
|
20
|
+
## The TDD Cycle
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
┌─────────────────────────────────────┐
|
|
24
|
+
│ │
|
|
25
|
+
│ ┌─────────┐ Write failing test │
|
|
26
|
+
│ │ RED │◄──────────────────────┤
|
|
27
|
+
│ └────┬────┘ │
|
|
28
|
+
│ │ │
|
|
29
|
+
│ ▼ Make it pass │
|
|
30
|
+
│ ┌─────────┐ │
|
|
31
|
+
│ │ GREEN │ │
|
|
32
|
+
│ └────┬────┘ │
|
|
33
|
+
│ │ │
|
|
34
|
+
│ ▼ Improve code │
|
|
35
|
+
│ ┌─────────┐ │
|
|
36
|
+
│ │REFACTOR │───────────────────────┘
|
|
37
|
+
│ └─────────┘
|
|
38
|
+
└─────────────────────────────────────┘
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Workflow
|
|
42
|
+
|
|
43
|
+
### Step 1: Identify Test Scope
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
/sdd-test-gen src/services/UserService.ts # Generate tests for file
|
|
47
|
+
/sdd-test-gen UserService.createUser # Generate for specific method
|
|
48
|
+
/sdd-test-gen src/services/ --integration # Integration tests for module
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Step 2: Analyze the Code
|
|
52
|
+
|
|
53
|
+
Before generating tests:
|
|
54
|
+
1. Read the source file to understand its behavior
|
|
55
|
+
2. Check existing tests (if any) to avoid duplication
|
|
56
|
+
3. Review related requirements in `.spec/specs/`
|
|
57
|
+
4. Identify dependencies that need mocking
|
|
58
|
+
|
|
59
|
+
### Step 3: Test File Structure
|
|
60
|
+
|
|
61
|
+
Generate tests with this structure:
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { UserService } from '../UserService';
|
|
65
|
+
import { UserRepository } from '../../repositories/UserRepository';
|
|
66
|
+
import { EmailService } from '../../services/EmailService';
|
|
67
|
+
|
|
68
|
+
// Mock dependencies
|
|
69
|
+
jest.mock('../../repositories/UserRepository');
|
|
70
|
+
jest.mock('../../services/EmailService');
|
|
71
|
+
|
|
72
|
+
describe('UserService', () => {
|
|
73
|
+
let userService: UserService;
|
|
74
|
+
let mockUserRepo: jest.Mocked<UserRepository>;
|
|
75
|
+
let mockEmailService: jest.Mocked<EmailService>;
|
|
76
|
+
|
|
77
|
+
beforeEach(() => {
|
|
78
|
+
jest.clearAllMocks();
|
|
79
|
+
mockUserRepo = new UserRepository() as jest.Mocked<UserRepository>;
|
|
80
|
+
mockEmailService = new EmailService() as jest.Mocked<EmailService>;
|
|
81
|
+
userService = new UserService(mockUserRepo, mockEmailService);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
describe('createUser', () => {
|
|
85
|
+
it('should create a user with valid input', async () => {
|
|
86
|
+
// Arrange
|
|
87
|
+
const input = { email: 'test@example.com', name: 'Test User' };
|
|
88
|
+
mockUserRepo.save.mockResolvedValue({ id: '1', ...input });
|
|
89
|
+
|
|
90
|
+
// Act
|
|
91
|
+
const result = await userService.createUser(input);
|
|
92
|
+
|
|
93
|
+
// Assert
|
|
94
|
+
expect(result.id).toBeDefined();
|
|
95
|
+
expect(mockUserRepo.save).toHaveBeenCalledWith(expect.objectContaining(input));
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('should throw error when email already exists', async () => {
|
|
99
|
+
// Arrange
|
|
100
|
+
mockUserRepo.findByEmail.mockResolvedValue({ id: '1', email: 'test@example.com' });
|
|
101
|
+
|
|
102
|
+
// Act & Assert
|
|
103
|
+
await expect(userService.createUser({ email: 'test@example.com' }))
|
|
104
|
+
.rejects.toThrow('Email already exists');
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Step 4: Test Categories to Generate
|
|
111
|
+
|
|
112
|
+
#### Unit Tests
|
|
113
|
+
|
|
114
|
+
Test individual functions in isolation:
|
|
115
|
+
- Mock all external dependencies
|
|
116
|
+
- Test one behavior per test
|
|
117
|
+
- Use descriptive test names
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
describe('calculateTotal', () => {
|
|
121
|
+
it('should sum all item prices', () => { ... });
|
|
122
|
+
it('should apply discount when provided', () => { ... });
|
|
123
|
+
it('should handle empty cart', () => { ... });
|
|
124
|
+
it('should throw error for negative quantities', () => { ... });
|
|
125
|
+
});
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
#### Edge Case Tests
|
|
129
|
+
|
|
130
|
+
Always test:
|
|
131
|
+
- Null/undefined inputs
|
|
132
|
+
- Empty arrays/objects
|
|
133
|
+
- Boundary values (0, -1, MAX_INT)
|
|
134
|
+
- Invalid types
|
|
135
|
+
- Concurrent access (if applicable)
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
describe('edge cases', () => {
|
|
139
|
+
it('should handle null input gracefully', () => { ... });
|
|
140
|
+
it('should handle empty array', () => { ... });
|
|
141
|
+
it('should handle maximum allowed length', () => { ... });
|
|
142
|
+
it('should reject invalid email format', () => { ... });
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
#### Error Handling Tests
|
|
147
|
+
|
|
148
|
+
Verify error paths:
|
|
149
|
+
```typescript
|
|
150
|
+
describe('error handling', () => {
|
|
151
|
+
it('should throw ValidationError for invalid input', async () => {
|
|
152
|
+
await expect(service.create({})).rejects.toThrow(ValidationError);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it('should propagate database errors', async () => {
|
|
156
|
+
mockRepo.save.mockRejectedValue(new DatabaseError('Connection failed'));
|
|
157
|
+
await expect(service.create(validInput)).rejects.toThrow(DatabaseError);
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
#### Integration Tests (when requested)
|
|
163
|
+
|
|
164
|
+
Test component interactions:
|
|
165
|
+
```typescript
|
|
166
|
+
describe('UserService integration', () => {
|
|
167
|
+
let app: Express;
|
|
168
|
+
let db: Database;
|
|
169
|
+
|
|
170
|
+
beforeAll(async () => {
|
|
171
|
+
db = await createTestDatabase();
|
|
172
|
+
app = createApp({ database: db });
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
afterAll(async () => {
|
|
176
|
+
await db.close();
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it('should create user and send welcome email', async () => {
|
|
180
|
+
const response = await request(app)
|
|
181
|
+
.post('/api/users')
|
|
182
|
+
.send({ email: 'test@example.com', name: 'Test' });
|
|
183
|
+
|
|
184
|
+
expect(response.status).toBe(201);
|
|
185
|
+
// Verify email was queued
|
|
186
|
+
expect(await getEmailQueue()).toContainEqual(
|
|
187
|
+
expect.objectContaining({ to: 'test@example.com' })
|
|
188
|
+
);
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Step 5: Test Naming Convention
|
|
194
|
+
|
|
195
|
+
Use the pattern: `should [expected behavior] when [condition]`
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
// Good
|
|
199
|
+
it('should return empty array when no users match criteria', () => {});
|
|
200
|
+
it('should throw AuthError when token is expired', () => {});
|
|
201
|
+
it('should create user and return ID when input is valid', () => {});
|
|
202
|
+
|
|
203
|
+
// Bad
|
|
204
|
+
it('test createUser', () => {});
|
|
205
|
+
it('works correctly', () => {});
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Test Quality Checklist
|
|
209
|
+
|
|
210
|
+
For each generated test:
|
|
211
|
+
- [ ] Test name describes behavior, not implementation
|
|
212
|
+
- [ ] Arrange-Act-Assert pattern used
|
|
213
|
+
- [ ] Only one assertion concept per test
|
|
214
|
+
- [ ] Tests are independent (no shared state)
|
|
215
|
+
- [ ] Mocks are minimal (only external deps)
|
|
216
|
+
- [ ] Edge cases covered
|
|
217
|
+
- [ ] Error paths tested
|
|
218
|
+
- [ ] Async tests properly awaited
|
|
219
|
+
|
|
220
|
+
## Integration with SDD Workflow
|
|
221
|
+
|
|
222
|
+
When generating tests for a spec:
|
|
223
|
+
1. Read requirements from `.spec/specs/{feature}/requirements.md`
|
|
224
|
+
2. Map each acceptance criterion to test cases
|
|
225
|
+
3. Check design.md for expected interfaces
|
|
226
|
+
4. Reference tasks.md for implementation details
|
|
227
|
+
|
|
228
|
+
## Test Generation Prompt
|
|
229
|
+
|
|
230
|
+
When running `/sdd-test-gen`:
|
|
231
|
+
|
|
232
|
+
```markdown
|
|
233
|
+
## Test Generation Summary
|
|
234
|
+
|
|
235
|
+
### Target: {file/function}
|
|
236
|
+
|
|
237
|
+
### Tests Generated:
|
|
238
|
+
- **Unit Tests**: {count}
|
|
239
|
+
- **Edge Cases**: {count}
|
|
240
|
+
- **Error Handling**: {count}
|
|
241
|
+
- **Integration**: {count} (if requested)
|
|
242
|
+
|
|
243
|
+
### Coverage Targets:
|
|
244
|
+
- Statements: 80%+
|
|
245
|
+
- Branches: 75%+
|
|
246
|
+
- Functions: 90%+
|
|
247
|
+
- Lines: 80%+
|
|
248
|
+
|
|
249
|
+
### Files Created:
|
|
250
|
+
- `src/__tests__/unit/{file}.test.ts`
|
|
251
|
+
- `src/__tests__/integration/{file}.integration.test.ts` (if requested)
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Framework Detection
|
|
255
|
+
|
|
256
|
+
Automatically detect and use project's test framework:
|
|
257
|
+
- **Jest** (default for TypeScript/JavaScript)
|
|
258
|
+
- **Vitest** (if vite.config.ts present)
|
|
259
|
+
- **Mocha/Chai** (if mocha in dependencies)
|
|
260
|
+
- **Pytest** (for Python projects)
|
|
261
|
+
|
|
262
|
+
## Example Output
|
|
263
|
+
|
|
264
|
+
For input: `/sdd-test-gen src/services/AuthService.ts`
|
|
265
|
+
|
|
266
|
+
```typescript
|
|
267
|
+
import { AuthService } from '../AuthService';
|
|
268
|
+
import { TokenService } from '../../utils/TokenService';
|
|
269
|
+
import { UserRepository } from '../../repositories/UserRepository';
|
|
270
|
+
|
|
271
|
+
jest.mock('../../utils/TokenService');
|
|
272
|
+
jest.mock('../../repositories/UserRepository');
|
|
273
|
+
|
|
274
|
+
describe('AuthService', () => {
|
|
275
|
+
// ... setup ...
|
|
276
|
+
|
|
277
|
+
describe('login', () => {
|
|
278
|
+
it('should return token when credentials are valid', async () => { ... });
|
|
279
|
+
it('should throw AuthError when user not found', async () => { ... });
|
|
280
|
+
it('should throw AuthError when password is incorrect', async () => { ... });
|
|
281
|
+
it('should increment failed login count on failure', async () => { ... });
|
|
282
|
+
it('should lock account after 5 failed attempts', async () => { ... });
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
describe('logout', () => {
|
|
286
|
+
it('should invalidate token when called', async () => { ... });
|
|
287
|
+
it('should handle already-logged-out user gracefully', async () => { ... });
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
describe('refreshToken', () => {
|
|
291
|
+
it('should return new token when refresh token is valid', async () => { ... });
|
|
292
|
+
it('should throw AuthError when refresh token is expired', async () => { ... });
|
|
293
|
+
});
|
|
294
|
+
});
|
|
295
|
+
```
|