UNPKG

expeditavoluptas

Version:

TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.

123 lines (94 loc) 5.84 kB
import { Collection, Entity, LoadStrategy, ManyToMany, MikroORM, PopulateHint, PrimaryKey, Property } from '@mikro-orm/core'; import type { AbstractSqlDriver } from '@mikro-orm/knex'; import { mockLogger } from '../helpers'; import { SqliteDriver } from '@mikro-orm/sqlite'; @Entity() export class App { @PrimaryKey() id!: number; @Property() name!: string; @ManyToMany('User', 'apps') users = new Collection<User>(this); } @Entity() export class User { @PrimaryKey() id!: number; @Property() name!: string; @ManyToMany(() => App, a => a.users, { owner: true }) apps = new Collection<App>(this); } describe('GH issue 1041, 1043', () => { let orm: MikroORM<AbstractSqlDriver>; const log = jest.fn(); beforeAll(async () => { orm = await MikroORM.init({ entities: [User, App], dbName: ':memory:', driver: SqliteDriver, }); mockLogger(orm, ['query', 'query-params'], log); await orm.schema.createSchema(); const user = orm.em.create(User, { id: 123, name: 'user' }); const app1 = orm.em.create(App, { id: 1, name: 'app 1' }); const app2 = orm.em.create(App, { id: 2, name: 'app 2' }); const app3 = orm.em.create(App, { id: 3, name: 'app 3' }); user.apps.add(app1, app2, app3); await orm.em.persistAndFlush(user); }); beforeEach(() => { log.mockReset(); orm.em.clear(); }); afterAll(() => orm.close(true)); test('select-in strategy: populate with apps and remove one app', async () => { const user = await orm.em.findOneOrFail(User, { id: 123 }, { populate: ['apps'], strategy: LoadStrategy.SELECT_IN }); const app = user.apps.getItems().find(i => i.id === 2); user.apps.remove(app!); log.mockReset(); await expect(orm.em.flush()).resolves.toBeUndefined(); expect(log.mock.calls[0][0]).toMatch('begin'); expect(log.mock.calls[1][0]).toMatch('delete from `user_apps` where (`app_id`) in ( values (2)) and `user_id` = 123'); expect(log.mock.calls[2][0]).toMatch('commit'); }); test('joined strategy: populate with apps and remove one app', async () => { const user = await orm.em.findOneOrFail(User, { id: 123 }, { populate: ['apps'], strategy: LoadStrategy.JOINED }); const app = user.apps.getItems().find(i => i.id === 3); user.apps.remove(app!); log.mockReset(); await expect(orm.em.flush()).resolves.toBeUndefined(); expect(log.mock.calls[0][0]).toMatch('begin'); expect(log.mock.calls[1][0]).toMatch('delete from `user_apps` where (`app_id`) in ( values (3)) and `user_id` = 123'); expect(log.mock.calls[2][0]).toMatch('commit'); }); test('select-in strategy: find by many-to-many relation ID', async () => { const findPromise = orm.em.findOne(User, { apps: 1 }, { populate: ['apps'], strategy: LoadStrategy.SELECT_IN }); await expect(findPromise).resolves.toBeInstanceOf(User); expect(log.mock.calls[0][0]).toMatch('select `u0`.* from `user` as `u0` left join `user_apps` as `u1` on `u0`.`id` = `u1`.`user_id` where `u1`.`app_id` = 1 limit 1'); expect(log.mock.calls[1][0]).toMatch('select `a0`.*, `u1`.`app_id` as `fk__app_id`, `u1`.`user_id` as `fk__user_id` from `app` as `a0` left join `user_apps` as `u1` on `a0`.`id` = `u1`.`app_id` where `u1`.`user_id` in (123)'); }); test('joined strategy: find by many-to-many relation ID', async () => { const findPromise = orm.em.findOne(User, { apps: 1 }, { populate: ['apps'], strategy: LoadStrategy.JOINED }); await expect(findPromise).resolves.toBeInstanceOf(User); expect(log.mock.calls[0][0]).toMatch('select `u0`.`id`, `u0`.`name`, `a1`.`id` as `a1__id`, `a1`.`name` as `a1__name` from `user` as `u0` left join `user_apps` as `u2` on `u0`.`id` = `u2`.`user_id` left join `app` as `a1` on `u2`.`app_id` = `a1`.`id` where `u2`.`app_id` = 1'); }); test('select-in strategy: find by many-to-many relation IDs (PopulateHint.INFER)', async () => { const findPromise = orm.em.findOne(User, { apps: [1, 2, 3] }, { populate: ['apps'], strategy: LoadStrategy.SELECT_IN, populateWhere: PopulateHint.INFER }); await expect(findPromise).resolves.toBeInstanceOf(User); expect(log.mock.calls[0][0]).toMatch('select `u0`.* from `user` as `u0` left join `user_apps` as `u1` on `u0`.`id` = `u1`.`user_id` where `u1`.`app_id` in (1, 2, 3) limit 1'); expect(log.mock.calls[1][0]).toMatch('select `a0`.*, `u1`.`app_id` as `fk__app_id`, `u1`.`user_id` as `fk__user_id` from `app` as `a0` left join `user_apps` as `u1` on `a0`.`id` = `u1`.`app_id` where `a0`.`id` in (1, 2, 3) and `u1`.`user_id` in (123)'); }); test('select-in strategy: find by many-to-many relation IDs', async () => { const findPromise = orm.em.findOne(User, { apps: [1, 2, 3] }, { populate: ['apps'], strategy: LoadStrategy.SELECT_IN }); await expect(findPromise).resolves.toBeInstanceOf(User); expect(log.mock.calls[0][0]).toMatch('select `u0`.* from `user` as `u0` left join `user_apps` as `u1` on `u0`.`id` = `u1`.`user_id` where `u1`.`app_id` in (1, 2, 3) limit 1'); expect(log.mock.calls[1][0]).toMatch('select `a0`.*, `u1`.`app_id` as `fk__app_id`, `u1`.`user_id` as `fk__user_id` from `app` as `a0` left join `user_apps` as `u1` on `a0`.`id` = `u1`.`app_id` where `u1`.`user_id` in (123)'); }); test('joined strategy: find by many-to-many relation IDs', async () => { const findPromise = orm.em.findOne(User, { apps: [1, 2, 3] }, { populate: ['apps'], strategy: LoadStrategy.JOINED }); await expect(findPromise).resolves.toBeInstanceOf(User); expect(log.mock.calls[0][0]).toMatch('select `u0`.`id`, `u0`.`name`, `a1`.`id` as `a1__id`, `a1`.`name` as `a1__name` from `user` as `u0` left join `user_apps` as `u2` on `u0`.`id` = `u2`.`user_id` left join `app` as `a1` on `u2`.`app_id` = `a1`.`id` where `u2`.`app_id` in (1, 2, 3)'); }); });