apeman-app-rest
Version:
apeman app to handle restful endpoint.
882 lines (843 loc) • 23.2 kB
JavaScript
/**
* Test case for create.
* Runs with mocha.
*/
const create = require('../lib/create.js')
const apemanport = require('apemanport')
const fs = require('fs')
const uuid = require('uuid')
const assert = require('assert')
const path = require('path')
const apemandb = require('apemandb')
const apemanApp = require('apeman-app')
const apemanmodel = require('apemanmodel')
const apemanrequest = require('apemanrequest')
const apemansleep = require('apemansleep')
const loc = require('../doc/mocks/locales')
const co = require('co')
const tmpDir = path.join(__dirname, '/../tmp')
const dbFile = tmpDir + '/testing-db01.db'
/* global describe, before, after, it */
describe('create', function () {
this.timeout(8000)
let sleep = apemansleep.create({})
let db, request, baseUrl, server
before(() => co(function * () {
request = apemanrequest.create({ jar: true })
db = apemandb({
env: {
DATABASE: 'testing-database02',
USERNAME: 'FOO',
PASSWORD: 'BAR',
DIALECT: 'sqlite',
STORAGE: dbFile,
LOGGING: false
},
models: `${apemanmodel.paths.SAMPLE_DEFS_DIR}/*.json`
})
yield db.sync({ force: true })
}))
before(() => co(function * () {
let port = yield apemanport.find()
server = yield apemanApp('testing-app', {
port,
configuration: {
$apps: {
'testing-app': {
'/': [
require('apeman-app-body')(),
require('apeman-app-link')({
protocol: 'http'
}),
require('apeman-app-locale')(
loc
),
require('apeman-app-jsonapi')()
],
'/api': [
create(db.models.User, {
pathname: '/users',
list: co.wrap(function * listWrap (ctx, next) {
ctx.set('test-before-list', true)
yield next()
ctx.set('test-after-list', true)
}),
create: {
schema: require('../doc/mocks/schemas/user.schema.json'),
handle: co.wrap(function * createWrap (ctx, next) {
ctx.set('test-before-create', true)
yield next()
ctx.set('test-after-create', true)
})
},
one: co.wrap(function * oneWrap (ctx, next) {
ctx.set('test-before-one', true)
yield next()
}),
update: co.wrap(function * updateWrap (ctx, next) {
ctx.set('test-before-update', true)
yield next()
}),
destroy: co.wrap(function * destroyWrap (ctx, next) {
ctx.set('test-before-destroy', true)
yield next()
}),
bulkDestroy: co.wrap(function * bulkDestroyWrap (ctx, next) {
ctx.set('test-before-destroy-bulk', true)
yield next()
})
}),
create(db.models.UserSign, {
pathname: '/signs'
})
]
}
}
}
})
baseUrl = `http://localhost:${port}`
}))
after(() => co(function * () {
yield sleep.sleep(100)
fs.unlinkSync(dbFile)
}))
after(() => co(function * () {
yield server.close()
}))
let user01, user02, user03, user04,
profile02, sign04
it('Endpoint spec', () => co(function * () {
let res = yield request({
method: 'OPTIONS',
url: `${baseUrl}/api/users`,
json: true
})
let { body, statusCode } = res
assert.equal(statusCode, 200)
assert.ok(body)
}))
it('List users', () => co(function * () {
let res = yield request({
method: 'GET',
url: `${baseUrl}/api/users`,
json: true
})
let { body, headers, statusCode } = res
assert.equal(statusCode, 200)
assert.ok(headers[ 'test-before-list' ])
assert.ok(headers[ 'test-after-list' ])
assert.equal(body.data.length, 0)
assert.equal(body.meta.total, 0)
}))
it('Create user', () => co(function * () {
{
let res = yield request({
method: 'POST',
url: `${baseUrl}/api/users/`,
json: true,
body: {
data: {
type: 'users',
attributes: {
email: 'apbc@example.com'
}
}
}
})
let { body, statusCode } = res
assert.equal(statusCode, 400)
let { errors } = body
assert.equal(errors[ 0 ].source.pointer, '/data/attributes/key')
}
{
let res = yield request({
method: 'POST',
url: `${baseUrl}/api/users/`,
json: true,
body: {
data: {
type: 'users',
attributes: {
key: 'foo_bar',
email: 'apbc@example.com'
}
}
}
})
let { body, headers, statusCode } = res
assert.equal(statusCode, 201)
assert.ok(body.links.self)
let { data } = body
user01 = Object.assign(
{},
data.attributes,
{ id: data.id }
)
assert.ok(!headers[ 'test-before-list' ])
assert.ok(headers[ 'test-before-create' ])
}
}))
it('Create user 2', () => co(function * () {
{
let res = yield request({
method: 'POST',
url: `${baseUrl}/api/users/`,
json: true,
body: {
data: {
type: '__invalid_types__',
attributes: {
key: 'foo_bar2_fail',
email: 'apbc2_fail@example.com'
}
}
}
})
let { body } = res
assert.equal(body.meta.action, 'create')
assert.equal(body.errors[ 0 ].title, 'RESOURCE_TYPE_INVALID_ERROR')
}
{
let res = yield request({
method: 'POST',
url: `${baseUrl}/api/users/`,
json: true,
body: {
data: {
type: 'users',
attributes: {
key: 'foo_bar2',
email: 'apbc2@example.com'
}
}
}
})
let { body } = res
assert.equal(res.statusCode, 201)
let { data } = body
user02 = Object.assign(
{},
data.attributes,
{ id: data.id }
)
let headers = res.headers
assert.ok(headers[ 'test-before-create' ])
}
}))
it('Bulk create users', () => co(function * () {
let res = yield request({
method: 'POST',
url: `${baseUrl}/api/users/`,
json: true,
body: {
data: [
{
type: 'users',
attributes: {
key: 'foo_bar3',
email: 'apbc3@example.com'
}
},
{
type: 'users',
id: uuid.v4(),
attributes: {
key: 'foo_bar4',
email: 'apbc4@example.com'
}
}
]
}
})
let { body } = res
let { meta } = body
let { data } = body
assert.equal(meta.action, 'bulkCreate')
assert.equal(meta.status, 201)
assert.equal(data.length, 2)
user03 = Object.assign({ id: data[ 0 ].id }, data[ 0 ].attributes)
user04 = Object.assign({ id: data[ 1 ].id }, data[ 1 ].attributes)
}))
it('Bulk update users', () => co(function * () {
let res = yield request({
method: 'PATCH',
url: `${baseUrl}/api/users/`,
json: true,
body: {
data: [
{
type: 'users',
id: user03.id,
attributes: {
email: 'apbc3_updated@example.com'
}
},
{
type: 'users',
id: user04.id,
attributes: {
email: 'apbc4_updated@example.com'
}
}
]
}
})
let { body } = res
let { meta } = body
let { data } = body
assert.equal(meta.action, 'bulkUpdate')
assert.equal(data.length, 2)
assert.equal(data[ 0 ].attributes.email, 'apbc3_updated@example.com')
}))
it('One user', () => co(function * () {
let relatedLink, relationLink
{
let res = yield request({
method: 'GET',
url: `${baseUrl}/api/users/${user02.id}`,
json: true
})
let { body, headers, statusCode } = res
assert.equal(statusCode, 200)
let { data } = body
assert.equal(data.id, user02.id)
assert.ok(headers[ 'test-before-one' ])
relationLink = data.relationships.profile.links.self
relatedLink = data.relationships.profile.links.related
assert.ok(
relatedLink.match(
'/api/users/2/profile'
)
)
assert.ok(
relationLink.match(
'/api/users/2/relationships/profile'
)
)
assert.ok(
relatedLink.match(
'/api/users/2/profile'
)
)
}
{
let res = yield request({
method: 'GET',
url: relatedLink,
json: true
})
let { body } = res
assert.equal(res.statusCode, 200)
assert.equal(body.meta.action, 'relatedList')
}
{
let res = yield request({
method: 'GET',
url: relationLink,
json: true
})
let { body } = res
assert.equal(res.statusCode, 200)
assert.equal(body.meta.action, 'relationList')
assert.equal(body.links.self, relationLink)
assert.equal(body.links.related, relatedLink)
}
}))
it('Create invalid id', () => co(function * () {
let res = yield request({
method: 'GET',
url: baseUrl + '/api/users/999999999999',
json: true
})
let { body } = res
assert.ok(body)
assert.equal(res.statusCode, 404)
let headers = res.headers
assert.ok(headers[ 'test-before-one' ])
}))
it('Update user.', () => co(function * () {
{
let res = yield request({
method: 'PATCH',
url: `${baseUrl}/api/users/` + user02.id,
json: true,
body: {
data: {
attributes: {
key: 'foo_bar2_updated',
vr: user02.vr
}
}
}
})
let { body } = res
assert.equal(res.statusCode, 400)
let errors = body.errors
assert.equal(errors[ 0 ].source.pointer, '/data/type')
}
{
let res = yield request({
method: 'PATCH',
url: `${baseUrl}/api/users/${user02.id}`,
json: true,
body: {
data: {
type: 'users',
attributes: {
key: 'foo_bar2_updated',
vr: user02.vr
}
}
}
})
let { body } = res
assert.equal(res.statusCode, 200)
let { data } = body
assert.equal(data.id, data.id)
assert.equal(data.attributes.key, 'foo_bar2_updated')
let headers = res.headers
assert.ok(headers[ 'test-before-update' ])
}
}))
it('Update user with conflict.', () => co(function * () {
let res = yield request({
method: 'PATCH',
url: `${baseUrl}/api/users/` + user02.id,
json: true,
body: {
data: {
type: 'users',
attributes: {
key: 'foo_bar2_updated',
vr: 1
}
}
}
})
let { body } = res
assert.equal(res.statusCode, 409)
assert.ok(body)
}))
it('Create user profile.', () => co(function * () {
let res = yield request({
method: 'POST',
url: `${baseUrl}/api/users/${user02.id}/profile`,
json: true,
body: {
data: {
type: 'user_profiles',
attributes: {
name: 'Profile of user02'
}
}
}
})
let { body } = res
assert.equal(res.statusCode, 201)
let { meta } = body
let { data } = body
assert.equal(meta.action, 'relatedCreate')
assert.equal(data.type, 'user_profiles')
assert.equal(data.attributes.userId, 2)
profile02 = Object.assign({ id: data.id }, data.attributes)
}))
it('Update user profile.', () => co(function * () {
let res = yield request({
method: 'PATCH',
url: `${baseUrl}/api/users/` + user02.id + '/profile/' + profile02.id,
json: true,
body: {
data: {
type: 'user_profiles',
attributes: {
name: 'Profile of user02'
}
}
}
})
let { body } = res
assert.equal(res.statusCode, 200)
let { meta } = body
let data = body.data
let links = body.links
assert.equal(meta.action, 'relatedUpdate')
assert.equal(data.type, 'user_profiles')
assert.equal(data.attributes.name, 'Profile of user02')
assert.ok(links.self.match('/api/users/2/profile/1'))
}))
it('List user profiles.', () => co(function * () {
let res = yield request({
method: 'GET',
url: `${baseUrl}/api/users/${user02.id}/profile`,
json: true,
body: {}
})
let { body } = res
assert.equal(res.statusCode, 200)
let { meta } = body
let data = body.data
assert.equal(data.id, profile02.id)
assert.equal(meta.action, 'relatedList')
}))
it('Get the user profile.', () => co(function * () {
let res = yield request({
method: 'GET',
url: `${baseUrl}/api/users/` + user02.id + '/profile/' + profile02.id,
json: true,
body: {}
})
let { body } = res
assert.equal(res.statusCode, 200)
let { meta } = body
let data = body.data
assert.equal(data.id, profile02.id)
assert.equal(meta.action, 'relatedOne')
}))
it('Get user include profile.', () => co(function * () {
let res = yield request({
method: 'get',
url: `${baseUrl}/api/users/${user02.id}?include=profile`,
json: true
})
let { body } = res
assert.equal(res.statusCode, 200)
let data = body.data
let included = body.included
assert.equal(included[ 0 ].type, 'user_profiles')
assert.ok(!data.attributes.profile)
}))
it('List users include profile.', () => co(function * () {
let res = yield request({
method: 'get',
url: baseUrl + '/api/users/?include=profile',
json: true
})
let { body } = res
assert.equal(res.statusCode, 200)
let data = body.data
let included = body.included
assert.equal(included[ 0 ].type, 'user_profiles')
assert.equal(included[ 0 ].id, 1)
data.forEach((data) => {
assert.ok(!data.attributes.profile) // Should in included.
assert.ok(data.links.self.match('/api/users/' + data.id))
let profile = data.relationships.profile
assert.ok(profile.links.self)
assert.ok(profile.links.related)
})
}))
it('Remove user profile relation.', () => co(function * () {
let res = yield request({
method: 'DELETE',
url: `${baseUrl}/api/users/${user02.id}/relationships/profile`,
json: true,
body: {
data: [
{ type: 'user_profiles', id: profile02.id }
]
}
})
let { body } = res
assert.equal(res.statusCode, 200)
let { meta } = body
assert.equal(meta.action, 'bulkRelationDestroy')
}))
it('Create user profile relation.', () => co(function * () {
let res = yield request({
method: 'POST',
url: `${baseUrl}/api/users/${user02.id}/relationships/profile`,
json: true,
body: {
data: [
{ type: 'user_profiles', id: profile02.id }
]
}
})
let { body } = res
assert.equal(res.statusCode, 200)
let { meta } = body
assert.equal(meta.action, 'bulkRelationCreate')
}))
it('update user profile relation.', () => co(function * () {
{
let res = yield request({
method: 'PATCH',
url: `${baseUrl}/api/users/` + user02.id + '/relationships/profile',
json: true,
body: {
data: []
}
})
let { body } = res
assert.equal(res.statusCode, 200)
let { meta } = body
assert.equal(meta.action, 'relationUpdate')
}
{
let res = yield request({
method: 'PATCH',
url: `${baseUrl}/api/users/${user02.id}/relationships/profile`,
json: true,
body: {
data: [
{ type: 'user_profiles', id: profile02.id }
]
}
})
let { body } = res
assert.equal(res.statusCode, 200)
let { meta } = body
assert.equal(meta.action, 'relationUpdate')
}
}))
it('Destroy user profile.', () => co(function * () {
let res = yield request({
method: 'DELETE',
url: `${baseUrl}/api/users/${user02.id}/profile/${profile02.id}`,
json: true
})
let { body } = res
assert.equal(res.statusCode, 200)
let { meta } = body
assert.equal(meta.action, 'relatedDestroy')
}))
it('List again', () => co(function * () {
let res = yield request({
method: 'GET',
url: `${baseUrl}/api/users/`,
json: true
})
let { body } = res
assert.equal(res.statusCode, 200)
let { meta } = body
let data = body.data
let links = body.links
assert.equal(data.length, 4)
assert.equal(meta.total, '4')
assert.ok(links)
let headers = res.headers
assert.ok(headers[ 'test-before-list' ])
}))
it('List with limit', () => co(function * () {
let res = yield request({
method: 'GET',
url: baseUrl + '/api/users/?page[size]=1'
})
let { body } = res
assert.equal(res.statusCode, 200)
let { meta, data } = body
assert.equal(data.length, 1)
assert.equal(meta.total, '4')
}))
it('List with keyword.', () => co(function * () {
let res = yield request({
method: 'GET',
url: baseUrl + '/api/users/?filter[key][$like]=%foo_bar2_%'
})
let { body } = res
assert.equal(res.statusCode, 200)
let { meta, data } = body
assert.equal(data.length, 1)
assert.equal(meta.total, '1')
}))
it('Create signs.', () => co(function * () {
{
let res = yield request({
method: 'POST',
url: baseUrl + '/api/signs',
json: true,
body: {
data: [
{
type: 'user_signs',
attributes: {
key: user03.key,
kind: 'user.key',
hash: 'hogehoge',
userId: user03.id
},
relationships: {
user: {
data: [
{ type: 'users', id: user03.id }
]
}
}
},
{
type: 'user_signs',
attributes: {
key: user04.key,
kind: 'user.key',
hash: 'hogehoge',
userId: user04.id
}
}
]
}
})
let { body, statusCode } = res
assert.equal(res.statusCode, 201)
let { meta, data } = body
assert.equal(meta.action, 'bulkCreate')
assert.equal(data[ 0 ].attributes.userId, 3)
sign04 = Object.assign({ id: data[ 1 ].id }, data[ 1 ].attributes)
}
{
let res = yield request({
method: 'POST',
url: `${baseUrl}/api/users/` + user04.id + '/relationships/sign',
json: true,
body: {
data: {
type: 'user_signs',
id: sign04.id
}
}
})
let { body } = res
assert.deepEqual(body.data, { type: 'user_signs', id: '2' })
}
}))
it('Destroy bulk the users', () => co(function * () {
let res = yield request({
method: 'DELETE',
url: baseUrl + '/api/users',
json: true,
body: {
data: [
{ type: 'users', id: user03.id },
{ type: 'users', id: user04.id }
]
}
})
let { body } = res
assert.equal(res.statusCode, 200)
let { meta } = body
assert.equal(meta.count, 2)
let headers = res.headers
assert.ok(headers[ 'test-before-destroy-bulk' ])
}))
it('Bulk destroy the user', () => co(function * () {
let res = yield request({
method: 'DELETE',
url: `${baseUrl}/api/users/${user02.id}`,
json: true
})
let { body } = res
assert.equal(res.statusCode, 200)
let { meta } = body
assert.equal(meta.count, 1)
let headers = res.headers
assert.ok(headers[ 'test-before-destroy' ])
}))
it('Create user and signs', () => co(function * () {
let sign02Signs
let id = uuid.v4()
{
let res = yield request({
method: 'POST',
url: `${baseUrl}/api/users/`,
json: true,
body: {
data: {
type: 'users',
id: id,
attributes: {
key: 'foo_bar5',
email: 'apbc5@example.com'
}
}
}
})
let { body } = res
assert.equal(res.statusCode, 201)
let data = body.data
user02 = Object.assign(
{},
data.attributes,
{ id: data.id }
)
let headers = res.headers
assert.ok(headers[ 'test-before-create' ])
}
{
let res = yield request({
method: 'POST',
url: `${baseUrl}/api/users/${user02.id}/sign`,
json: true,
body: {
data: [
{
type: 'user_signs',
attributes: {
key: user02.key,
kind: 'user.key',
hash: 'hoge'
}
},
{
type: 'user_signs',
attributes: {
key: user02.email,
kind: 'user.email',
hash: 'hoge'
}
}
]
}
})
let { body } = res
assert.equal(res.statusCode, 201)
let data = body.data
assert.equal(data[ 0 ].type, 'user_signs')
sign02Signs = data.map((data) => Object.assign(
{ id: data.id },
data.attributes
))
}
{
let res = yield request({
method: 'PATCH',
url: `${baseUrl}/api/users/` + user02.id + '/sign',
json: true,
body: {
data: sign02Signs.map((sign) =>
({
type: 'user_signs',
id: sign.id,
attributes: {
hash: 'fuge'
}
})
)
}
})
let { body } = res
assert.equal(res.statusCode, 200)
let { meta } = body
let data = body.data
assert.equal(meta.action, 'bulkRelatedUpdate')
assert.equal(data[ 0 ].attributes.hash, 'fuge')
}
{
let res = yield request({
method: 'DELETE',
url: `${baseUrl}/api/users/${user02.id}/sign`,
json: true,
body: {
data: {
type: 'user_signs',
id: sign02Signs[ 0 ].id
}
}
})
let { body } = res
assert.equal(res.statusCode, 200)
let { meta } = body
assert.equal(meta.action, 'bulkRelatedDestroy')
assert.deepEqual(meta, { action: 'bulkRelatedDestroy', count: 1 })
}
}))
})