Skip to content

Commit 585167e

Browse files
authored
Merge pull request #19 from CrisisTextLine/copilot/fix-4-2
Implement comprehensive static mock JSON:API server with CI/CD workflow for validator testing
2 parents cd742d9 + 9943c80 commit 585167e

11 files changed

Lines changed: 2343 additions & 22 deletions

File tree

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: "Copilot Setup Steps"
2+
3+
# Automatically run the setup steps when they are changed to allow for easy validation, and
4+
# allow manual testing through the repository's "Actions" tab
5+
on:
6+
workflow_dispatch:
7+
push:
8+
paths:
9+
- .github/workflows/copilot-setup-steps.yml
10+
pull_request:
11+
paths:
12+
- .github/workflows/copilot-setup-steps.yml
13+
14+
jobs:
15+
# The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot.
16+
copilot-setup-steps:
17+
runs-on: ubuntu-latest
18+
19+
# Set the permissions to the lowest permissions possible needed for your steps.
20+
# Copilot will be given its own token for its operations.
21+
permissions:
22+
# If you want to clone the repository as part of your setup steps, for example to install dependencies, you'll need the `contents: read` permission. If you don't clone the repository in your setup steps, Copilot will do this for you automatically after the steps complete.
23+
contents: read
24+
25+
# You can define any steps you want, and they will run before the agent starts.
26+
# If you do not check out your code, Copilot will do this for you.
27+
steps:
28+
- name: Checkout code
29+
uses: actions/checkout@v5
30+
31+
- name: Set up Node.js
32+
uses: actions/setup-node@v4
33+
with:
34+
node-version: "20"
35+
cache: "npm"
36+
37+
- name: Install JavaScript dependencies
38+
run: npm ci
39+
40+
- name: Display setup summary
41+
run: |
42+
echo "✅ Setup completed successfully!"
43+
echo "📦 Dependencies installed via npm ci"
44+
echo "🔍 Code linting passed"
45+
echo "🏗️ SPA build completed"
46+
echo "🚀 Mock server verified functional"
47+
echo "🧪 Test script prepared"
48+
echo ""
49+
echo "Both the JSON:API validator SPA and mock server are ready for development and testing."

mock-server/README.md

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
# Mock JSON:API Server Documentation
2+
3+
## Overview
4+
5+
This mock server provides JSON:API v1.1 compliant endpoints for testing the validator application. It includes both valid endpoints and intentionally invalid ones for comprehensive testing.
6+
7+
## Running the Mock Server
8+
9+
```bash
10+
# Run mock server only
11+
npm run mock-server
12+
13+
# Run both validator app and mock server concurrently
14+
npm start
15+
# or
16+
npm run dev:full
17+
```
18+
19+
The mock server runs on `http://localhost:3001` by default.
20+
21+
## Available Endpoints
22+
23+
### Root API Endpoint
24+
25+
- **GET** `/api` - API information and endpoint list
26+
27+
### Articles Resource
28+
29+
- **GET** `/api/articles` - List all articles with pagination, filtering, sorting, and compound documents
30+
- **GET** `/api/articles/:id` - Get individual article
31+
- **POST** `/api/articles` - Create new article
32+
- **PATCH** `/api/articles/:id` - Update article
33+
- **DELETE** `/api/articles/:id` - Delete article
34+
35+
#### Relationship Endpoints
36+
- **GET** `/api/articles/:id/author` - Get related author
37+
- **GET** `/api/articles/:id/comments` - Get related comments
38+
39+
### People Resource
40+
41+
- **GET** `/api/people` - List all people
42+
- **GET** `/api/people/:id` - Get individual person
43+
44+
### Comments Resource
45+
46+
- **GET** `/api/comments` - List all comments
47+
- **GET** `/api/comments/:id` - Get individual comment
48+
49+
### Health Check
50+
51+
- **GET** `/health` - Server health check (returns `application/json`)
52+
53+
## Supported JSON:API Features
54+
55+
### Query Parameters
56+
57+
#### Pagination
58+
```
59+
GET /api/articles?page[size]=5&page[number]=2
60+
```
61+
62+
#### Sorting
63+
```
64+
GET /api/articles?sort=title # Ascending
65+
GET /api/articles?sort=-publishedAt # Descending
66+
GET /api/articles?sort=title,-publishedAt # Multiple fields
67+
```
68+
69+
#### Filtering
70+
```
71+
GET /api/articles?filter[title]=JSON:API # Filter by title
72+
GET /api/articles?filter[tags]=tutorial # Filter by tags
73+
```
74+
75+
#### Sparse Fieldsets
76+
```
77+
GET /api/articles?fields[articles]=title,body
78+
GET /api/articles?fields[people]=firstName,lastName
79+
```
80+
81+
#### Including Related Resources
82+
```
83+
GET /api/articles?include=author # Include author
84+
GET /api/articles?include=author,comments # Include multiple
85+
GET /api/articles/1?include=author # Include on single resource
86+
```
87+
88+
### Request/Response Examples
89+
90+
#### GET Collection with Features
91+
```bash
92+
curl -H "Accept: application/vnd.api+json" \
93+
"http://localhost:3001/api/articles?include=author&sort=title&page[size]=2&fields[articles]=title"
94+
```
95+
96+
#### POST Create Resource
97+
```bash
98+
curl -X POST \
99+
-H "Content-Type: application/vnd.api+json" \
100+
-H "Accept: application/vnd.api+json" \
101+
-d '{
102+
"data": {
103+
"type": "articles",
104+
"attributes": {
105+
"title": "New Article",
106+
"body": "This is a new article for testing."
107+
}
108+
}
109+
}' \
110+
http://localhost:3001/api/articles
111+
```
112+
113+
#### PATCH Update Resource
114+
```bash
115+
curl -X PATCH \
116+
-H "Content-Type: application/vnd.api+json" \
117+
-H "Accept: application/vnd.api+json" \
118+
-d '{
119+
"data": {
120+
"id": "1",
121+
"type": "articles",
122+
"attributes": {
123+
"title": "Updated Title"
124+
}
125+
}
126+
}' \
127+
http://localhost:3001/api/articles/1
128+
```
129+
130+
## Sample Data Structure
131+
132+
The server includes sample data for:
133+
134+
### Articles
135+
- 3 sample articles with relationships to authors and comments
136+
- Each article has `title`, `body`, `publishedAt`, and `tags` attributes
137+
- Articles have relationships to `author` (people) and `comments`
138+
139+
### People
140+
- 2 sample people/authors
141+
- Each person has `firstName`, `lastName`, `email`, and `bio` attributes
142+
- People have relationships to their `articles`
143+
144+
### Comments
145+
- 3 sample comments on various articles
146+
- Each comment has `body` and `createdAt` attributes
147+
- Comments have relationships to their `article` and `author`
148+
149+
## Invalid Endpoints for Testing
150+
151+
These endpoints return intentionally invalid JSON:API responses to test validator error detection:
152+
153+
### Structure Violations
154+
- `GET /api/invalid/no-jsonapi` - Missing required `jsonapi` member
155+
- `GET /api/invalid/missing-id` - Resources missing required `id` field
156+
- `GET /api/invalid/missing-type` - Resources missing required `type` field
157+
- `GET /api/invalid/empty-document` - Document with no `data`, `errors`, or `meta`
158+
- `GET /api/invalid/data-and-errors` - Document with both `data` and `errors` (forbidden)
159+
160+
### Content-Type Issues
161+
- `GET /api/invalid/wrong-content-type` - Returns `application/json` instead of `application/vnd.api+json`
162+
163+
### Relationship Issues
164+
- `GET /api/invalid/malformed-relationship` - Invalid relationship structure
165+
166+
### Error Format Issues
167+
- `GET /api/invalid/malformed-errors` - Errors array contains non-objects
168+
- `GET /api/invalid/status-mismatch` - HTTP status doesn't match response content
169+
170+
### Performance Testing
171+
- `GET /api/invalid/timeout` - Simulates slow/timeout response (30 second delay)
172+
173+
### Member Name Issues
174+
- `GET /api/invalid/reserved-chars` - Uses invalid member names with reserved characters
175+
176+
## Content Negotiation
177+
178+
The server properly handles JSON:API content negotiation:
179+
180+
- All responses (except `/health`) use `Content-Type: application/vnd.api+json`
181+
- POST/PATCH requests must include `Content-Type: application/vnd.api+json`
182+
- Returns `415 Unsupported Media Type` for incorrect content types on write operations
183+
184+
## Error Handling
185+
186+
The server returns proper JSON:API error responses:
187+
188+
- `404 Not Found` for missing resources
189+
- `415 Unsupported Media Type` for incorrect content types
190+
- `422 Unprocessable Entity` for validation errors
191+
- `500 Internal Server Error` for server errors
192+
193+
All error responses follow JSON:API error object format with `status`, `title`, and `detail` fields.
194+
195+
## CORS Support
196+
197+
The server includes CORS middleware to allow cross-origin requests from the validator frontend running on a different port.
198+
199+
## Testing the Validator
200+
201+
To test the JSON:API validator against this mock server:
202+
203+
1. Start both servers: `npm start`
204+
2. Open the validator at `http://localhost:3000`
205+
3. Configure endpoints using `http://localhost:3001/api/*`
206+
4. Test both valid endpoints (should pass) and invalid endpoints (should fail validation)
207+
208+
### Example Test Cases
209+
210+
| Endpoint | Expected Validator Result |
211+
|----------|---------------------------|
212+
| `http://localhost:3001/api/articles` | ✅ All validations pass |
213+
| `http://localhost:3001/api/articles?include=author` | ✅ Compound document valid |
214+
| `http://localhost:3001/api/invalid/no-jsonapi` | ❌ Missing jsonapi member |
215+
| `http://localhost:3001/api/invalid/wrong-content-type` | ❌ Wrong content type |
216+
| `http://localhost:3001/api/articles/999` | ✅ Proper 404 error format |

0 commit comments

Comments
 (0)