UNPKG

@getanthill/datastore

Version:

Event-Sourced Datastore

392 lines (368 loc) 10.6 kB
import { MongoDbConnector } from '@getanthill/mongodb-connector'; import * as builder from './builder'; import setup from '../../../test/setup'; import { Services } from '../../typings'; describe('api/spec/builder', () => { let models; let app; let services: Services; let mongodb: MongoDbConnector; const defaultSpec = { components: { schemas: {}, }, }; beforeAll(async () => { app = await setup.build(); services = app.services; mongodb = services.mongodb; models = await setup.initModels(services, []); }); afterEach(async () => { models.reset(); jest.restoreAllMocks(); }); afterAll(async () => { await setup.teardownDb(mongodb); }); describe('build', () => { it('must match empty spec if no model is defined', () => { expect(builder.build(defaultSpec, models)).toMatchSnapshot(); }); it('must match a simple default specification with a very simple model', () => { models.addModel({ db: 'datastore', name: 'users', }); expect(builder.build(defaultSpec, models)).toMatchSnapshot(); }); it('must match a specification with required field on CREATED event', () => { models.addModel({ db: 'datastore', name: 'users', schema: { model: { properties: { firstname: { type: 'string', }, }, }, events: { CREATED: { '0_0_0': { required: ['firstname'], properties: { firstname: { type: 'string', }, }, }, }, }, }, }); expect(builder.build(defaultSpec, models)).toMatchSnapshot(); }); it('must match a specification without default CREATED event', () => { models.addModel({ db: 'datastore', name: 'users', with_default_events: false, schema: { events: {}, }, }); expect(builder.build(defaultSpec, models)).toMatchSnapshot(); }); it('must match a specification with required field on UPDATED event', () => { models.addModel({ db: 'datastore', name: 'users', schema: { model: { properties: { firstname: { type: 'string', }, }, }, events: { UPDATED: { '0_0_0': { required: ['firstname'], properties: { firstname: { type: 'string', }, }, }, }, }, }, }); expect(builder.build(defaultSpec, models)).toMatchSnapshot(); }); it('must match a specification with custom events', () => { models.addModel({ db: 'datastore', name: 'users', schema: { model: { properties: { firstname: { type: 'string', }, }, }, events: { FIRSTNAME_UPDATED: { '0_0_0': { required: ['firstname'], properties: { firstname: { type: 'string', }, }, }, }, }, }, }); expect(builder.build(defaultSpec, models)).toMatchSnapshot(); }); it('must match a specification with custom events and encrypted fields', () => { models.addModel({ db: 'datastore', name: 'users', encrypted_fields: ['firstname'], schema: { model: { properties: { firstname: { type: 'string', }, }, }, events: { FIRSTNAME_UPDATED: { '0_0_0': { 'x-show-handler': true, required: ['firstname'], properties: { firstname: { type: 'string', }, }, }, }, }, }, }); expect(builder.build(defaultSpec, models)).toMatchSnapshot(); }); it('must match a specification with custom events and special responses defined', () => { models.addModel({ db: 'datastore', name: 'users', encrypted_fields: ['firstname'], schema: { model: { properties: { firstname: { type: 'string', }, }, }, events: { FIRSTNAME_UPDATED: { '0_0_0': { required: ['firstname'], properties: { firstname: { type: 'string', }, }, 'x-responses': [ { status: 200, description: 'User created', }, ], }, }, }, }, }); expect(builder.build(defaultSpec, models)).toMatchSnapshot(); }); it('must match a specification with custom events and dedicated handler (`x-show-handler=true`)', () => { models.addModel({ db: 'datastore', name: 'users', encrypted_fields: ['firstname'], schema: { model: { properties: { firstname: { type: 'string', }, }, }, events: { FIRSTNAME_UPDATED: { '0_0_0': { 'x-show-handler': true, handler: `if (state.email_verification_token !== event.email_verification_token) {\n const err = new Error('Invalid email verification token');\n // @ts-ignore\n err.status = 412;\n throw err;\n }\n return [\n Object.assign(Object.assign({}, state), { is_email_verified: true }),\n ];`, required: ['firstname'], properties: { firstname: { type: 'string', }, }, }, }, }, }, }); expect(builder.build(defaultSpec, models)).toMatchSnapshot(); }); it('must match a specification with custom events and dedicated handler (`x-show-handler=unknown`)', () => { models.addModel({ db: 'datastore', name: 'users', encrypted_fields: ['firstname'], schema: { model: { properties: { firstname: { type: 'string', }, }, }, events: { FIRSTNAME_UPDATED: { '0_0_0': { handler: `if (state.email_verification_token !== event.email_verification_token) {\n const err = new Error('Invalid email verification token');\n // @ts-ignore\n err.status = 412;\n throw err;\n }\n return [\n Object.assign(Object.assign({}, state), { is_email_verified: true }),\n ];`, required: ['firstname'], properties: { firstname: { type: 'string', }, }, }, }, }, }, }); expect(builder.build(defaultSpec, models)).toMatchSnapshot(); }); it('must match a specification with custom events but no required field', () => { models.addModel({ db: 'datastore', name: 'users', schema: { model: { properties: { firstname: { type: 'string', }, }, }, events: { FIRSTNAME_UPDATED: { '0_0_0': { required: [], properties: { firstname: { type: 'string', }, }, }, }, }, }, }); expect(builder.build(defaultSpec, models)).toMatchSnapshot(); }); it('must match a specification with specified data processings', () => { models.addModel({ db: 'datastore', name: 'users', processings: [ { field: 'firstname', name: 'Say hello', purpose: 'The objective of this processing is to access the firstname of the user to say hello politely.', persons: ['users'], recipients: ['anthill'], tokens: ['say_hello_processing'], duration_in_seconds: 31536000, }, ], schema: { model: { properties: { firstname: { type: 'string', }, }, }, events: { FIRSTNAME_UPDATED: { '0_0_0': { required: [], properties: { firstname: { type: 'string', }, }, }, }, }, }, }); expect(builder.build(defaultSpec, models)).toMatchSnapshot(); }); it('must match a specification with specified data processings without access tokens', () => { models.addModel({ db: 'datastore', name: 'users', processings: [ { field: 'firstname', name: 'Say hello', purpose: 'The objective of this processing is to access the firstname of the user to say hello politely.', persons: ['users'], recipients: ['anthill'], duration_in_seconds: 31536000, }, ], schema: { model: { properties: { firstname: { type: 'string', }, }, }, events: { FIRSTNAME_UPDATED: { '0_0_0': { required: [], properties: { firstname: { type: 'string', }, }, }, }, }, }, }); expect(builder.build(defaultSpec, models)).toMatchSnapshot(); }); }); });