Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Test CI

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
build:
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [18.x]

steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- run: npm install
- run: npm test
Empty file removed .gitkeep
Empty file.
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# API Standard RFC7807

![CI](https://github.com/NeaDigitra/API-Standard-RFC7807/actions/workflows/test.yml/badge.svg)

A production-ready Express.js API boilerplate implementing **RFC7807 Problem Details** standard, configurable error documentation, and universal success/error responses. Built for scalable API development with clean PR history and coding standards.

---
Expand All @@ -12,6 +14,7 @@ A production-ready Express.js API boilerplate implementing **RFC7807 Problem Det
* ✅ **Environment-based config with dotenv**
* ✅ **Example API route with validation**
* ✅ **Express 5 ready**
* ✅ **Built-in unit tests with Jest + node-mocks-http**

---

Expand All @@ -30,6 +33,10 @@ src/
└── utils/
├── sendProblem.js # RFC7807 error response helper
└── sendSuccess.js # Success response helper
test/
├── errorDocPage.test.js # Unit test for HTML generator
├── sendProblem.test.js # Unit test for RFC7807 helper
└── sendSuccess.test.js # Unit test for success helper
```

---
Expand All @@ -50,7 +57,8 @@ ERROR_BASE_URL=https://api.domain.com/errors

```bash
npm install
node src/app.js
npm test # run unit tests
npm start # start the server
```

* Access API: `http://localhost:3000/api/example?email=test@example.com`
Expand Down
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"description": "API Standard RFC7807 implementation for error and success response, including documentation generator for organizations.",
"main": "index.js",
"scripts": {
"start": "node src/app.js"
"start": "node src/app.js",
"test": "jest"
},
"repository": {
"type": "git",
Expand All @@ -19,5 +20,9 @@
"dependencies": {
"dotenv": "^17.0.1",
"express": "^5.1.0"
},
"devDependencies": {
"jest": "^30.0.4",
"node-mocks-http": "^1.17.2"
}
}
Empty file removed src/.keep
Empty file.
Empty file removed src/middleware/.keep
Empty file.
Empty file removed src/routes/.keep
Empty file.
Empty file removed src/utils/.keep
Empty file.
Empty file removed test/.keep
Empty file.
12 changes: 12 additions & 0 deletions test/errorDocPage.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const errorDocPage = require('../src/middleware/errorDocPage')

test('should return HTML for known error key', () => {
const html = errorDocPage('validation')
expect(html).toMatch(/<!DOCTYPE html>/)
expect(html).toMatch(/Validation Failed/)
})

test('should return null for unknown error key', () => {
const html = errorDocPage('unknown')
expect(html).toBeNull()
})
14 changes: 14 additions & 0 deletions test/sendProblem.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const sendProblem = require('../src/utils/sendProblem')
const httpMocks = require('node-mocks-http')

test('should return RFC7807 validation error response', () => {
const response = httpMocks.createResponse()
sendProblem(response, 422, 'validation', 'Input invalid.', '/api/example', { email: ['Invalid'] })
const data = response._getJSONData()
expect(response.statusCode).toBe(422)
expect(response.getHeader('Content-Type')).toMatch(/application\/json/)
expect(data.type).toMatch(/validation$/)
expect(data.title).toBe('Validation Failed')
expect(data.detail).toBe('Input invalid.')
expect(data.errors).toHaveProperty('email')
})
13 changes: 13 additions & 0 deletions test/sendSuccess.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const sendSuccess = require('../src/utils/sendSuccess')
const httpMocks = require('node-mocks-http')

test('should return success response with data', () => {
const response = httpMocks.createResponse()
sendSuccess(response, { test: true }, 'Success')
const data = response._getJSONData()
expect(response.statusCode).toBe(200)
expect(response.getHeader('Content-Type')).toMatch(/application\/json/)
expect(data.status).toBe(200)
expect(data.message).toBe('Success')
expect(data.data.test).toBe(true)
})