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