diff --git a/TESTING.md b/TESTING.md new file mode 100644 index 0000000..b6924a8 --- /dev/null +++ b/TESTING.md @@ -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 +``` + +### 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 " +``` + +### Library Endpoints + +**Create a library:** +```bash +curl -X POST http://localhost:3000/api/v1/libraries \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d '{"name": "My Project"}' +``` + +**List root libraries:** +```bash +curl http://localhost:3000/api/v1/libraries \ + -H "Authorization: Bearer " +``` + +**Get library contents:** +```bash +curl http://localhost:3000/api/v1/libraries/ \ + -H "Authorization: Bearer " +``` + +**Get library tree:** +```bash +curl http://localhost:3000/api/v1/libraries//tree \ + -H "Authorization: Bearer " +``` + +**Delete library:** +```bash +curl -X DELETE http://localhost:3000/api/v1/libraries/ \ + -H "Authorization: Bearer " +``` + +### Document Endpoints + +**Create document:** +```bash +curl -X POST http://localhost:3000/api/v1/documents \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d '{ + "title": "API Requirements", + "libraryId": "", + "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 " + +# Filter by tag +curl "http://localhost:3000/api/v1/documents?tag=backend" \ + -H "Authorization: Bearer " + +# Filter by library +curl "http://localhost:3000/api/v1/documents?library=" \ + -H "Authorization: Bearer " + +# Filter by type +curl "http://localhost:3000/api/v1/documents?type=requirement" \ + -H "Authorization: Bearer " + +# Filter by status +curl "http://localhost:3000/api/v1/documents?status=draft" \ + -H "Authorization: Bearer " + +# With pagination +curl "http://localhost:3000/api/v1/documents?limit=10&offset=0" \ + -H "Authorization: Bearer " +``` + +**Get document:** +```bash +curl http://localhost:3000/api/v1/documents/ \ + -H "Authorization: Bearer " +``` + +**Update document:** +```bash +curl -X PUT http://localhost:3000/api/v1/documents/ \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d '{"title": "Updated Title", "status": "approved"}' +``` + +**Delete document:** +```bash +curl -X DELETE http://localhost:3000/api/v1/documents/ \ + -H "Authorization: Bearer " +``` + +**Export document as markdown:** +```bash +curl http://localhost:3000/api/v1/documents//export \ + -H "Authorization: Bearer " +``` + +**Add tags to document:** +```bash +curl -X POST http://localhost:3000/api/v1/documents//tags \ + -H "Authorization: Bearer " \ + -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 " +``` + +**Get documents with a tag:** +```bash +curl http://localhost:3000/api/v1/tags/backend \ + -H "Authorization: Bearer " +``` + +## 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)