UNPKG

@getanthill/datastore

Version:

Event-Sourced Datastore

900 lines (804 loc) 22 kB
import Model from './Model'; import Datastore from './Datastore'; import usersConfig from '../../test/fixtures/users'; describe('sdk/Model', () => { let client; let model; beforeEach(() => { client = new Datastore(); client.core._axios = { request: jest.fn().mockImplementation(() => ({ data: null })), }; model = new Model(client, usersConfig); }); afterEach(() => { jest.restoreAllMocks(); }); describe('constructor', () => { it('creates a new model client with datastore and model configuration attached', () => { model = new Model(client, usersConfig); expect(model).toHaveProperty('modelConfig'); expect(model).toHaveProperty('datastore'); expect(model.modelConfig).toEqual(usersConfig); expect(model.datastore).toEqual(client); }); }); describe('get name', () => { it('returns the name of the model', () => { expect(model.name).toEqual('users'); }); }); describe('#heartbeat', () => { it('calls the heartbeat route', async () => { await model.heartbeat(); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'get', url: '/heartbeat', headers: { 'force-primary': undefined, }, }); }); }); /** * Admin routes */ describe('#createModel', () => { it('calls the admin create model route', async () => { await model.createModel(); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'post', url: '/api/admin', data: model.modelConfig, headers: { 'force-primary': undefined, }, }); }); }); describe('#updateModel', () => { it('calls the admin update model route', async () => { await model.updateModel(); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'post', url: '/api/admin/users', data: model.modelConfig, headers: { 'force-primary': undefined, }, }); }); }); describe('#createModelIndexes', () => { it('calls the admin create model indexes route', async () => { await model.createModelIndexes({ db: 'datastore', name: 'users', }); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'post', url: '/api/admin/users/indexes', data: model.modelConfig, headers: { 'force-primary': undefined, }, }); }); }); describe('#getSchema', () => { it('calls the admin get model schema route', async () => { await model.getSchema(); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'get', url: '/api/admin/users/schema', headers: { 'force-primary': undefined, }, }); }); }); /** * Non admin routes */ describe('#encryptOne', () => { beforeEach(() => { client.core._axios = { request: jest.fn().mockImplementation(({ data }) => ({ data, })), }; }); it('calls the encrypt model route to encrypt a single object', async () => { await model.encryptOne({ firstname: 'azerty', }); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'post', url: '/api/users/encrypt', params: { fields: [], }, data: [ { firstname: 'azerty', }, ], headers: { 'force-primary': undefined, }, }); }); it('calls the encrypt model route to encrypt a single object on extra encryption fields', async () => { await model.encryptOne( { firstname: 'azerty', }, ['firstname'], ); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'post', url: '/api/users/encrypt', params: { fields: ['firstname'], }, data: [ { firstname: 'azerty', }, ], headers: { 'force-primary': undefined, }, }); }); }); describe('#encryptMany', () => { beforeEach(() => { client.core._axios = { request: jest.fn().mockImplementation(({ data }) => ({ data, })), }; }); it('calls the encrypt model route for all requested objects', async () => { await model.encryptMany([ { firstname: 'azerty', }, { firstname: 'qwerty', }, ]); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'post', url: '/api/users/encrypt', params: { fields: [], }, data: [ { firstname: 'azerty', }, { firstname: 'qwerty', }, ], headers: { 'force-primary': undefined, }, }); }); it('calls the encrypt model route for all requested objects on additional encryption fields', async () => { await model.encryptMany( [ { firstname: 'azerty', }, { firstname: 'qwerty', }, ], ['firstname'], ); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'post', url: '/api/users/encrypt', params: { fields: ['firstname'], }, data: [ { firstname: 'azerty', }, { firstname: 'qwerty', }, ], headers: { 'force-primary': undefined, }, }); }); }); describe('#decryptOne', () => { beforeEach(() => { client.core._axios = { request: jest.fn().mockImplementation(({ data }) => ({ data, })), }; }); it('calls the decrypt model route to decrypt a single object', async () => { await model.decryptOne({ firstname: 'azerty', }); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'post', url: '/api/users/decrypt', params: { fields: [], }, data: [ { firstname: 'azerty', }, ], headers: { 'force-primary': undefined, }, }); }); it('calls the decrypt model route to decrypt a single object on extra encryption fields', async () => { await model.decryptOne( { firstname: 'azerty', }, ['firstname'], ); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'post', url: '/api/users/decrypt', params: { fields: ['firstname'], }, data: [ { firstname: 'azerty', }, ], headers: { 'force-primary': undefined, }, }); }); }); describe('#decryptMany', () => { beforeEach(() => { client.core._axios = { request: jest.fn().mockImplementation(({ data }) => ({ data, })), }; }); it('calls the decrypt model route for all requested objects', async () => { await model.decryptMany([ { firstname: 'azerty', }, { firstname: 'qwerty', }, ]); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'post', url: '/api/users/decrypt', params: { fields: [], }, data: [ { firstname: 'azerty', }, { firstname: 'qwerty', }, ], headers: { 'force-primary': undefined, }, }); }); it('calls the decrypt model route for all requested objects on additional encryption fields', async () => { await model.decryptMany( [ { firstname: 'azerty', }, { firstname: 'qwerty', }, ], ['firstname'], ); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'post', url: '/api/users/decrypt', params: { fields: ['firstname'], }, data: [ { firstname: 'azerty', }, { firstname: 'qwerty', }, ], headers: { 'force-primary': undefined, }, }); }); }); describe('#createOne', () => { it('calls the create model route to create a single object', async () => { await model.createOne({ firstname: 'John', }); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'post', url: '/api/users', data: { firstname: 'John', }, headers: { 'force-primary': undefined, }, }); }); }); describe('#createMany', () => { it('calls the create model route for each object defined in the payloads array', async () => { await model.createMany([ { firstname: 'John', }, { firstname: 'Jack', }, ]); expect(model.datastore.core._axios.request).toHaveReturnedTimes(2); expect(model.datastore.core._axios.request.mock.calls).toEqual([ [ { data: { firstname: 'John' }, method: 'post', url: '/api/users', headers: { 'force-primary': undefined, }, }, ], [ { data: { firstname: 'Jack' }, method: 'post', url: '/api/users', headers: { 'force-primary': undefined, }, }, ], ]); }); }); describe('#create (deprecated)', () => { it('calls the create model route to create a single object', async () => { await model.create({ firstname: 'John', }); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'post', url: '/api/users', data: { firstname: 'John', }, headers: { 'force-primary': undefined, }, }); }); it('calls the create model route for each object defined in the payloads array', async () => { await model.create([ { firstname: 'John', }, { firstname: 'Jack', }, ]); expect(model.datastore.core._axios.request).toHaveReturnedTimes(2); expect(model.datastore.core._axios.request.mock.calls).toEqual([ [ { data: { firstname: 'John' }, method: 'post', url: '/api/users', headers: { 'force-primary': undefined, }, }, ], [ { data: { firstname: 'Jack' }, method: 'post', url: '/api/users', headers: { 'force-primary': undefined, }, }, ], ]); }); }); describe('#updateOne', () => { it('calls the update model route on a single object', async () => { await model.updateOne({ firstname: 'Jack', user_id: 'user_correlation_id', }); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'post', url: '/api/users/user_correlation_id', data: { firstname: 'Jack', }, headers: { 'force-primary': undefined, }, }); }); }); describe('#updateMany', () => { it('calls the update model route for each object defined in the payloads array with the correct correlation_id', async () => { await model.updateMany([ { firstname: 'John', user_id: 'john', }, { firstname: 'Jack', user_id: 'jack', }, ]); expect(model.datastore.core._axios.request).toHaveReturnedTimes(2); expect(model.datastore.core._axios.request.mock.calls).toEqual([ [ { data: { firstname: 'John' }, method: 'post', url: '/api/users/john', headers: { 'force-primary': undefined, }, }, ], [ { data: { firstname: 'Jack' }, method: 'post', url: '/api/users/jack', headers: { 'force-primary': undefined, }, }, ], ]); }); }); describe('#update (deprecated)', () => { it('calls the update model route on a single object', async () => { await model.update({ firstname: 'Jack', user_id: 'user_correlation_id', }); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'post', url: '/api/users/user_correlation_id', data: { firstname: 'Jack', }, headers: { 'force-primary': undefined, }, }); }); it('calls the update model route for each object defined in the payloads array with the correct correlation_id', async () => { await model.update([ { firstname: 'John', user_id: 'john', }, { firstname: 'Jack', user_id: 'jack', }, ]); expect(model.datastore.core._axios.request).toHaveReturnedTimes(2); expect(model.datastore.core._axios.request.mock.calls).toEqual([ [ { data: { firstname: 'John' }, method: 'post', url: '/api/users/john', headers: { 'force-primary': undefined, }, }, ], [ { data: { firstname: 'Jack' }, method: 'post', url: '/api/users/jack', headers: { 'force-primary': undefined, }, }, ], ]); }); }); describe('#apply', () => { it('calls the apply model route', async () => { await model.apply('FIRSTNAME_UPDATED', { firstname: 'Jack', user_id: 'user_correlation_id', }); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'post', url: '/api/users/user_correlation_id/firstname_updated/0_0_0', data: { firstname: 'Jack', }, headers: { 'force-primary': undefined, }, }); }); }); describe('#get', () => { it('calls the get model route', async () => { await model.get('user_correlation_id'); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'get', url: '/api/users/user_correlation_id', headers: { 'force-primary': undefined, }, }); }); }); describe('#count', () => { it('calls the find model route with a pageSize of 0', async () => { client.core._axios = { request: jest.fn().mockImplementation(() => ({ headers: { count: '1', }, })), }; const count = await model.count({ firstname: 'Jack', }); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'get', url: '/api/users', params: { firstname: 'Jack', }, headers: { page: 0, 'page-size': 0, 'force-primary': undefined, }, }); expect(count).toEqual(1); }); }); describe('#find', () => { it('calls the find model route', async () => { await model.find({ firstname: 'Jack', }); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'get', url: '/api/users', params: { firstname: 'Jack', }, headers: { 'force-primary': undefined, }, }); }); }); describe('#events', () => { it('calls the get events model route', async () => { await model.events('user_correlation_id'); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'get', url: '/api/users/user_correlation_id/events', headers: { 'force-primary': undefined, }, }); }); }); describe('#version', () => { it('calls the get version model route', async () => { await model.version('user_correlation_id', 2); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'get', url: '/api/users/user_correlation_id/2', headers: { 'force-primary': undefined, }, }); }); }); describe('#at', () => { it('calls the get at model route', async () => { await model.at('user_correlation_id', '2020-01-01T00:00:00.000Z'); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'get', url: '/api/users/user_correlation_id/2020-01-01T00:00:00.000Z', headers: { 'force-primary': undefined, }, }); }); }); describe('#restore', () => { it('calls the restore model route', async () => { await model.restore('user_correlation_id', 1); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'post', url: '/api/users/user_correlation_id/1/restore', headers: { 'force-primary': undefined, }, }); }); }); describe('#snapshot', () => { it('calls the create snapshot model route', async () => { await model.snapshot('user_correlation_id'); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'post', url: '/api/users/user_correlation_id/snapshot', headers: { 'force-primary': undefined, }, }); }); }); describe('#archive', () => { it('calls the archive model route', async () => { await model.archive('user_correlation_id'); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'post', url: '/api/users/user_correlation_id/archive', params: { deep: false, }, headers: { 'force-primary': undefined, }, }); }); it('calls the archive model route with deep graph request', async () => { await model.archive('user_correlation_id', true); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'post', url: '/api/users/user_correlation_id/archive', params: { deep: true, }, headers: { 'force-primary': undefined, }, }); }); }); describe('#unarchive', () => { it('calls the unarchive model route', async () => { await model.unarchive('user_correlation_id'); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'post', url: '/api/users/user_correlation_id/unarchive', params: { deep: false, }, headers: { 'force-primary': undefined, }, }); }); it('calls the unarchive model route with deep graph request', async () => { await model.unarchive('user_correlation_id', true); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'post', url: '/api/users/user_correlation_id/unarchive', params: { deep: true, }, headers: { 'force-primary': undefined, }, }); }); }); describe('#delete', () => { it('calls the delete model route', async () => { await model.delete('user_correlation_id'); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'delete', url: '/api/users/user_correlation_id', params: { deep: false, }, headers: { 'force-primary': undefined, }, }); }); it('calls the delete model route with deep graph request', async () => { await model.delete('user_correlation_id', true); expect(model.datastore.core._axios.request).toHaveBeenLastCalledWith({ method: 'delete', url: '/api/users/user_correlation_id', params: { deep: true, }, headers: { 'force-primary': undefined, }, }); }); }); describe('#updateOverwhelmingly', () => { it('calls the updateOverwhelmingly model route', async () => { model.datastore.updateOverwhelmingly = jest.fn(); const query = {}; const handler = jest.fn(); const progress = jest.fn(); const pageSize = 1; await model.updateOverwhelmingly(query, handler, progress, pageSize); expect(model.datastore.updateOverwhelmingly).toHaveBeenCalledWith( model.name, query, handler, progress, pageSize, ); }); }); describe('typing', () => { interface User { firstname: string; lastname?: string; } it('instanciates a new Model with this type in return', async () => { const User = new Model<User>(client, usersConfig); client.core._axios = { request: jest.fn().mockImplementation((r) => ({ data: r.data })), }; const user = await User.createOne({ firstname: 'John', }); const users = await User.find({ firstname: 'John' }); }); }); });