UNPKG

apialize

Version:

Turn a database model into a production ready REST(ish) CRUD API in a few lines.

118 lines (104 loc) 3.44 kB
const express = require('express'); const bodyParser = require('body-parser'); const request = require('supertest'); const { Sequelize, DataTypes } = require('sequelize'); const { list } = require('../src'); async function buildAppAndModels() { const sequelize = new Sequelize('sqlite::memory:', { logging: false }); const Label = sequelize.define( 'Label', { id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true }, name: { type: DataTypes.STRING(100), allowNull: false }, }, { tableName: 'labels', timestamps: false } ); const Artist = sequelize.define( 'Artist', { id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true }, name: { type: DataTypes.STRING(100), allowNull: false }, label_id: { type: DataTypes.INTEGER, allowNull: false }, }, { tableName: 'artists_multi', timestamps: false } ); const Album = sequelize.define( 'Album', { id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true }, title: { type: DataTypes.STRING(100), allowNull: false }, artist_id: { type: DataTypes.INTEGER, allowNull: false }, }, { tableName: 'albums_multi', timestamps: false } ); Artist.belongsTo(Label, { as: 'label', foreignKey: 'label_id' }); Label.hasMany(Artist, { as: 'artists', foreignKey: 'label_id' }); Album.belongsTo(Artist, { as: 'artist', foreignKey: 'artist_id' }); Artist.hasMany(Album, { as: 'albums', foreignKey: 'artist_id' }); await sequelize.sync({ force: true }); const app = express(); app.use(bodyParser.json()); app.use( '/albums', list( Album, { metaShowOrdering: true }, { include: [ { model: Artist, as: 'artist', include: [{ model: Label, as: 'label' }], }, ], } ) ); return { sequelize, Label, Artist, Album, app }; } async function seed(Label, Artist, Album) { const [warner, sony] = await Label.bulkCreate( [{ name: 'Warner' }, { name: 'Sony' }], { returning: true } ); const [prince, beethoven] = await Artist.bulkCreate( [ { name: 'Prince', label_id: warner.id }, { name: 'Ludwig van Beethoven', label_id: sony.id }, ], { returning: true } ); await Album.bulkCreate([ { title: '1999', artist_id: prince.id }, { title: 'Symphony No. 5', artist_id: beethoven.id }, { title: 'Purple Rain', artist_id: prince.id }, ]); } function titles(res) { return res.body.data.map((r) => r.title); } describe('list: multi-level include filtering and ordering', () => { let sequelize; afterEach(async () => { if (sequelize) { await sequelize.close(); sequelize = null; } }); test('filter by artist.label.name and order by artist.label.name then artist.name', async () => { const ctx = await buildAppAndModels(); sequelize = ctx.sequelize; const { Label, Artist, Album, app } = ctx; await seed(Label, Artist, Album); const res = await request(app).get( '/albums?artist.label.name=warner&api:order_by=artist.label.name,artist.name' ); expect(res.status).toBe(200); // Only prince albums (label Warner), ordered by label then artist expect(titles(res)).toEqual(['1999', 'Purple Rain']); expect(res.body.meta.order).toEqual([ ['artist.label.name', 'ASC'], ['artist.name', 'ASC'], ]); }); });