Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
Hendrixer committed Dec 1, 2018
1 parent 2de078e commit d71b969
Show file tree
Hide file tree
Showing 30 changed files with 582 additions and 192 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# API Design with Node V3
> Lean to build REST and GraphQL API's with node
3 changes: 2 additions & 1 deletion nodemon.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"runOnChangeOnly": false,
"watch": [
"src/**/*.js",
"src/**/*.graphql"
"src/**/*.graphql",
"src/**/*.gql"
],
"env": {
"NODE_ENV": "development"
Expand Down
6 changes: 1 addition & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,18 @@
"license": "MIT",
"scripts": {
"build": "babel src --out-dir dist",
"test": "NODE_ENV=testing jest --forceExit --detectOpenHandles --verbose false",
"test": "NODE_ENV=testing jest --forceExit --detectOpenHandles --silent",
"dev": "nodemon --exec yarn restart",
"restart": "rimraf dist && yarn build && yarn start",
"start": "node dist/index.js"
},
"dependencies": {
"apollo-server": "^2.2.2",
"apollo-server-express": "^2.2.2",
"bcrypt": "^3.0.2",
"body-parser": "^1.18.3",
"cors": "^2.8.5",
"cuid": "^2.1.4",
"dotenv": "^6.1.0",
"express": "^4.16.4",
"graphql": "^14.0.2",
"graphql-tools": "^4.0.3",
"jsonwebtoken": "^8.4.0",
"lodash": "^4.17.11",
"mongoose": "^5.3.13",
Expand Down
32 changes: 18 additions & 14 deletions src/rest/__tests__/routes.spec.js → src/__tests__/server.spec.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import request from 'supertest'
import { app } from '../../server'
import { User } from '../../models'
import { newToken } from '../auth'
import { app } from '../server'
import { User } from '../resources/user/user.model'
import { newToken } from '../utils/auth'
import mongoose from 'mongoose'

describe('rest routes', () => {
describe('server', () => {
let token
beforeEach(async () => {
const user = await User.create({ email: 'a@a.com', password: 'hello' })
Expand All @@ -13,34 +13,38 @@ describe('rest routes', () => {

describe('api auth', () => {
test('api should be locked down', async () => {
const response = await request(app).get('/api/task')
let response = await request(app).get('/api/item')
expect(response.statusCode).toBe(401)

response = await request(app).get('/api/list')
expect(response.statusCode).toBe(401)

response = await request(app).get('/api/user')
expect(response.statusCode).toBe(401)
})

test('passes with JWT', async () => {
const jwt = `Bearer: ${token}`
const jwt = `Bearer ${token}`
const id = mongoose.Types.ObjectId()
const results = await Promise.all([
request(app)
.get('/api/task')
.get('/api/item')
.set('Authorization', jwt),
request(app)
.get(`/api/task/${id}`)
.get(`/api/item/${id}`)
.set('Authorization', jwt),
request(app)
.post('/api/task')
.post('/api/item')
.set('Authorization', jwt),
request(app)
.put(`/api/task/${id}`)
.put(`/api/item/${id}`)
.set('Authorization', jwt),
request(app)
.delete(`/api/task/${id}`)
.delete(`/api/item/${id}`)
.set('Authorization', jwt)
])

results.forEach(res => expect(res.statusCode).not.toBe(404))
results.forEach(res => expect(res.statusCode).not.toBe(401))
})
})

// test('crud routes for list', async () => {})
})
33 changes: 0 additions & 33 deletions src/models/coupon.js

This file was deleted.

3 changes: 0 additions & 3 deletions src/models/index.js

This file was deleted.

56 changes: 0 additions & 56 deletions src/models/product.js

This file was deleted.

18 changes: 18 additions & 0 deletions src/resources/item/__tests__/item.controllers.spec..js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import controllers from '../item.controllers'
import { isFunction } from 'lodash'

describe('item controllers', () => {
test('has crud controllers', () => {
const crudMethods = [
'getOne',
'getMany',
'createOne',
'removeOne',
'updateOne'
]

crudMethods.forEach(name =>
expect(isFunction(controllers[name])).toBe(true)
)
})
})
54 changes: 54 additions & 0 deletions src/resources/item/__tests__/item.model.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Item } from '../item.model'
import mongoose from 'mongoose'

describe('Item model', () => {
describe('schema', () => {
test('name', () => {
const name = Item.schema.obj.name
expect(name).toEqual({
type: String,
required: true,
trim: true,
maxlength: 50
})
})

test('status', () => {
const status = Item.schema.obj.status
expect(status).toEqual({
type: String,
required: true,
enum: ['active', 'complete', 'pastdue'],
default: 'active'
})
})

test('notes', () => {
const notes = Item.schema.obj.notes
expect(notes).toEqual(String)
})

test('due', () => {
const due = Item.schema.obj.due
expect(due).toEqual(Date)
})

test('createdBy', () => {
const createdBy = Item.schema.obj.createdBy
expect(createdBy).toEqual({
type: mongoose.SchemaTypes.ObjectId,
ref: 'user',
required: true
})
})

test('list', () => {
const list = Item.schema.obj.list
expect(list).toEqual({
type: mongoose.SchemaTypes.ObjectId,
ref: 'list',
required: true
})
})
})
})
20 changes: 20 additions & 0 deletions src/resources/item/__tests__/item.router.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import router from '../item.router'

describe('item router', () => {
test('has crud routes', () => {
const routes = [
{ path: '/', method: 'get' },
{ path: '/:id', method: 'get' },
{ path: '/:id', method: 'delete' },
{ path: '/:id', method: 'put' },
{ path: '/', method: 'post' }
]

routes.forEach(route => {
const match = router.stack.find(
s => s.route.path === route.path && s.route.methods[route.method]
)
expect(match).toBeTruthy()
})
})
})
4 changes: 4 additions & 0 deletions src/resources/item/item.controllers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { crudControllers } from '../../utils/crud'
import { Item } from './item.model'

export default crudControllers(Item)
35 changes: 35 additions & 0 deletions src/resources/item/item.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import mongoose from 'mongoose'

const itemSchema = new mongoose.Schema(
{
name: {
type: String,
required: true,
trim: true,
maxlength: 50
},
status: {
type: String,
required: true,
enum: ['active', 'complete', 'pastdue'],
default: 'active'
},
notes: String,
due: Date,
createdBy: {
type: mongoose.SchemaTypes.ObjectId,
ref: 'user',
required: true
},
list: {
type: mongoose.SchemaTypes.ObjectId,
ref: 'list',
required: true
}
},
{ timestamps: true }
)

itemSchema.index({ list: 1, name: 1 }, { unique: true })

export const Item = mongoose.model('item', itemSchema)
19 changes: 19 additions & 0 deletions src/resources/item/item.router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Router } from 'express'
import controllers from './item.controllers'

const router = Router()

// /api/item
router
.route('/')
.get(controllers.getOne)
.post(controllers.createOne)

// /api/item/:id
router
.route('/:id')
.get(controllers.getOne)
.put(controllers.updateOne)
.delete(controllers.removeOne)

export default router
4 changes: 4 additions & 0 deletions src/resources/list/list.controllers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { crudControllers } from '../../utils/crud'
import { List } from './list.model'

export default crudControllers(List)
23 changes: 23 additions & 0 deletions src/resources/list/list.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import mongoose from 'mongoose'

const listSchema = new mongoose.Schema(
{
name: {
type: String,
required: true,
trim: true,
maxlength: 50
},
description: String,
createdBy: {
type: mongoose.SchemaTypes.ObjectId,
ref: 'user',
required: true
}
},
{ timestamps: true }
)

listSchema.index({ user: 1, name: 1 }, { unique: true })

export const List = mongoose.model('list', listSchema)
Loading

0 comments on commit d71b969

Please sign in to comment.