docs: add TESTING.md with API testing guide
This commit is contained in:
213
TESTING.md
Normal file
213
TESTING.md
Normal file
@@ -0,0 +1,213 @@
|
||||
# SimpleNote Web - Testing Guide
|
||||
|
||||
## Running the Server Locally
|
||||
|
||||
```bash
|
||||
cd simplenote-projects/simplenote-web
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
|
||||
The server starts on `http://localhost:3000` by default.
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Default | Description |
|
||||
|---------------|-------------------------------|---------------------------|
|
||||
| `PORT` | `3000` | Server port |
|
||||
| `HOST` | `0.0.0.0` | Server host |
|
||||
| `DATA_ROOT` | `./data` | Document storage path |
|
||||
| `ADMIN_TOKEN` | `snk_initial_admin_token_change_me` | Initial admin token |
|
||||
| `CORS_ORIGIN` | `*` | CORS allowed origin |
|
||||
| `API_PREFIX` | `/api/v1` | API route prefix |
|
||||
|
||||
## API Endpoints
|
||||
|
||||
Base URL: `http://localhost:3000/api/v1`
|
||||
|
||||
All endpoints (except `/health` and `/auth/verify`) require:
|
||||
```
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
### Health Check
|
||||
|
||||
```bash
|
||||
curl http://localhost:3000/health
|
||||
```
|
||||
|
||||
### Auth Endpoints
|
||||
|
||||
**Generate token (admin only):**
|
||||
```bash
|
||||
# Using initial admin token
|
||||
curl -X POST http://localhost:3000/api/v1/auth/token \
|
||||
-H "Authorization: Bearer snk_initial_admin_token_change_me" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"label": "test-token"}'
|
||||
```
|
||||
|
||||
**Verify token:**
|
||||
```bash
|
||||
curl http://localhost:3000/api/v1/auth/verify \
|
||||
-H "Authorization: Bearer <token>"
|
||||
```
|
||||
|
||||
### Library Endpoints
|
||||
|
||||
**Create a library:**
|
||||
```bash
|
||||
curl -X POST http://localhost:3000/api/v1/libraries \
|
||||
-H "Authorization: Bearer <token>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name": "My Project"}'
|
||||
```
|
||||
|
||||
**List root libraries:**
|
||||
```bash
|
||||
curl http://localhost:3000/api/v1/libraries \
|
||||
-H "Authorization: Bearer <token>"
|
||||
```
|
||||
|
||||
**Get library contents:**
|
||||
```bash
|
||||
curl http://localhost:3000/api/v1/libraries/<library-id> \
|
||||
-H "Authorization: Bearer <token>"
|
||||
```
|
||||
|
||||
**Get library tree:**
|
||||
```bash
|
||||
curl http://localhost:3000/api/v1/libraries/<library-id>/tree \
|
||||
-H "Authorization: Bearer <token>"
|
||||
```
|
||||
|
||||
**Delete library:**
|
||||
```bash
|
||||
curl -X DELETE http://localhost:3000/api/v1/libraries/<library-id> \
|
||||
-H "Authorization: Bearer <token>"
|
||||
```
|
||||
|
||||
### Document Endpoints
|
||||
|
||||
**Create document:**
|
||||
```bash
|
||||
curl -X POST http://localhost:3000/api/v1/documents \
|
||||
-H "Authorization: Bearer <token>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"title": "API Requirements",
|
||||
"libraryId": "<library-id>",
|
||||
"content": "# API Requirements\n\n## Description\n...",
|
||||
"tags": ["backend", "api"],
|
||||
"type": "requirement",
|
||||
"priority": "high",
|
||||
"status": "draft"
|
||||
}'
|
||||
```
|
||||
|
||||
**List documents (with filters):**
|
||||
```bash
|
||||
# All documents
|
||||
curl "http://localhost:3000/api/v1/documents" \
|
||||
-H "Authorization: Bearer <token>"
|
||||
|
||||
# Filter by tag
|
||||
curl "http://localhost:3000/api/v1/documents?tag=backend" \
|
||||
-H "Authorization: Bearer <token>"
|
||||
|
||||
# Filter by library
|
||||
curl "http://localhost:3000/api/v1/documents?library=<library-id>" \
|
||||
-H "Authorization: Bearer <token>"
|
||||
|
||||
# Filter by type
|
||||
curl "http://localhost:3000/api/v1/documents?type=requirement" \
|
||||
-H "Authorization: Bearer <token>"
|
||||
|
||||
# Filter by status
|
||||
curl "http://localhost:3000/api/v1/documents?status=draft" \
|
||||
-H "Authorization: Bearer <token>"
|
||||
|
||||
# With pagination
|
||||
curl "http://localhost:3000/api/v1/documents?limit=10&offset=0" \
|
||||
-H "Authorization: Bearer <token>"
|
||||
```
|
||||
|
||||
**Get document:**
|
||||
```bash
|
||||
curl http://localhost:3000/api/v1/documents/<doc-id> \
|
||||
-H "Authorization: Bearer <token>"
|
||||
```
|
||||
|
||||
**Update document:**
|
||||
```bash
|
||||
curl -X PUT http://localhost:3000/api/v1/documents/<doc-id> \
|
||||
-H "Authorization: Bearer <token>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"title": "Updated Title", "status": "approved"}'
|
||||
```
|
||||
|
||||
**Delete document:**
|
||||
```bash
|
||||
curl -X DELETE http://localhost:3000/api/v1/documents/<doc-id> \
|
||||
-H "Authorization: Bearer <token>"
|
||||
```
|
||||
|
||||
**Export document as markdown:**
|
||||
```bash
|
||||
curl http://localhost:3000/api/v1/documents/<doc-id>/export \
|
||||
-H "Authorization: Bearer <token>"
|
||||
```
|
||||
|
||||
**Add tags to document:**
|
||||
```bash
|
||||
curl -X POST http://localhost:3000/api/v1/documents/<doc-id>/tags \
|
||||
-H "Authorization: Bearer <token>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"tags": ["new-tag", "another-tag"]}'
|
||||
```
|
||||
|
||||
### Tag Endpoints
|
||||
|
||||
**List all tags:**
|
||||
```bash
|
||||
curl http://localhost:3000/api/v1/tags \
|
||||
-H "Authorization: Bearer <token>"
|
||||
```
|
||||
|
||||
**Get documents with a tag:**
|
||||
```bash
|
||||
curl http://localhost:3000/api/v1/tags/backend \
|
||||
-H "Authorization: Bearer <token>"
|
||||
```
|
||||
|
||||
## Test Cases
|
||||
|
||||
### Happy Path
|
||||
1. Create a library → receive library ID
|
||||
2. Create a document in that library → receive document ID
|
||||
3. List documents filtered by that library → document appears
|
||||
4. Get the document by ID → full content returned
|
||||
5. Update the document title and status
|
||||
6. Add tags to the document
|
||||
7. List tags → new tags appear with correct counts
|
||||
8. Get documents by tag → document appears
|
||||
9. Export document → markdown returned
|
||||
10. Delete document → confirmed deleted
|
||||
11. Delete library → confirmed deleted
|
||||
|
||||
### Edge Cases
|
||||
- Create document without library ID → 400 error
|
||||
- Create document with empty title → 400 error
|
||||
- Get non-existent document → 404 error
|
||||
- Update non-existent document → 404 error
|
||||
- Delete non-existent document → 404 error
|
||||
- List documents with invalid tag → empty list
|
||||
- Create document with invalid type → defaults to "general"
|
||||
- Create document with invalid priority → defaults to "medium"
|
||||
- Unauthorized request (no token) → 401 error
|
||||
- Invalid token → 401 error
|
||||
|
||||
### Security Tests
|
||||
- Path traversal attempt in library ID → should be handled safely
|
||||
- Very large content in document → limit enforced (10mb)
|
||||
- XSS in document title/content → no sanitization (intentional, markdown renderer handles it)
|
||||
Reference in New Issue
Block a user