Skip to content

Commit

Permalink
test(repository): add tests for hasManyThrough helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
Agnes Lin committed May 7, 2020
1 parent 806cdf0 commit f0a435c
Showing 1 changed file with 189 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
// Copyright IBM Corp. 2019. All Rights Reserved.
// Node module: @loopback/repository
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT

import {expect} from '@loopback/testlab';
import {
Entity,
HasManyDefinition,
ModelDefinition,
RelationType,
} from '../../../..';
import {resolveHasManyThroughMetadata} from '../../../../relations/has-many/has-many-through.helper';

describe.only('resolveHasManyThroughMetadata', () => {
it('throws if the wrong metadata type is used', async () => {
const metadata: unknown = {
name: 'category',
type: RelationType.hasOne,
targetsMany: false,
source: Category,
target: () => Category,
};

expect(() => {
resolveHasManyThroughMetadata(metadata as HasManyDefinition);
}).to.throw(
/Invalid hasOne definition for Category#category: relation type must be HasMany/,
);
});

it('throws if the through is not resolvable', async () => {
const metadata: unknown = {
name: 'category',
type: RelationType.hasMany,
targetsMany: true,
source: Category,
through: {model: 'random'},
target: () => Category,
};

expect(() => {
resolveHasManyThroughMetadata(metadata as HasManyDefinition);
}).to.throw(
/Invalid hasMany definition for Category#category: through.model must be a type resolver/,
);
});

describe('resolves through.keyTo/keyFrom', () => {
it('resolves metadata with complete hasManyThrough definition', () => {
const metadata = {
name: 'products',
type: RelationType.hasMany,
targetsMany: true,
source: Category,
keyFrom: 'id',
target: () => Product,
keyTo: 'categoryId',

through: {
model: () => CategoryProductLink,
keyFrom: 'categoryId',
keyTo: 'productId',
},
};
const meta = resolveHasManyThroughMetadata(metadata as HasManyDefinition);

expect(meta).to.eql(resolvedMetadata);
});

it('infers through.keyFrom if it is not provided', () => {
const metadata = {
name: 'products',
type: RelationType.hasMany,
targetsMany: true,
source: Category,
keyFrom: 'id',
target: () => Product,
keyTo: 'categoryId',

through: {
model: () => CategoryProductLink,
// no through.keyFrom
keyTo: 'productId',
},
};
const meta = resolveHasManyThroughMetadata(metadata as HasManyDefinition);

expect(meta).to.eql(resolvedMetadata);
});

it('infers through.keyTo if it is not provided', () => {
const metadata = {
name: 'products',
type: RelationType.hasMany,
targetsMany: true,
source: Category,
keyFrom: 'id',
target: () => Product,
keyTo: 'categoryId',

through: {
model: () => CategoryProductLink,
keyFrom: 'categoryId',
// no through.keyTo
},
};

const meta = resolveHasManyThroughMetadata(metadata as HasManyDefinition);

expect(meta).to.eql(resolvedMetadata);
});

it('throws if through.keyFrom, through.keyTo, and default foreign key name are not provided in through', async () => {
const metadata = {
name: 'categories',
type: RelationType.hasMany,
targetsMany: true,
source: Category,
keyFrom: 'id',
target: () => Product,
keyTo: 'categoryId',

through: {
model: () => InvalidThrough,
keyTo: 'productId',
},
};

expect(() => {
resolveHasManyThroughMetadata(metadata as HasManyDefinition);
}).to.throw(
/Invalid hasMany definition for Category#categories: through model InvalidThrough is missing definition of source foreign key/,
);
});
});
/****** HELPERS *******/

class Category extends Entity {}
Category.definition = new ModelDefinition('Category').addProperty('id', {
type: 'number',
id: true,
required: true,
});

class Product extends Entity {}
Product.definition = new ModelDefinition('Product')
.addProperty('id', {
type: 'number',
id: true,
required: true,
})
.addProperty('categoryId', {type: 'number'});

class CategoryProductLink extends Entity {}
CategoryProductLink.definition = new ModelDefinition('CategoryProductLink')
.addProperty('id', {
type: 'number',
id: true,
required: true,
})
.addProperty('categoryId', {type: 'number'})
.addProperty('productId', {type: 'number'});

const resolvedMetadata = {
name: 'products',
type: 'hasMany',
targetsMany: true,
source: Category,
keyFrom: 'id',
target: () => Product,
keyTo: 'categoryId',
through: {
model: () => CategoryProductLink,
keyFrom: 'categoryId',
keyTo: 'productId',
},
};

class InvalidThrough extends Entity {}
InvalidThrough.definition = new ModelDefinition('InvalidThrough')
.addProperty('id', {
type: 'number',
id: true,
required: true,
})
// lack through.keyFrom
.addProperty('productId', {type: 'number'});
});

0 comments on commit f0a435c

Please sign in to comment.