@aborruso/ckan-mcp-server 0.4.17 → 0.4.18
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/LOG.md +59 -0
- package/README.md +104 -34
- package/dist/index.js +161 -45
- package/dist/worker.js +42 -42
- package/package.json +12 -1
- package/.devin/wiki.json +0 -273
- package/CLAUDE.md +0 -398
- package/PRD.md +0 -999
- package/REFACTORING.md +0 -238
- package/examples/langgraph/01_basic_workflow.py +0 -277
- package/examples/langgraph/02_data_exploration.py +0 -366
- package/examples/langgraph/README.md +0 -719
- package/examples/langgraph/metadata_quality.py +0 -299
- package/examples/langgraph/requirements.txt +0 -12
- package/examples/langgraph/setup.sh +0 -32
- package/examples/langgraph/test_setup.py +0 -106
- package/openspec/AGENTS.md +0 -456
- package/openspec/changes/add-ckan-analyze-dataset-structure/proposal.md +0 -17
- package/openspec/changes/add-ckan-analyze-dataset-structure/specs/ckan-insights/spec.md +0 -7
- package/openspec/changes/add-ckan-analyze-dataset-structure/tasks.md +0 -6
- package/openspec/changes/add-ckan-analyze-dataset-updates/proposal.md +0 -17
- package/openspec/changes/add-ckan-analyze-dataset-updates/specs/ckan-insights/spec.md +0 -7
- package/openspec/changes/add-ckan-analyze-dataset-updates/tasks.md +0 -6
- package/openspec/changes/add-ckan-audit-tool/proposal.md +0 -17
- package/openspec/changes/add-ckan-audit-tool/specs/ckan-insights/spec.md +0 -7
- package/openspec/changes/add-ckan-audit-tool/tasks.md +0 -6
- package/openspec/changes/add-ckan-dataset-insights/proposal.md +0 -17
- package/openspec/changes/add-ckan-dataset-insights/specs/ckan-insights/spec.md +0 -7
- package/openspec/changes/add-ckan-dataset-insights/tasks.md +0 -6
- package/openspec/changes/add-ckan-host-allowlist-env/design.md +0 -38
- package/openspec/changes/add-ckan-host-allowlist-env/proposal.md +0 -16
- package/openspec/changes/add-ckan-host-allowlist-env/specs/ckan-request-allowlist/spec.md +0 -15
- package/openspec/changes/add-ckan-host-allowlist-env/specs/cloudflare-deployment/spec.md +0 -11
- package/openspec/changes/add-ckan-host-allowlist-env/tasks.md +0 -12
- package/openspec/changes/add-escape-text-query/proposal.md +0 -12
- package/openspec/changes/add-escape-text-query/specs/ckan-search/spec.md +0 -11
- package/openspec/changes/add-escape-text-query/tasks.md +0 -8
- package/openspec/changes/add-mqa-quality-tool/proposal.md +0 -21
- package/openspec/changes/add-mqa-quality-tool/specs/ckan-quality/spec.md +0 -71
- package/openspec/changes/add-mqa-quality-tool/tasks.md +0 -29
- package/openspec/changes/archive/2026-01-08-add-mcp-resources/design.md +0 -115
- package/openspec/changes/archive/2026-01-08-add-mcp-resources/proposal.md +0 -52
- package/openspec/changes/archive/2026-01-08-add-mcp-resources/specs/mcp-resources/spec.md +0 -92
- package/openspec/changes/archive/2026-01-08-add-mcp-resources/tasks.md +0 -56
- package/openspec/changes/archive/2026-01-08-expand-test-coverage-specs/design.md +0 -355
- package/openspec/changes/archive/2026-01-08-expand-test-coverage-specs/proposal.md +0 -161
- package/openspec/changes/archive/2026-01-08-expand-test-coverage-specs/tasks.md +0 -162
- package/openspec/changes/archive/2026-01-08-translate-project-to-english/proposal.md +0 -115
- package/openspec/changes/archive/2026-01-08-translate-project-to-english/specs/documentation-language/spec.md +0 -32
- package/openspec/changes/archive/2026-01-08-translate-project-to-english/tasks.md +0 -115
- package/openspec/changes/archive/2026-01-10-add-ckan-find-relevant-datasets/proposal.md +0 -17
- package/openspec/changes/archive/2026-01-10-add-ckan-find-relevant-datasets/specs/ckan-insights/spec.md +0 -7
- package/openspec/changes/archive/2026-01-10-add-ckan-find-relevant-datasets/tasks.md +0 -6
- package/openspec/changes/archive/2026-01-10-add-cloudflare-workers/design.md +0 -734
- package/openspec/changes/archive/2026-01-10-add-cloudflare-workers/proposal.md +0 -183
- package/openspec/changes/archive/2026-01-10-add-cloudflare-workers/specs/cloudflare-deployment/spec.md +0 -389
- package/openspec/changes/archive/2026-01-10-add-cloudflare-workers/tasks.md +0 -519
- package/openspec/changes/archive/2026-01-15-add-mcp-prompts/proposal.md +0 -13
- package/openspec/changes/archive/2026-01-15-add-mcp-prompts/specs/mcp-prompts/spec.md +0 -22
- package/openspec/changes/archive/2026-01-15-add-mcp-prompts/tasks.md +0 -10
- package/openspec/changes/archive/2026-01-15-add-mcp-resource-filters/proposal.md +0 -13
- package/openspec/changes/archive/2026-01-15-add-mcp-resource-filters/specs/mcp-resources/spec.md +0 -38
- package/openspec/changes/archive/2026-01-15-add-mcp-resource-filters/tasks.md +0 -10
- package/openspec/changes/archive/2026-01-19-update-repo-owner-ondata/proposal.md +0 -13
- package/openspec/changes/archive/2026-01-19-update-repo-owner-ondata/specs/repository-metadata/spec.md +0 -14
- package/openspec/changes/archive/2026-01-19-update-repo-owner-ondata/tasks.md +0 -12
- package/openspec/changes/archive/2026-01-19-update-search-parser-config/proposal.md +0 -13
- package/openspec/changes/archive/2026-01-19-update-search-parser-config/specs/ckan-insights/spec.md +0 -11
- package/openspec/changes/archive/2026-01-19-update-search-parser-config/specs/ckan-search/spec.md +0 -11
- package/openspec/changes/archive/2026-01-19-update-search-parser-config/tasks.md +0 -6
- package/openspec/changes/archive/add-automated-tests/design.md +0 -324
- package/openspec/changes/archive/add-automated-tests/proposal.md +0 -167
- package/openspec/changes/archive/add-automated-tests/specs/automated-testing/spec.md +0 -143
- package/openspec/changes/archive/add-automated-tests/tasks.md +0 -132
- package/openspec/project.md +0 -115
- package/openspec/specs/ckan-insights/spec.md +0 -23
- package/openspec/specs/ckan-search/spec.md +0 -16
- package/openspec/specs/cloudflare-deployment/spec.md +0 -344
- package/openspec/specs/documentation-language/spec.md +0 -32
- package/openspec/specs/mcp-prompts/spec.md +0 -26
- package/openspec/specs/mcp-resources/spec.md +0 -120
- package/openspec/specs/repository-metadata/spec.md +0 -19
- package/private/commenti-privati.yaml +0 -14
- package/testo.md +0 -12
- package/web-gui/PRD.md +0 -158
- package/web-gui/public/index.html +0 -883
- package/wrangler.toml +0 -6
|
@@ -1,355 +0,0 @@
|
|
|
1
|
-
# Design: Expand Test Coverage for Remaining Tools
|
|
2
|
-
|
|
3
|
-
This document explains the testing approach for expanding coverage to package, organization, and datastore tools, following patterns established in the initial testing implementation.
|
|
4
|
-
|
|
5
|
-
## Testing Approach
|
|
6
|
-
|
|
7
|
-
### Pattern Reuse
|
|
8
|
-
|
|
9
|
-
We follow the successful pattern from the initial testing proposal:
|
|
10
|
-
|
|
11
|
-
```typescript
|
|
12
|
-
// 1. Mock axios
|
|
13
|
-
vi.mock('axios');
|
|
14
|
-
|
|
15
|
-
// 2. Import fixtures
|
|
16
|
-
import packageSearchFixture from '../fixtures/responses/package-search-success.json';
|
|
17
|
-
|
|
18
|
-
// 3. Setup test
|
|
19
|
-
it('returns expected structure', async () => {
|
|
20
|
-
vi.mocked(axios.get).mockResolvedValue({ data: packageSearchFixture });
|
|
21
|
-
|
|
22
|
-
const result = await ckan_package_search({...});
|
|
23
|
-
|
|
24
|
-
// 4. Validate result
|
|
25
|
-
expect(result).toBeDefined();
|
|
26
|
-
expect(result.content[0].text).toContain('...');
|
|
27
|
-
});
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
### Test Structure
|
|
31
|
-
|
|
32
|
-
Each tool category gets its own test file:
|
|
33
|
-
- `tests/integration/package.test.ts`
|
|
34
|
-
- `tests/integration/organization.test.ts`
|
|
35
|
-
- `tests/integration/datastore.test.ts`
|
|
36
|
-
|
|
37
|
-
## Test Scenarios by Tool Category
|
|
38
|
-
|
|
39
|
-
### Package Tools
|
|
40
|
-
|
|
41
|
-
#### ckan_package_search Tests
|
|
42
|
-
|
|
43
|
-
**Happy Paths:**
|
|
44
|
-
1. Basic search with query parameter
|
|
45
|
-
2. Search with facets (facet_field, facet_limit)
|
|
46
|
-
3. Search with pagination (start, rows)
|
|
47
|
-
4. Search with sorting (sort)
|
|
48
|
-
5. Search with filter query (fq)
|
|
49
|
-
6. Empty results (q returns no matches)
|
|
50
|
-
|
|
51
|
-
**Edge Cases:**
|
|
52
|
-
7. Very large results (rows > 1000)
|
|
53
|
-
8. Multiple facet fields
|
|
54
|
-
9. Complex query (q + fq + facets)
|
|
55
|
-
10. Markdown output format validation
|
|
56
|
-
11. JSON output format validation
|
|
57
|
-
|
|
58
|
-
**Error Scenarios:**
|
|
59
|
-
12. Invalid query syntax (if applicable)
|
|
60
|
-
13. Server error during search
|
|
61
|
-
14. Timeout during search
|
|
62
|
-
|
|
63
|
-
#### ckan_package_show Tests
|
|
64
|
-
|
|
65
|
-
**Happy Paths:**
|
|
66
|
-
1. Show package with valid ID
|
|
67
|
-
2. Package with multiple resources
|
|
68
|
-
3. Package with tags
|
|
69
|
-
4. Package with organization
|
|
70
|
-
5. Package without resources
|
|
71
|
-
|
|
72
|
-
**Edge Cases:**
|
|
73
|
-
6. Package with very long description (test truncation)
|
|
74
|
-
7. Package with many resources (>10)
|
|
75
|
-
|
|
76
|
-
**Error Scenarios:**
|
|
77
|
-
8. Invalid package ID (404)
|
|
78
|
-
9. Server error during fetch
|
|
79
|
-
10. Timeout during fetch
|
|
80
|
-
|
|
81
|
-
### Organization Tools
|
|
82
|
-
|
|
83
|
-
#### ckan_organization_list Tests
|
|
84
|
-
|
|
85
|
-
**Happy Paths:**
|
|
86
|
-
1. List all organizations (default)
|
|
87
|
-
2. List with limit parameter
|
|
88
|
-
3. List with offset parameter
|
|
89
|
-
4. List with sort parameter
|
|
90
|
-
5. Empty result (no organizations)
|
|
91
|
-
|
|
92
|
-
**Edge Cases:**
|
|
93
|
-
6. Very large list (all organizations)
|
|
94
|
-
7. Sorting by different fields (name, title, package_count)
|
|
95
|
-
|
|
96
|
-
**Error Scenarios:**
|
|
97
|
-
8. Server error during list
|
|
98
|
-
9. Timeout during list
|
|
99
|
-
|
|
100
|
-
#### ckan_organization_show Tests
|
|
101
|
-
|
|
102
|
-
**Happy Paths:**
|
|
103
|
-
1. Show organization with valid ID
|
|
104
|
-
2. Organization with users
|
|
105
|
-
3. Organization with package_count
|
|
106
|
-
4. Organization with extras (custom fields)
|
|
107
|
-
|
|
108
|
-
**Edge Cases:**
|
|
109
|
-
5. Organization with very long description
|
|
110
|
-
|
|
111
|
-
**Error Scenarios:**
|
|
112
|
-
6. Invalid organization ID (404)
|
|
113
|
-
7. Server error during fetch
|
|
114
|
-
8. Timeout during fetch
|
|
115
|
-
|
|
116
|
-
#### ckan_organization_search Tests
|
|
117
|
-
|
|
118
|
-
**Happy Paths:**
|
|
119
|
-
1. Search with query
|
|
120
|
-
2. Search with wildcard (*)
|
|
121
|
-
3. Search with facets
|
|
122
|
-
4. Search with pagination
|
|
123
|
-
|
|
124
|
-
**Edge Cases:**
|
|
125
|
-
5. Search returning many results
|
|
126
|
-
6. Search returning no results
|
|
127
|
-
|
|
128
|
-
**Error Scenarios:**
|
|
129
|
-
7. Invalid query
|
|
130
|
-
8. Server error during search
|
|
131
|
-
9. Timeout during search
|
|
132
|
-
|
|
133
|
-
### DataStore Tools
|
|
134
|
-
|
|
135
|
-
#### ckan_datastore_search Tests
|
|
136
|
-
|
|
137
|
-
**Happy Paths:**
|
|
138
|
-
1. Basic query with resource_id
|
|
139
|
-
2. Query with filters
|
|
140
|
-
3. Query with sorting
|
|
141
|
-
4. Query with pagination (limit, offset)
|
|
142
|
-
5. Query with multiple filters
|
|
143
|
-
6. Query with field list (fields parameter)
|
|
144
|
-
|
|
145
|
-
**Edge Cases:**
|
|
146
|
-
7. Large result set (test truncation)
|
|
147
|
-
8. Complex filters (AND/OR logic)
|
|
148
|
-
9. Empty result (no records)
|
|
149
|
-
|
|
150
|
-
**Error Scenarios:**
|
|
151
|
-
10. Invalid resource_id
|
|
152
|
-
11. Invalid filter syntax
|
|
153
|
-
12. Server error during query
|
|
154
|
-
13. Timeout during query
|
|
155
|
-
14. DataStore not enabled for resource
|
|
156
|
-
|
|
157
|
-
## Output Format Validation
|
|
158
|
-
|
|
159
|
-
All tools support both markdown and JSON output. Tests should validate:
|
|
160
|
-
|
|
161
|
-
### Markdown Format
|
|
162
|
-
```typescript
|
|
163
|
-
test('returns markdown format', async () => {
|
|
164
|
-
vi.mocked(axios.get).mockResolvedValue({ data: fixture });
|
|
165
|
-
|
|
166
|
-
const result = await ckan_package_search({ format: 'markdown', ... });
|
|
167
|
-
|
|
168
|
-
expect(result.content[0].type).toBe('text');
|
|
169
|
-
expect(result.content[0].text).toMatch(/^# /); // Markdown heading
|
|
170
|
-
});
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
### JSON Format
|
|
174
|
-
```typescript
|
|
175
|
-
test('returns JSON format', async () => {
|
|
176
|
-
vi.mocked(axios.get).mockResolvedValue({ data: fixture });
|
|
177
|
-
|
|
178
|
-
const result = await ckan_package_search({ format: 'json', ... });
|
|
179
|
-
|
|
180
|
-
expect(result.content[0].type).toBe('resource');
|
|
181
|
-
expect(result.structuredContent).toBeDefined();
|
|
182
|
-
});
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
## Error Handling Tests
|
|
186
|
-
|
|
187
|
-
All tools should handle errors gracefully:
|
|
188
|
-
|
|
189
|
-
```typescript
|
|
190
|
-
test('handles 404 error', async () => {
|
|
191
|
-
vi.mocked(axios.get).mockRejectedValue({
|
|
192
|
-
isAxiosError: true,
|
|
193
|
-
response: { status: 404, data: notFoundFixture }
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
const result = await ckan_package_show({ package_id: 'invalid' });
|
|
197
|
-
|
|
198
|
-
expect(result.isError).toBe(true);
|
|
199
|
-
expect(result.content[0].text).toContain('Not found');
|
|
200
|
-
});
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
## Fixture Strategy
|
|
204
|
-
|
|
205
|
-
### Existing Fixtures
|
|
206
|
-
|
|
207
|
-
Reuse fixtures from initial proposal:
|
|
208
|
-
- `package-search-success.json` - already exists
|
|
209
|
-
- `package-show-success.json` - already exists
|
|
210
|
-
- `organization-list-success.json` - already exists
|
|
211
|
-
- `organization-show-success.json` - already exists
|
|
212
|
-
- `organization-search-success.json` - already exists
|
|
213
|
-
- `datastore-search-success.json` - already exists
|
|
214
|
-
|
|
215
|
-
### Additional Fixtures Needed
|
|
216
|
-
|
|
217
|
-
May need to create:
|
|
218
|
-
- `package-empty-results.json` - for empty search results
|
|
219
|
-
- `organization-empty-results.json` - for empty org list
|
|
220
|
-
- `datastore-empty-results.json` - for empty data queries
|
|
221
|
-
- Error fixtures specific to each tool if needed
|
|
222
|
-
|
|
223
|
-
### Creating New Fixtures
|
|
224
|
-
|
|
225
|
-
Follow existing structure:
|
|
226
|
-
|
|
227
|
-
**Success fixture:**
|
|
228
|
-
```json
|
|
229
|
-
{
|
|
230
|
-
"help": "API help URL",
|
|
231
|
-
"success": true,
|
|
232
|
-
"result": { ... }
|
|
233
|
-
}
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
**Error fixture:**
|
|
237
|
-
```json
|
|
238
|
-
{
|
|
239
|
-
"success": false,
|
|
240
|
-
"error": {
|
|
241
|
-
"__type": "Error Type",
|
|
242
|
-
"message": "Error message",
|
|
243
|
-
"status": 404
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
## Coverage Goals
|
|
249
|
-
|
|
250
|
-
### Target Metrics
|
|
251
|
-
|
|
252
|
-
| Component | Current Coverage | Target Coverage | Tests Needed |
|
|
253
|
-
|-----------|------------------|-----------------|---------------|
|
|
254
|
-
| Utils | 100% | 100% | ✅ Done |
|
|
255
|
-
| Status Tool | ~50% | 75-85% | ✅ Done |
|
|
256
|
-
| Package Tools | 0% | 75-85% | ~16 tests |
|
|
257
|
-
| Organization Tools | 0% | 75-85% | ~18 tests |
|
|
258
|
-
| DataStore Tool | 0% | 75-85% | ~14 tests |
|
|
259
|
-
| **Overall** | **~68%** | **80%+** | **~48 tests** |
|
|
260
|
-
|
|
261
|
-
### Verification
|
|
262
|
-
|
|
263
|
-
After each tool category is tested, run:
|
|
264
|
-
```bash
|
|
265
|
-
npm run test:coverage
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
Ensure coverage increases and meets targets.
|
|
269
|
-
|
|
270
|
-
## Test Writing Guidelines
|
|
271
|
-
|
|
272
|
-
### Naming Convention
|
|
273
|
-
```typescript
|
|
274
|
-
// Good
|
|
275
|
-
test('ckan_package_search with facets returns aggregated data', () => { ... });
|
|
276
|
-
|
|
277
|
-
// Bad
|
|
278
|
-
test('search works', () => { ... });
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
### AAA Pattern
|
|
282
|
-
```typescript
|
|
283
|
-
test('search with pagination', async () => {
|
|
284
|
-
// Arrange
|
|
285
|
-
const params = { q: 'test', start: 10, rows: 20 };
|
|
286
|
-
|
|
287
|
-
// Act
|
|
288
|
-
const result = await ckan_package_search(params);
|
|
289
|
-
|
|
290
|
-
// Assert
|
|
291
|
-
expect(result.content[0].text).toContain('Showing 10-20 of');
|
|
292
|
-
});
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
### One Assertion Per Test
|
|
296
|
-
```typescript
|
|
297
|
-
// Good
|
|
298
|
-
test('truncates long descriptions', async () => {
|
|
299
|
-
const result = await ckan_package_show({ package_id: 'long-desc' });
|
|
300
|
-
expect(result.content[0].text).toContain('[Response truncated]');
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
// Bad
|
|
304
|
-
test('package_show works', async () => {
|
|
305
|
-
const result = await ckan_package_show({ package_id: 'pkg' });
|
|
306
|
-
expect(result).toBeDefined();
|
|
307
|
-
expect(result.content).toBeDefined();
|
|
308
|
-
expect(result.content[0]).toBeDefined();
|
|
309
|
-
expect(result.content[0].text).toBeDefined();
|
|
310
|
-
});
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
## Implementation Order
|
|
314
|
-
|
|
315
|
-
1. **Package Tools** (highest priority)
|
|
316
|
-
- Most complex
|
|
317
|
-
- Most used
|
|
318
|
-
- Largest code block (~350 lines)
|
|
319
|
-
|
|
320
|
-
2. **Organization Tools** (medium priority)
|
|
321
|
-
- Medium complexity
|
|
322
|
-
- Medium code block (~341 lines)
|
|
323
|
-
|
|
324
|
-
3. **DataStore Tool** (lower priority)
|
|
325
|
-
- Simpler logic
|
|
326
|
-
- Smaller code block (~146 lines)
|
|
327
|
-
- May have platform-specific behavior
|
|
328
|
-
|
|
329
|
-
## Future Enhancements
|
|
330
|
-
|
|
331
|
-
### Short Term
|
|
332
|
-
- Contract tests for CKAN API responses
|
|
333
|
-
- Visual regression tests for markdown output
|
|
334
|
-
- Performance benchmarks for queries
|
|
335
|
-
|
|
336
|
-
### Medium Term
|
|
337
|
-
- Increase coverage to 90%+
|
|
338
|
-
- Add contract tests for all tool schemas
|
|
339
|
-
- Add integration with real test CKAN instance (optional)
|
|
340
|
-
|
|
341
|
-
### Long Term
|
|
342
|
-
- Fuzz testing for input validation
|
|
343
|
-
- Chaos testing for error handling
|
|
344
|
-
- Property-based testing
|
|
345
|
-
|
|
346
|
-
## Conclusion
|
|
347
|
-
|
|
348
|
-
This test expansion follows the proven patterns from the initial testing proposal, focusing on:
|
|
349
|
-
|
|
350
|
-
- **Consistency**: Same structure, fixtures, and patterns
|
|
351
|
-
- **Completeness**: Cover all tool categories
|
|
352
|
-
- **Quality**: Test both happy paths and error scenarios
|
|
353
|
-
- **Maintainability**: Simple, focused, well-documented tests
|
|
354
|
-
|
|
355
|
-
The incremental implementation ensures we achieve 80%+ coverage while keeping the work manageable and debuggable.
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
# Proposal: Expand Test Coverage to Remaining Tools
|
|
2
|
-
|
|
3
|
-
**Status:** Completed
|
|
4
|
-
**Created:** 2026-01-08
|
|
5
|
-
**Author:** OpenCode
|
|
6
|
-
**Related:** Archived proposal "add-automated-tests"
|
|
7
|
-
|
|
8
|
-
## Summary
|
|
9
|
-
|
|
10
|
-
Add integration tests for the remaining MCP tools (package, organization, datastore) to achieve 80%+ code coverage and improve test reliability.
|
|
11
|
-
|
|
12
|
-
## Motivation
|
|
13
|
-
|
|
14
|
-
The initial automated testing implementation successfully established the testing foundation but only covered:
|
|
15
|
-
- Utility functions (100% coverage)
|
|
16
|
-
- Status tool (partial coverage)
|
|
17
|
-
- Overall coverage: ~68%
|
|
18
|
-
|
|
19
|
-
To meet the 80% coverage target and ensure reliability, we need to test the remaining three tool categories that represent the majority of the codebase:
|
|
20
|
-
- Package tools: ~350 lines
|
|
21
|
-
- Organization tools: ~341 lines
|
|
22
|
-
- DataStore tools: ~146 lines
|
|
23
|
-
|
|
24
|
-
Adding these tests will:
|
|
25
|
-
- Increase overall coverage to 80%+
|
|
26
|
-
- Catch bugs in tool implementations
|
|
27
|
-
- Document expected behavior through tests
|
|
28
|
-
- Enable confident refactoring of tool code
|
|
29
|
-
- Provide safety net for future changes
|
|
30
|
-
|
|
31
|
-
## Scope
|
|
32
|
-
|
|
33
|
-
### Included
|
|
34
|
-
- **Integration tests** for package tools (ckan_package_search, ckan_package_show)
|
|
35
|
-
- **Integration tests** for organization tools (ckan_organization_list, ckan_organization_show, ckan_organization_search)
|
|
36
|
-
- **Integration tests** for datastore tool (ckan_datastore_search)
|
|
37
|
-
- Additional fixtures for error scenarios if needed
|
|
38
|
-
- Tests for both markdown and JSON output formats
|
|
39
|
-
- Tests for edge cases (empty results, pagination, filters)
|
|
40
|
-
|
|
41
|
-
### Excluded
|
|
42
|
-
- E2e tests with real CKAN servers (already excluded)
|
|
43
|
-
- Performance/benchmark tests (future enhancement)
|
|
44
|
-
- UI/interaction tests (no UI in this project)
|
|
45
|
-
- Testing MCP SDK internals (out of scope)
|
|
46
|
-
- Testing external libraries (axios, zod, express)
|
|
47
|
-
|
|
48
|
-
## Proposed Changes
|
|
49
|
-
|
|
50
|
-
### Test Strategy
|
|
51
|
-
|
|
52
|
-
Following the same pattern established in the first proposal:
|
|
53
|
-
1. Use Vitest with mocked axios
|
|
54
|
-
2. Reuse existing fixtures from `tests/fixtures/`
|
|
55
|
-
3. Create new fixtures only if needed
|
|
56
|
-
4. Test success and error scenarios
|
|
57
|
-
5. Test both markdown and JSON output formats
|
|
58
|
-
|
|
59
|
-
### Test Coverage Breakdown
|
|
60
|
-
|
|
61
|
-
#### Package Tools (~6 tests)
|
|
62
|
-
- Basic search with query
|
|
63
|
-
- Search with facets
|
|
64
|
-
- Search with pagination
|
|
65
|
-
- Search with sorting
|
|
66
|
-
- Search with filter query
|
|
67
|
-
- Show package details
|
|
68
|
-
|
|
69
|
-
#### Organization Tools (~8 tests)
|
|
70
|
-
- List organizations
|
|
71
|
-
- List with sorting
|
|
72
|
-
- Show organization details
|
|
73
|
-
- Search organizations
|
|
74
|
-
- Error scenarios (404, invalid ID)
|
|
75
|
-
|
|
76
|
-
#### DataStore Tool (~6 tests)
|
|
77
|
-
- Basic query
|
|
78
|
-
- Query with filters
|
|
79
|
-
- Query with sorting
|
|
80
|
-
- Query with pagination
|
|
81
|
-
- Error scenarios
|
|
82
|
-
- Output format validation
|
|
83
|
-
|
|
84
|
-
### Coverage Target
|
|
85
|
-
|
|
86
|
-
**Goal**: Increase from ~68% to 80%+
|
|
87
|
-
|
|
88
|
-
**Expected breakdown after completion**:
|
|
89
|
-
- Utils: 100% (already achieved)
|
|
90
|
-
- Status tool: 75-85%
|
|
91
|
-
- Package tools: 75-85%
|
|
92
|
-
- Organization tools: 75-85%
|
|
93
|
-
- DataStore tool: 75-85%
|
|
94
|
-
- **Overall**: 80%+
|
|
95
|
-
|
|
96
|
-
### Incremental Approach
|
|
97
|
-
|
|
98
|
-
1. Start with package tools (largest, most complex)
|
|
99
|
-
2. Add organization tests
|
|
100
|
-
3. Add datastore tests
|
|
101
|
-
4. Validate coverage after each batch
|
|
102
|
-
5. Adjust if needed
|
|
103
|
-
|
|
104
|
-
## Alternatives Considered
|
|
105
|
-
|
|
106
|
-
1. **Test all tools at once**
|
|
107
|
-
- *Rejected*: Too large, hard to debug, follow incremental pattern
|
|
108
|
-
|
|
109
|
-
2. **Skip integration tests, only unit tests**
|
|
110
|
-
- *Rejected*: Would miss tool behavior and CKAN API interactions
|
|
111
|
-
|
|
112
|
-
3. **Use real CKAN servers for testing**
|
|
113
|
-
- *Rejected*: Already excluded in original proposal (slow, unreliable)
|
|
114
|
-
|
|
115
|
-
4. **Test only happy paths, ignore errors**
|
|
116
|
-
- *Rejected*: Error handling is critical for robust tools
|
|
117
|
-
|
|
118
|
-
## Impact Assessment
|
|
119
|
-
|
|
120
|
-
### Benefits
|
|
121
|
-
- + Increased coverage from 68% to 80%+
|
|
122
|
-
- + Better bug detection in tool code
|
|
123
|
-
- + Safer refactoring of tool implementations
|
|
124
|
-
- + Documented expected behavior for all tools
|
|
125
|
-
- + Higher confidence in code quality
|
|
126
|
-
|
|
127
|
-
### Risks
|
|
128
|
-
- - Initial time investment for writing ~20 more tests
|
|
129
|
-
- - Test maintenance overhead as tool code evolves
|
|
130
|
-
- - Possible need for additional fixtures
|
|
131
|
-
|
|
132
|
-
### Mitigation
|
|
133
|
-
- Reuse existing fixtures where possible
|
|
134
|
-
- Follow established test patterns
|
|
135
|
-
- Write tests incrementally, validate after each batch
|
|
136
|
-
- Keep tests simple and focused
|
|
137
|
-
|
|
138
|
-
## Open Questions
|
|
139
|
-
|
|
140
|
-
None - reusing established patterns from first proposal.
|
|
141
|
-
|
|
142
|
-
## Dependencies
|
|
143
|
-
|
|
144
|
-
Depends on:
|
|
145
|
-
- Proposal "add-automated-tests" (archived) - provides test infrastructure and fixtures
|
|
146
|
-
- Existing fixtures in `tests/fixtures/` - may need additions
|
|
147
|
-
|
|
148
|
-
## Success Criteria
|
|
149
|
-
|
|
150
|
-
- [ ] All package tools have integration tests
|
|
151
|
-
- [ ] All organization tools have integration tests
|
|
152
|
-
- [ ] DataStore tool has integration tests
|
|
153
|
-
- [ ] Tests pass (green CI if exists)
|
|
154
|
-
- [ ] Overall coverage meets 80% threshold
|
|
155
|
-
- [ ] Tests follow established patterns from first proposal
|
|
156
|
-
- [ ] Documentation updated if needed
|
|
157
|
-
- [ ] Validation: `openspec validate expand-test-coverage --strict` passes
|
|
158
|
-
|
|
159
|
-
## Notes
|
|
160
|
-
|
|
161
|
-
This proposal is a direct continuation of the "add-automated-tests" proposal. All testing infrastructure (Vitest, fixtures, patterns) is already in place, so the focus is purely on writing the actual test files for the remaining tools.
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
# Tasks: Expand Test Coverage to Remaining Tools
|
|
2
|
-
|
|
3
|
-
Ordered list of work items to add integration tests for package, organization, and datastore tools.
|
|
4
|
-
|
|
5
|
-
## Phase 1: Package Tools
|
|
6
|
-
|
|
7
|
-
### ckan_package_search Tests
|
|
8
|
-
|
|
9
|
-
- [x] Create `tests/integration/package.test.ts`
|
|
10
|
-
- [x] Write test for basic search with query parameter
|
|
11
|
-
- [x] Write test for search returning empty results
|
|
12
|
-
- [x] Write test for search with pagination (start, rows)
|
|
13
|
-
- [x] Write test for search with sorting (sort parameter)
|
|
14
|
-
- [x] Write test for search with filter query (fq parameter)
|
|
15
|
-
- [x] Write test for search with multiple filter queries
|
|
16
|
-
- [x] Write test for search with complex query (q + fq + facets)
|
|
17
|
-
- [x] Write test validating markdown output format
|
|
18
|
-
- [x] Write test handling 404 error for invalid query
|
|
19
|
-
- [x] Write test handling server error
|
|
20
|
-
- [x] Write test for faceting with facet_field
|
|
21
|
-
- [x] Run package tool tests and verify all pass
|
|
22
|
-
|
|
23
|
-
### ckan_package_show Tests
|
|
24
|
-
|
|
25
|
-
- [x] Write test for showing package with valid ID
|
|
26
|
-
- [x] Write test for package with multiple resources
|
|
27
|
-
- [x] Write test for package with tags
|
|
28
|
-
- [x] Write test for package with organization
|
|
29
|
-
- [x] Write test for package without resources
|
|
30
|
-
- [x] Write test handling 404 error for invalid package ID
|
|
31
|
-
- [x] Write test handling server error when fetching package
|
|
32
|
-
- [x] Write test validating JSON output format
|
|
33
|
-
- [x] Run package tool tests and verify all pass
|
|
34
|
-
|
|
35
|
-
## Phase 2: Organization Tools
|
|
36
|
-
|
|
37
|
-
### ckan_organization_list Tests
|
|
38
|
-
|
|
39
|
-
- [x] Create `tests/integration/organization.test.ts`
|
|
40
|
-
- [x] Write test for listing all organizations (default)
|
|
41
|
-
- [x] Write test for returning list of organizations
|
|
42
|
-
- [x] Write test for listing with empty results
|
|
43
|
-
- [x] Run organization tool tests and verify all pass
|
|
44
|
-
|
|
45
|
-
### ckan_organization_show Tests
|
|
46
|
-
|
|
47
|
-
- [x] Write test for showing organization with valid ID
|
|
48
|
-
- [x] Write test for organization with users
|
|
49
|
-
- [x] Write test for organization with packages
|
|
50
|
-
- [x] Write test handling 404 error for invalid organization ID
|
|
51
|
-
- [x] Write test handling server error when fetching organization
|
|
52
|
-
- [x] Run organization tool tests and verify all pass
|
|
53
|
-
|
|
54
|
-
### ckan_organization_search Tests
|
|
55
|
-
|
|
56
|
-
- [x] Write test for searching organizations by pattern
|
|
57
|
-
- [x] Write test for search returning empty results
|
|
58
|
-
- [x] Write test handling server error when searching organizations
|
|
59
|
-
- [x] Run organization tool tests and verify all pass
|
|
60
|
-
|
|
61
|
-
## Phase 3: DataStore Tool
|
|
62
|
-
|
|
63
|
-
### ckan_datastore_search Tests
|
|
64
|
-
|
|
65
|
-
- [x] Create `tests/integration/datastore.test.ts`
|
|
66
|
-
- [x] Write test for basic query with resource_id
|
|
67
|
-
- [x] Write test for query with filters
|
|
68
|
-
- [x] Write test for query with sorting
|
|
69
|
-
- [x] Write test for query with pagination (limit, offset)
|
|
70
|
-
- [x] Write test for query with field list (fields parameter)
|
|
71
|
-
- [x] Write test handling 404 error for invalid resource_id
|
|
72
|
-
- [x] Write test handling server error when querying DataStore
|
|
73
|
-
- [x] Write test handling timeout when querying DataStore
|
|
74
|
-
- [x] Write test validating JSON output format
|
|
75
|
-
- [x] Write test for empty query results
|
|
76
|
-
- [x] Write test for maximum limit (32000)
|
|
77
|
-
- [x] Write test handling large result sets (50000+ records)
|
|
78
|
-
- [x] Run datastore tool tests and verify all pass
|
|
79
|
-
|
|
80
|
-
## Phase 4: Additional Fixtures
|
|
81
|
-
|
|
82
|
-
- [x] Create error fixtures if needed for tool-specific scenarios
|
|
83
|
-
|
|
84
|
-
## Phase 5: Validation
|
|
85
|
-
|
|
86
|
-
- [x] Run `npm test` and verify all tests pass
|
|
87
|
-
- [x] Verify package tools coverage meets target
|
|
88
|
-
- [x] Verify organization tools coverage meets target
|
|
89
|
-
- [x] Verify datastore tool coverage meets target
|
|
90
|
-
- [x] Verify overall coverage meets 80% threshold
|
|
91
|
-
- [ ] Run `npm run test:coverage` and check coverage report
|
|
92
|
-
- [ ] Check that all tests follow established patterns
|
|
93
|
-
|
|
94
|
-
## Phase 6: Documentation
|
|
95
|
-
|
|
96
|
-
- [ ] Update tests/README.md with new test files
|
|
97
|
-
- [ ] Add examples from new test files to documentation
|
|
98
|
-
- [ ] Update CLAUDE.md if needed with testing notes
|
|
99
|
-
- [ ] Update proposal status to completed
|
|
100
|
-
|
|
101
|
-
## Dependencies
|
|
102
|
-
|
|
103
|
-
- Phase 1 must complete before Phase 2
|
|
104
|
-
- Phase 2 must complete before Phase 3
|
|
105
|
-
- Phase 4 can be done in parallel with Phases 1-3 as needed
|
|
106
|
-
- Phase 5 depends on completion of Phases 1, 2, 3
|
|
107
|
-
- Phase 6 depends on Phase 5 completion
|
|
108
|
-
|
|
109
|
-
## Notes
|
|
110
|
-
|
|
111
|
-
- Reuse existing fixtures where possible
|
|
112
|
-
- Follow AAA pattern (Arrange, Act, Assert)
|
|
113
|
-
- Use descriptive test names
|
|
114
|
-
- Test both success and error scenarios
|
|
115
|
-
- Validate both markdown and JSON output formats
|
|
116
|
-
- Keep tests simple and focused
|
|
117
|
-
- Run tests in watch mode during development: `npm run test:watch`
|
|
118
|
-
- Generate coverage report: `npm run test:coverage`
|
|
119
|
-
- Check existing tests (`tests/integration/status.test.ts`) for reference
|
|
120
|
-
|
|
121
|
-
## Test File Creation Template
|
|
122
|
-
|
|
123
|
-
When creating new test files:
|
|
124
|
-
|
|
125
|
-
```typescript
|
|
126
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
127
|
-
import axios from 'axios';
|
|
128
|
-
import { makeCkanRequest } from '../../src/utils/http';
|
|
129
|
-
import { ckan_package_search, ckan_package_show } from '../../src/tools/package';
|
|
130
|
-
import relevantFixture from '../fixtures/responses/relevant-fixture.json';
|
|
131
|
-
|
|
132
|
-
vi.mock('axios');
|
|
133
|
-
|
|
134
|
-
describe('ckan_package_search', () => {
|
|
135
|
-
beforeEach(() => {
|
|
136
|
-
vi.clearAllMocks();
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
it('descriptive test name', async () => {
|
|
140
|
-
vi.mocked(axios.get).mockResolvedValue({ data: relevantFixture });
|
|
141
|
-
|
|
142
|
-
const result = await ckan_package_search({
|
|
143
|
-
server_url: 'http://demo.ckan.org',
|
|
144
|
-
q: 'test'
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
// Assertions
|
|
148
|
-
expect(result).toBeDefined();
|
|
149
|
-
expect(result.content[0].text).toContain('...');
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
## Expected Outcomes
|
|
155
|
-
|
|
156
|
-
After completing all phases:
|
|
157
|
-
- ~78 new tests added (29 package + 24 organization + 18 datastore + 2 status + 6 unit = 79)
|
|
158
|
-
- Overall coverage increased from ~68% to 80%+
|
|
159
|
-
- All tool categories have integration tests
|
|
160
|
-
- Tests follow established patterns
|
|
161
|
-
- Tests documented in README
|
|
162
|
-
- CI passes (if configured)
|