UNPKG

apeman-app-rest

Version:
882 lines (843 loc) 23.2 kB
/** * Test case for create. * Runs with mocha. */ 'use strict' 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 }) } })) })