| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047 |
- import {expect} from 'chai';
- import {Schema} from '../schema.js';
- import {format} from '@e22m4u/format';
- import {DataType} from '../definition/index.js';
- import {RelationType} from '../definition/index.js';
- import {BelongsToResolver} from './belongs-to-resolver.js';
- import {DEFAULT_PRIMARY_KEY_PROPERTY_NAME as DEF_PK} from '../definition/index.js';
- describe('BelongsToResolver', function () {
- describe('includeTo', function () {
- it('requires the "entities" parameter to be an array', async function () {
- const S = new Schema();
- const R = S.get(BelongsToResolver);
- const error = v =>
- format(
- 'The parameter "entities" of BelongsToResolver.includeTo requires ' +
- 'an Array of Object, but %s given.',
- v,
- );
- const throwable = v =>
- R.includeTo(v, 'sourceName', 'targetName', 'relationName');
- await expect(throwable('')).to.be.rejectedWith(error('""'));
- await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
- await expect(throwable(10)).to.be.rejectedWith(error('10'));
- await expect(throwable(true)).to.be.rejectedWith(error('true'));
- await expect(throwable(false)).to.be.rejectedWith(error('false'));
- await expect(throwable({})).to.be.rejectedWith(error('Object'));
- await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
- await expect(throwable(null)).to.be.rejectedWith(error('null'));
- });
- it('requires elements of the "entities" parameter to be an Object', async function () {
- const S = new Schema();
- const R = S.get(BelongsToResolver);
- const error = v =>
- format(
- 'The parameter "entities" of BelongsToResolver.includeTo requires ' +
- 'an Array of Object, but %s given.',
- v,
- );
- const throwable = v =>
- R.includeTo([v], 'sourceName', 'targetName', 'relationName');
- await expect(throwable('')).to.be.rejectedWith(error('""'));
- await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
- await expect(throwable(10)).to.be.rejectedWith(error('10'));
- await expect(throwable(true)).to.be.rejectedWith(error('true'));
- await expect(throwable(false)).to.be.rejectedWith(error('false'));
- await expect(throwable([])).to.be.rejectedWith(error('Array'));
- await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
- await expect(throwable(null)).to.be.rejectedWith(error('null'));
- });
- it('requires the "sourceName" parameter to be a non-empty string', async function () {
- const S = new Schema();
- const R = S.get(BelongsToResolver);
- const error = v =>
- format(
- 'The parameter "sourceName" of BelongsToResolver.includeTo requires ' +
- 'a non-empty String, but %s given.',
- v,
- );
- const throwable = v => R.includeTo([], v, 'targetName', 'relationName');
- await expect(throwable('')).to.be.rejectedWith(error('""'));
- await expect(throwable(10)).to.be.rejectedWith(error('10'));
- await expect(throwable(true)).to.be.rejectedWith(error('true'));
- await expect(throwable(false)).to.be.rejectedWith(error('false'));
- await expect(throwable([])).to.be.rejectedWith(error('Array'));
- await expect(throwable({})).to.be.rejectedWith(error('Object'));
- await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
- await expect(throwable(null)).to.be.rejectedWith(error('null'));
- });
- it('requires the "targetName" parameter to be a non-empty string', async function () {
- const S = new Schema();
- const R = S.get(BelongsToResolver);
- const error = v =>
- format(
- 'The parameter "targetName" of BelongsToResolver.includeTo requires ' +
- 'a non-empty String, but %s given.',
- v,
- );
- const throwable = v => R.includeTo([], 'sourceName', v, 'relationName');
- await expect(throwable('')).to.be.rejectedWith(error('""'));
- await expect(throwable(10)).to.be.rejectedWith(error('10'));
- await expect(throwable(true)).to.be.rejectedWith(error('true'));
- await expect(throwable(false)).to.be.rejectedWith(error('false'));
- await expect(throwable([])).to.be.rejectedWith(error('Array'));
- await expect(throwable({})).to.be.rejectedWith(error('Object'));
- await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
- await expect(throwable(null)).to.be.rejectedWith(error('null'));
- });
- it('requires the "relationName" parameter to be a non-empty string', async function () {
- const S = new Schema();
- const R = S.get(BelongsToResolver);
- const error = v =>
- format(
- 'The parameter "relationName" of BelongsToResolver.includeTo requires ' +
- 'a non-empty String, but %s given.',
- v,
- );
- const throwable = v => R.includeTo([], 'sourceName', 'targetName', v);
- await expect(throwable('')).to.be.rejectedWith(error('""'));
- await expect(throwable(10)).to.be.rejectedWith(error('10'));
- await expect(throwable(true)).to.be.rejectedWith(error('true'));
- await expect(throwable(false)).to.be.rejectedWith(error('false'));
- await expect(throwable([])).to.be.rejectedWith(error('Array'));
- await expect(throwable({})).to.be.rejectedWith(error('Object'));
- await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
- await expect(throwable(null)).to.be.rejectedWith(error('null'));
- });
- it('requires the provided parameter "foreignKey" to be a string', async function () {
- const S = new Schema();
- const R = S.get(BelongsToResolver);
- const error = v =>
- format(
- 'The provided parameter "foreignKey" of BelongsToResolver.includeTo ' +
- 'should be a String, but %s given.',
- v,
- );
- const throwable = v =>
- R.includeTo([], 'sourceName', 'targetName', 'relationName', v);
- await expect(throwable(10)).to.be.rejectedWith(error('10'));
- await expect(throwable(true)).to.be.rejectedWith(error('true'));
- await expect(throwable([])).to.be.rejectedWith(error('Array'));
- await expect(throwable({})).to.be.rejectedWith(error('Object'));
- });
- it('requires the provided parameter "scope" to be an object', async function () {
- const S = new Schema();
- const R = S.get(BelongsToResolver);
- const error = v =>
- format(
- 'The provided parameter "scope" of BelongsToResolver.includeTo ' +
- 'should be an Object, but %s given.',
- v,
- );
- const throwable = v =>
- R.includeTo(
- [],
- 'sourceName',
- 'targetName',
- 'relationName',
- undefined,
- v,
- );
- await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
- await expect(throwable(10)).to.be.rejectedWith(error('10'));
- await expect(throwable(true)).to.be.rejectedWith(error('true'));
- await expect(throwable([])).to.be.rejectedWith(error('Array'));
- });
- it('throws an error if the given target model is not found', async function () {
- const S = new Schema();
- S.defineModel({name: 'source'});
- const R = S.get(BelongsToResolver);
- const promise = R.includeTo([], 'source', 'target', 'relation');
- await expect(promise).to.be.rejectedWith(
- 'The model "target" is not defined',
- );
- });
- it('throws an error if the given target model does not have a datasource', async function () {
- const S = new Schema();
- S.defineModel({name: 'target'});
- const R = S.get(BelongsToResolver);
- const promise = R.includeTo([], 'source', 'target', 'relation');
- await expect(promise).to.be.rejectedWith(
- 'The model "target" does not have a specified datasource.',
- );
- });
- it('does not throw an error if a relation target is not found', async function () {
- const S = new Schema();
- S.defineDatasource({name: 'datasource', adapter: 'memory'});
- S.defineModel({name: 'source', datasource: 'datasource'});
- S.defineModel({name: 'target', datasource: 'datasource'});
- const sourceRel = S.getRepository('source');
- const source = await sourceRel.create({parentId: 10});
- const R = S.get(BelongsToResolver);
- await R.includeTo([source], 'source', 'target', 'parent');
- expect(source).to.be.eql({
- [DEF_PK]: source[DEF_PK],
- parentId: 10,
- });
- });
- it('includes if a primary key is not defined in the target model', async function () {
- const S = new Schema();
- S.defineDatasource({name: 'datasource', adapter: 'memory'});
- S.defineModel({name: 'source', datasource: 'datasource'});
- S.defineModel({name: 'target', datasource: 'datasource'});
- const sourceRep = S.getRepository('source');
- const targetRep = S.getRepository('target');
- const target = await targetRep.create({});
- expect(target).to.be.eql({[DEF_PK]: target[DEF_PK]});
- const source = await sourceRep.create({parentId: target[DEF_PK]});
- expect(source).to.be.eql({
- [DEF_PK]: source[DEF_PK],
- parentId: target[DEF_PK],
- });
- const R = S.get(BelongsToResolver);
- await R.includeTo([source], 'source', 'target', 'parent');
- expect(source).to.be.eql({
- [DEF_PK]: source[DEF_PK],
- parentId: target[DEF_PK],
- parent: target,
- });
- });
- it('includes if the target model has a custom primary key', async function () {
- const S = new Schema();
- S.defineDatasource({name: 'datasource', adapter: 'memory'});
- S.defineModel({name: 'source', datasource: 'datasource'});
- S.defineModel({
- name: 'target',
- datasource: 'datasource',
- properties: {
- myId: {
- type: DataType.NUMBER,
- primaryKey: true,
- },
- },
- });
- const sourceRep = S.getRepository('source');
- const targetRep = S.getRepository('target');
- const target = await targetRep.create({});
- expect(target).to.be.eql({myId: target.myId});
- const source = await sourceRep.create({parentId: target.myId});
- expect(source).to.be.eql({
- [DEF_PK]: source[DEF_PK],
- parentId: target.myId,
- });
- const R = S.get(BelongsToResolver);
- await R.includeTo([source], 'source', 'target', 'parent');
- expect(source).to.be.eql({
- [DEF_PK]: source[DEF_PK],
- parentId: target.myId,
- parent: target,
- });
- });
- it('includes if the source model has a custom primary key', async function () {
- const S = new Schema();
- S.defineDatasource({name: 'datasource', adapter: 'memory'});
- S.defineModel({
- name: 'source',
- datasource: 'datasource',
- properties: {
- myId: {
- type: DataType.NUMBER,
- primaryKey: true,
- },
- },
- });
- S.defineModel({name: 'target', datasource: 'datasource'});
- const sourceRep = S.getRepository('source');
- const targetRep = S.getRepository('target');
- const target = await targetRep.create({});
- expect(target).to.be.eql({[DEF_PK]: target[DEF_PK]});
- const source = await sourceRep.create({parentId: target[DEF_PK]});
- expect(source).to.be.eql({
- myId: source.myId,
- parentId: target[DEF_PK],
- });
- const R = S.get(BelongsToResolver);
- await R.includeTo([source], 'source', 'target', 'parent');
- expect(source).to.be.eql({
- myId: source.myId,
- parentId: target[DEF_PK],
- parent: target,
- });
- });
- it('includes if the property "foreignKey" is specified', async function () {
- const S = new Schema();
- S.defineDatasource({name: 'datasource', adapter: 'memory'});
- S.defineModel({name: 'source', datasource: 'datasource'});
- S.defineModel({name: 'target', datasource: 'datasource'});
- const sourceRep = S.getRepository('source');
- const targetRep = S.getRepository('target');
- const target = await targetRep.create({});
- expect(target).to.be.eql({[DEF_PK]: target[DEF_PK]});
- const source = await sourceRep.create({parentId: target[DEF_PK]});
- expect(source).to.be.eql({
- [DEF_PK]: source[DEF_PK],
- parentId: target[DEF_PK],
- });
- const R = S.get(BelongsToResolver);
- await R.includeTo([source], 'source', 'target', 'relation', 'parentId');
- expect(source).to.be.eql({
- [DEF_PK]: source[DEF_PK],
- parentId: target[DEF_PK],
- relation: target,
- });
- });
- it('uses a where clause of the given scope to filter the relation target', async function () {
- const S = new Schema();
- S.defineDatasource({name: 'datasource', adapter: 'memory'});
- S.defineModel({name: 'source', datasource: 'datasource'});
- S.defineModel({name: 'target', datasource: 'datasource'});
- const sourceRep = S.getRepository('source');
- const targetRep = S.getRepository('target');
- const target = await targetRep.create({
- foo: 'fooVal',
- bar: 'barVal',
- });
- expect(target).to.be.eql({
- [DEF_PK]: target[DEF_PK],
- foo: 'fooVal',
- bar: 'barVal',
- });
- const source = await sourceRep.create({
- parentId: target[DEF_PK],
- });
- expect(source).to.be.eql({
- [DEF_PK]: source[DEF_PK],
- parentId: target[DEF_PK],
- });
- const R = S.get(BelongsToResolver);
- await R.includeTo([source], 'source', 'target', 'parent', undefined, {
- where: {foo: 'barVal'},
- });
- expect(source).to.be.eql({
- [DEF_PK]: source[DEF_PK],
- parentId: target[DEF_PK],
- });
- await R.includeTo([source], 'source', 'target', 'parent', undefined, {
- where: {foo: 'fooVal'},
- });
- expect(source).to.be.eql({
- [DEF_PK]: source[DEF_PK],
- parentId: target[DEF_PK],
- parent: target,
- });
- });
- it('uses a fields clause of the given scope to filter the relation target', async function () {
- const S = new Schema();
- S.defineDatasource({name: 'datasource', adapter: 'memory'});
- S.defineModel({name: 'source', datasource: 'datasource'});
- S.defineModel({name: 'target', datasource: 'datasource'});
- const sourceRep = S.getRepository('source');
- const targetRep = S.getRepository('target');
- const target = await targetRep.create({
- foo: 'fooVal',
- bar: 'barVal',
- });
- expect(target).to.be.eql({
- [DEF_PK]: target[DEF_PK],
- foo: 'fooVal',
- bar: 'barVal',
- });
- const source = await sourceRep.create({
- parentId: target[DEF_PK],
- });
- expect(source).to.be.eql({
- [DEF_PK]: source[DEF_PK],
- parentId: target[DEF_PK],
- });
- const R = S.get(BelongsToResolver);
- await R.includeTo([source], 'source', 'target', 'parent', undefined, {
- fields: [DEF_PK, 'bar'],
- });
- expect(source).to.be.eql({
- [DEF_PK]: source[DEF_PK],
- parentId: target[DEF_PK],
- parent: {
- [DEF_PK]: target[DEF_PK],
- bar: target.bar,
- },
- });
- });
- it('uses an include clause of the given scope to resolve target relations', async function () {
- const S = new Schema();
- S.defineDatasource({
- name: 'datasource',
- adapter: 'memory',
- });
- S.defineModel({
- name: 'modelA',
- datasource: 'datasource',
- properties: {
- id: {
- type: DataType.NUMBER,
- primaryKey: true,
- },
- source: {
- type: DataType.STRING,
- default: 'modelA',
- },
- },
- });
- S.defineModel({
- name: 'modelB',
- datasource: 'datasource',
- properties: {
- id: {
- type: DataType.NUMBER,
- primaryKey: true,
- },
- source: {
- type: DataType.STRING,
- default: 'modelB',
- },
- },
- relations: {
- parent: {
- type: RelationType.BELONGS_TO,
- model: 'modelA',
- },
- },
- });
- S.defineModel({
- name: 'modelC',
- datasource: 'datasource',
- properties: {
- id: {
- type: DataType.NUMBER,
- primaryKey: true,
- },
- source: {
- type: DataType.STRING,
- default: 'modelC',
- },
- },
- relations: {
- parent: {
- type: RelationType.BELONGS_TO,
- model: 'modelB',
- },
- },
- });
- const aRep = S.getRepository('modelA');
- const bRep = S.getRepository('modelB');
- const cRep = S.getRepository('modelC');
- const a = await aRep.create({});
- const b = await bRep.create({parentId: a.id});
- const c = await cRep.create({parentId: b.id});
- expect(a).to.be.eql({
- id: a.id,
- source: 'modelA',
- });
- expect(b).to.be.eql({
- id: b.id,
- source: 'modelB',
- parentId: a.id,
- });
- expect(c).to.be.eql({
- id: c.id,
- source: 'modelC',
- parentId: b.id,
- });
- const R = S.get(BelongsToResolver);
- await R.includeTo([c], 'modelC', 'modelB', 'parent', undefined, {
- include: 'parent',
- });
- expect(c).to.be.eql({
- id: c.id,
- source: 'modelC',
- parentId: b.id,
- parent: {
- id: b.id,
- source: 'modelB',
- parentId: a.id,
- parent: {
- id: a.id,
- source: 'modelA',
- },
- },
- });
- });
- it('does not break the "and" operator of the given "where" clause', async function () {
- const S = new Schema();
- S.defineDatasource({name: 'datasource', adapter: 'memory'});
- S.defineModel({name: 'source', datasource: 'datasource'});
- S.defineModel({name: 'target', datasource: 'datasource'});
- const sourceRep = S.getRepository('source');
- const targetRep = S.getRepository('target');
- const target = await targetRep.create({
- foo: 'fooVal',
- bar: 'barVal',
- });
- expect(target).to.be.eql({
- [DEF_PK]: target[DEF_PK],
- foo: 'fooVal',
- bar: 'barVal',
- });
- const source = await sourceRep.create({
- parentId: target[DEF_PK],
- });
- expect(source).to.be.eql({
- [DEF_PK]: source[DEF_PK],
- parentId: target[DEF_PK],
- });
- const R = S.get(BelongsToResolver);
- await R.includeTo([source], 'source', 'target', 'parent', undefined, {
- where: {and: [{foo: 'barVal'}]},
- fields: [DEF_PK, 'bar'],
- });
- expect(source).to.be.eql({
- [DEF_PK]: source[DEF_PK],
- parentId: target[DEF_PK],
- });
- await R.includeTo([source], 'source', 'target', 'parent', undefined, {
- where: {and: [{foo: 'fooVal'}]},
- fields: [DEF_PK, 'bar'],
- });
- expect(source).to.be.eql({
- [DEF_PK]: source[DEF_PK],
- parentId: target[DEF_PK],
- parent: {
- [DEF_PK]: target[DEF_PK],
- bar: target.bar,
- },
- });
- });
- });
- describe('includePolymorphicTo', function () {
- it('requires the "entities" parameter to be an array', async function () {
- const S = new Schema();
- const R = S.get(BelongsToResolver);
- const error = v =>
- format(
- 'The parameter "entities" of BelongsToResolver.includePolymorphicTo requires ' +
- 'an Array of Object, but %s given.',
- v,
- );
- const throwable = v =>
- R.includePolymorphicTo(v, 'sourceName', 'relationName');
- await expect(throwable('')).to.be.rejectedWith(error('""'));
- await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
- await expect(throwable(10)).to.be.rejectedWith(error('10'));
- await expect(throwable(true)).to.be.rejectedWith(error('true'));
- await expect(throwable(false)).to.be.rejectedWith(error('false'));
- await expect(throwable({})).to.be.rejectedWith(error('Object'));
- await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
- await expect(throwable(null)).to.be.rejectedWith(error('null'));
- });
- it('requires elements of the "entities" parameter to be an Object', async function () {
- const S = new Schema();
- const R = S.get(BelongsToResolver);
- const error = v =>
- format(
- 'The parameter "entities" of BelongsToResolver.includePolymorphicTo requires ' +
- 'an Array of Object, but %s given.',
- v,
- );
- const throwable = v =>
- R.includePolymorphicTo([v], 'sourceName', 'relationName');
- await expect(throwable('')).to.be.rejectedWith(error('""'));
- await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
- await expect(throwable(10)).to.be.rejectedWith(error('10'));
- await expect(throwable(true)).to.be.rejectedWith(error('true'));
- await expect(throwable(false)).to.be.rejectedWith(error('false'));
- await expect(throwable([])).to.be.rejectedWith(error('Array'));
- await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
- await expect(throwable(null)).to.be.rejectedWith(error('null'));
- });
- it('requires the "sourceName" parameter to be a non-empty string', async function () {
- const S = new Schema();
- const R = S.get(BelongsToResolver);
- const error = v =>
- format(
- 'The parameter "sourceName" of BelongsToResolver.includePolymorphicTo requires ' +
- 'a non-empty String, but %s given.',
- v,
- );
- const throwable = v =>
- R.includePolymorphicTo([], v, 'sourceName', 'relationName');
- await expect(throwable('')).to.be.rejectedWith(error('""'));
- await expect(throwable(10)).to.be.rejectedWith(error('10'));
- await expect(throwable(true)).to.be.rejectedWith(error('true'));
- await expect(throwable(false)).to.be.rejectedWith(error('false'));
- await expect(throwable([])).to.be.rejectedWith(error('Array'));
- await expect(throwable({})).to.be.rejectedWith(error('Object'));
- await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
- await expect(throwable(null)).to.be.rejectedWith(error('null'));
- });
- it('requires the "relationName" parameter to be a non-empty string', async function () {
- const S = new Schema();
- const R = S.get(BelongsToResolver);
- const error = v =>
- format(
- 'The parameter "relationName" of BelongsToResolver.includePolymorphicTo requires ' +
- 'a non-empty String, but %s given.',
- v,
- );
- const throwable = v => R.includePolymorphicTo([], 'sourceName', v);
- await expect(throwable('')).to.be.rejectedWith(error('""'));
- await expect(throwable(10)).to.be.rejectedWith(error('10'));
- await expect(throwable(true)).to.be.rejectedWith(error('true'));
- await expect(throwable(false)).to.be.rejectedWith(error('false'));
- await expect(throwable([])).to.be.rejectedWith(error('Array'));
- await expect(throwable({})).to.be.rejectedWith(error('Object'));
- await expect(throwable(undefined)).to.be.rejectedWith(error('undefined'));
- await expect(throwable(null)).to.be.rejectedWith(error('null'));
- });
- it('requires the provided parameter "foreignKey" to be a string', async function () {
- const S = new Schema();
- const R = S.get(BelongsToResolver);
- const error = v =>
- format(
- 'The provided parameter "foreignKey" of BelongsToResolver.includePolymorphicTo ' +
- 'should be a String, but %s given.',
- v,
- );
- const throwable = v =>
- R.includePolymorphicTo([], 'sourceName', 'relationName', v);
- await expect(throwable(10)).to.be.rejectedWith(error('10'));
- await expect(throwable(true)).to.be.rejectedWith(error('true'));
- await expect(throwable([])).to.be.rejectedWith(error('Array'));
- await expect(throwable({})).to.be.rejectedWith(error('Object'));
- });
- it('requires the provided parameter "discriminator" to be a string', async function () {
- const S = new Schema();
- const R = S.get(BelongsToResolver);
- const error = v =>
- format(
- 'The provided parameter "discriminator" of BelongsToResolver.includePolymorphicTo ' +
- 'should be a String, but %s given.',
- v,
- );
- const throwable = v =>
- R.includePolymorphicTo([], 'sourceName', 'relationName', undefined, v);
- await expect(throwable(10)).to.be.rejectedWith(error('10'));
- await expect(throwable(true)).to.be.rejectedWith(error('true'));
- await expect(throwable([])).to.be.rejectedWith(error('Array'));
- await expect(throwable({})).to.be.rejectedWith(error('Object'));
- });
- it('requires the provided parameter "scope" to be an object', async function () {
- const S = new Schema();
- const R = S.get(BelongsToResolver);
- const error = v =>
- format(
- 'The provided parameter "scope" of BelongsToResolver.includePolymorphicTo ' +
- 'should be an Object, but %s given.',
- v,
- );
- const throwable = v =>
- R.includePolymorphicTo(
- [],
- 'sourceName',
- 'relationName',
- undefined,
- undefined,
- v,
- );
- await expect(throwable('str')).to.be.rejectedWith(error('"str"'));
- await expect(throwable(10)).to.be.rejectedWith(error('10'));
- await expect(throwable(true)).to.be.rejectedWith(error('true'));
- await expect(throwable([])).to.be.rejectedWith(error('Array'));
- });
- it('does not throw an error if a target model is not found', async function () {
- const S = new Schema();
- S.defineModel({name: 'source'});
- const R = S.get(BelongsToResolver);
- const entity = {[DEF_PK]: 1, parentId: 1, parentType: 'target'};
- await R.includePolymorphicTo([entity], 'source', 'parent');
- expect(entity).to.be.eql(entity);
- });
- it('does not throws an error if a target model does not have datasource', async function () {
- const S = new Schema();
- S.defineModel({name: 'source'});
- S.defineModel({name: 'target'});
- const R = S.get(BelongsToResolver);
- const entity = {[DEF_PK]: 1, parentId: 1, parentType: 'target'};
- await R.includePolymorphicTo([entity], 'source', 'parent');
- expect(entity).to.be.eql(entity);
- });
- it('does not throw an error if a relation target is not found', async function () {
- const S = new Schema();
- S.defineDatasource({name: 'datasource', adapter: 'memory'});
- S.defineModel({name: 'source', datasource: 'datasource'});
- S.defineModel({name: 'target', datasource: 'datasource'});
- const sourceRel = S.getRepository('source');
- const source = await sourceRel.create({
- parentId: 10,
- parentType: 'target',
- });
- const R = S.get(BelongsToResolver);
- await R.includePolymorphicTo([source], 'source', 'parent');
- expect(source).to.be.eql({
- [DEF_PK]: source[DEF_PK],
- parentId: 10,
- parentType: 'target',
- });
- });
- it('does not throw an error if no discriminator value', async function () {
- const S = new Schema();
- S.defineModel({name: 'source'});
- const R = S.get(BelongsToResolver);
- const entity = {[DEF_PK]: 1, parentId: 1};
- await R.includePolymorphicTo([entity], 'source', 'parent');
- expect(entity).to.be.eql(entity);
- });
- it('includes if a primary key is not defined in the target model', async function () {
- const S = new Schema();
- S.defineDatasource({name: 'datasource', adapter: 'memory'});
- S.defineModel({name: 'source', datasource: 'datasource'});
- S.defineModel({name: 'target', datasource: 'datasource'});
- const sourceRep = S.getRepository('source');
- const targetRep = S.getRepository('target');
- const target = await targetRep.create({});
- expect(target).to.be.eql({[DEF_PK]: target[DEF_PK]});
- const source = await sourceRep.create({
- parentId: target[DEF_PK],
- parentType: 'target',
- });
- expect(source).to.be.eql({
- [DEF_PK]: source[DEF_PK],
- parentId: target[DEF_PK],
- parentType: 'target',
- });
- const R = S.get(BelongsToResolver);
- await R.includePolymorphicTo([source], 'source', 'parent');
- expect(source).to.be.eql({
- [DEF_PK]: source[DEF_PK],
- parentId: target[DEF_PK],
- parentType: 'target',
- parent: target,
- });
- });
- it('includes if the source model has a custom primary key', async function () {
- const S = new Schema();
- S.defineDatasource({name: 'datasource', adapter: 'memory'});
- S.defineModel({
- name: 'source',
- datasource: 'datasource',
- properties: {
- myId: {
- type: DataType.NUMBER,
- primaryKey: true,
- },
- },
- });
- S.defineModel({name: 'target', datasource: 'datasource'});
- const sourceRep = S.getRepository('source');
- const targetRep = S.getRepository('target');
- const target = await targetRep.create({});
- expect(target).to.be.eql({[DEF_PK]: target[DEF_PK]});
- const source = await sourceRep.create({
- parentId: target[DEF_PK],
- parentType: 'target',
- });
- expect(source).to.be.eql({
- myId: source.myId,
- parentId: target[DEF_PK],
- parentType: 'target',
- });
- const R = S.get(BelongsToResolver);
- await R.includePolymorphicTo([source], 'source', 'parent');
- expect(source).to.be.eql({
- myId: source.myId,
- parentId: target[DEF_PK],
- parentType: 'target',
- parent: target,
- });
- });
- it('includes if the property "foreignKey" is specified', async function () {
- const S = new Schema();
- S.defineDatasource({name: 'datasource', adapter: 'memory'});
- S.defineModel({name: 'source', datasource: 'datasource'});
- S.defineModel({name: 'target', datasource: 'datasource'});
- const sourceRep = S.getRepository('source');
- const targetRep = S.getRepository('target');
- const target = await targetRep.create({});
- expect(target).to.be.eql({[DEF_PK]: target[DEF_PK]});
- const source = await sourceRep.create({
- parentId: target[DEF_PK],
- relationType: 'target',
- });
- expect(source).to.be.eql({
- [DEF_PK]: source[DEF_PK],
- parentId: target[DEF_PK],
- relationType: 'target',
- });
- const R = S.get(BelongsToResolver);
- await R.includePolymorphicTo([source], 'source', 'relation', 'parentId');
- expect(source).to.be.eql({
- [DEF_PK]: source[DEF_PK],
- parentId: target[DEF_PK],
- relationType: 'target',
- relation: target,
- });
- });
- it('includes if the property "discriminator" is specified', async function () {
- const S = new Schema();
- S.defineDatasource({name: 'datasource', adapter: 'memory'});
- S.defineModel({name: 'source', datasource: 'datasource'});
- S.defineModel({name: 'target', datasource: 'datasource'});
- const sourceRep = S.getRepository('source');
- const targetRep = S.getRepository('target');
- const target = await targetRep.create({});
- expect(target).to.be.eql({[DEF_PK]: target[DEF_PK]});
- const source = await sourceRep.create({
- relationId: target[DEF_PK],
- parentType: 'target',
- });
- expect(source).to.be.eql({
- [DEF_PK]: source[DEF_PK],
- relationId: target[DEF_PK],
- parentType: 'target',
- });
- const R = S.get(BelongsToResolver);
- await R.includePolymorphicTo(
- [source],
- 'source',
- 'relation',
- undefined,
- 'parentType',
- );
- expect(source).to.be.eql({
- [DEF_PK]: source[DEF_PK],
- relationId: target[DEF_PK],
- parentType: 'target',
- relation: target,
- });
- });
- it('uses a where clause of the given scope to filter the relation target', async function () {
- const S = new Schema();
- S.defineDatasource({name: 'datasource', adapter: 'memory'});
- S.defineModel({name: 'source', datasource: 'datasource'});
- S.defineModel({name: 'target', datasource: 'datasource'});
- const sourceRep = S.getRepository('source');
- const targetRep = S.getRepository('target');
- const target = await targetRep.create({
- foo: 'fooVal',
- bar: 'barVal',
- });
- expect(target).to.be.eql({
- [DEF_PK]: target[DEF_PK],
- foo: 'fooVal',
- bar: 'barVal',
- });
- const source = await sourceRep.create({
- parentId: target[DEF_PK],
- parentType: 'target',
- });
- expect(source).to.be.eql({
- [DEF_PK]: source[DEF_PK],
- parentId: target[DEF_PK],
- parentType: 'target',
- });
- const R = S.get(BelongsToResolver);
- await R.includePolymorphicTo(
- [source],
- 'source',
- 'parent',
- undefined,
- undefined,
- {where: {foo: 'barVal'}},
- );
- expect(source).to.be.eql({
- [DEF_PK]: source[DEF_PK],
- parentId: target[DEF_PK],
- parentType: 'target',
- });
- await R.includePolymorphicTo(
- [source],
- 'source',
- 'parent',
- undefined,
- undefined,
- {where: {foo: 'fooVal'}},
- );
- expect(source).to.be.eql({
- [DEF_PK]: source[DEF_PK],
- parentId: target[DEF_PK],
- parentType: 'target',
- parent: target,
- });
- });
- it('uses a fields clause of the given scope to filter the relation target', async function () {
- const S = new Schema();
- S.defineDatasource({name: 'datasource', adapter: 'memory'});
- S.defineModel({name: 'source', datasource: 'datasource'});
- S.defineModel({name: 'target', datasource: 'datasource'});
- const sourceRep = S.getRepository('source');
- const targetRep = S.getRepository('target');
- const target = await targetRep.create({
- foo: 'fooVal',
- bar: 'barVal',
- });
- expect(target).to.be.eql({
- [DEF_PK]: target[DEF_PK],
- foo: 'fooVal',
- bar: 'barVal',
- });
- const source = await sourceRep.create({
- parentId: target[DEF_PK],
- parentType: 'target',
- });
- expect(source).to.be.eql({
- [DEF_PK]: source[DEF_PK],
- parentId: target[DEF_PK],
- parentType: 'target',
- });
- const R = S.get(BelongsToResolver);
- await R.includePolymorphicTo(
- [source],
- 'source',
- 'parent',
- undefined,
- undefined,
- {fields: [DEF_PK, 'bar']},
- );
- expect(source).to.be.eql({
- [DEF_PK]: source[DEF_PK],
- parentId: target[DEF_PK],
- parentType: 'target',
- parent: {
- [DEF_PK]: target[DEF_PK],
- bar: target.bar,
- },
- });
- });
- it('uses an include clause of the given scope to resolve target relations', async function () {
- const S = new Schema();
- S.defineDatasource({
- name: 'datasource',
- adapter: 'memory',
- });
- S.defineModel({
- name: 'modelA',
- datasource: 'datasource',
- properties: {
- id: {
- type: DataType.NUMBER,
- primaryKey: true,
- },
- source: {
- type: DataType.STRING,
- default: 'modelA',
- },
- },
- });
- S.defineModel({
- name: 'modelB',
- datasource: 'datasource',
- properties: {
- id: {
- type: DataType.NUMBER,
- primaryKey: true,
- },
- source: {
- type: DataType.STRING,
- default: 'modelB',
- },
- },
- relations: {
- parent: {
- type: RelationType.BELONGS_TO,
- model: 'modelA',
- },
- },
- });
- S.defineModel({
- name: 'modelC',
- datasource: 'datasource',
- properties: {
- id: {
- type: DataType.NUMBER,
- primaryKey: true,
- },
- source: {
- type: DataType.STRING,
- default: 'modelC',
- },
- },
- relations: {
- parent: {
- type: RelationType.BELONGS_TO,
- polymorphic: true,
- },
- },
- });
- const aRep = S.getRepository('modelA');
- const bRep = S.getRepository('modelB');
- const cRep = S.getRepository('modelC');
- const a = await aRep.create({});
- const b = await bRep.create({parentId: a.id});
- const c = await cRep.create({parentId: b.id, parentType: 'modelB'});
- expect(a).to.be.eql({
- id: a.id,
- source: 'modelA',
- });
- expect(b).to.be.eql({
- id: b.id,
- source: 'modelB',
- parentId: a.id,
- });
- expect(c).to.be.eql({
- id: c.id,
- source: 'modelC',
- parentId: b.id,
- parentType: 'modelB',
- });
- const R = S.get(BelongsToResolver);
- await R.includePolymorphicTo(
- [c],
- 'modelC',
- 'parent',
- undefined,
- undefined,
- {include: 'parent'},
- );
- expect(c).to.be.eql({
- id: c.id,
- source: 'modelC',
- parentId: b.id,
- parentType: 'modelB',
- parent: {
- id: b.id,
- source: 'modelB',
- parentId: a.id,
- parent: {
- id: a.id,
- source: 'modelA',
- },
- },
- });
- });
- });
- });
|