Skip to content

Commit

Permalink
test(repository): verify relation type in resolve{Relation}Metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
nabdelgadir committed Nov 6, 2019
1 parent d065e7d commit d814165
Show file tree
Hide file tree
Showing 3 changed files with 226 additions and 140 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// 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 {
BelongsToDefinition,
Entity,
ModelDefinition,
RelationType,
} from '../../..';
import {resolveBelongsToMetadata} from '../../../relations/belongs-to/belongs-to.helpers';

describe('resolveBelongsToMetadata', () => {
it('throws if the wrong metadata type is used', async () => {
expect(() => {
resolveBelongsToMetadata(Category.definition.relations[
'category'
] as BelongsToDefinition);
}).to.throw(
/Invalid hasOne definition for Category#category: relation type must be BelongsTo/,
);
});

/****** HELPERS *******/
class Category extends Entity {}

Category.definition = new ModelDefinition('Category')
.addProperty('id', {type: 'number', id: true, required: true})
// need <unknown> to avoid Type 'RelationType.hasOne' is not comparable
// to type 'RelationType.belongsTo'
.addRelation(<BelongsToDefinition>(<unknown>{
name: 'category',
type: RelationType.hasOne,
targetsMany: false,
source: Category,
keyFrom: 'id',
target: () => Category,
keyTo: 'categoryId',
}));
});
Original file line number Diff line number Diff line change
Expand Up @@ -12,92 +12,102 @@ import {
} from '../../..';
import {resolveHasManyMetadata} from '../../../relations/has-many/has-many.helpers';

describe('keyTo and keyFrom with resolveHasManyMetadata', () => {
it('resolves metadata using keyTo and keyFrom', () => {
const meta = resolveHasManyMetadata(Category.definition.relations[
'products'
] as HasManyDefinition);
describe('resolveHasOneMetadata', () => {
it('throws if the wrong metadata type is used', async () => {
expect(() => {
resolveHasManyMetadata(Category.definition.relations[
'category'
] as HasManyDefinition);
}).to.throw(
/Invalid hasOne definition for Category#category: relation type must be HasMany/,
);
});
describe('keyTo and keyFrom with resolveHasManyMetadata', () => {
it('resolves metadata using keyTo and keyFrom', () => {
const meta = resolveHasManyMetadata(Category.definition.relations[
'products'
] as HasManyDefinition);

expect(meta).to.eql({
name: 'products',
type: 'hasMany',
targetsMany: true,
source: Category,
keyFrom: 'id',
target: () => Product,
keyTo: 'categoryId',
expect(meta).to.eql({
name: 'products',
type: 'hasMany',
targetsMany: true,
source: Category,
keyFrom: 'id',
target: () => Product,
keyTo: 'categoryId',
});
});
});

it('infers keyFrom if it is not provided', () => {
const meta = resolveHasManyMetadata(Category.definition.relations[
'items'
] as HasManyDefinition);
it('infers keyFrom if it is not provided', () => {
const meta = resolveHasManyMetadata(Category.definition.relations[
'items'
] as HasManyDefinition);

expect(meta).to.eql({
name: 'items',
type: 'hasMany',
targetsMany: true,
source: Category,
keyFrom: 'id',
target: () => Item,
keyTo: 'categoryId',
expect(meta).to.eql({
name: 'items',
type: 'hasMany',
targetsMany: true,
source: Category,
keyFrom: 'id',
target: () => Item,
keyTo: 'categoryId',
});
});
});

it('infers keyTo if it is not provided', () => {
const meta = resolveHasManyMetadata(Category.definition.relations[
'things'
] as HasManyDefinition);
it('infers keyTo if it is not provided', () => {
const meta = resolveHasManyMetadata(Category.definition.relations[
'things'
] as HasManyDefinition);

expect(meta).to.eql({
name: 'things',
type: 'hasMany',
targetsMany: true,
source: Category,
keyFrom: 'id',
target: () => Thing,
keyTo: 'categoryId',
expect(meta).to.eql({
name: 'things',
type: 'hasMany',
targetsMany: true,
source: Category,
keyFrom: 'id',
target: () => Thing,
keyTo: 'categoryId',
});
});
});

it('throws if keyFrom, keyTo, and default foreign key name are not provided', async () => {
let error;
it('throws if keyFrom, keyTo, and default foreign key name are not provided', async () => {
let error;

try {
resolveHasManyMetadata(Category.definition.relations[
'categories'
] as HasManyDefinition);
} catch (err) {
error = err;
}
try {
resolveHasManyMetadata(Category.definition.relations[
'categories'
] as HasManyDefinition);
} catch (err) {
error = err;
}

expect(error.message).to.eql(
'Invalid hasMany definition for Category#categories: target model ' +
'Category is missing definition of foreign key categoryId',
);
expect(error.message).to.eql(
'Invalid hasMany definition for Category#categories: target model ' +
'Category is missing definition of foreign key categoryId',
);

expect(error.code).to.eql('INVALID_RELATION_DEFINITION');
});
expect(error.code).to.eql('INVALID_RELATION_DEFINITION');
});

it('resolves metadata if keyTo and keyFrom are not provided, but default foreign key is', async () => {
Category.definition.addProperty('categoryId', {type: 'number'});
it('resolves metadata if keyTo and keyFrom are not provided, but default foreign key is', async () => {
Category.definition.addProperty('categoryId', {type: 'number'});

const meta = resolveHasManyMetadata(Category.definition.relations[
'categories'
] as HasManyDefinition);
const meta = resolveHasManyMetadata(Category.definition.relations[
'categories'
] as HasManyDefinition);

expect(meta).to.eql({
name: 'categories',
type: 'hasMany',
targetsMany: true,
source: Category,
keyFrom: 'id',
target: () => Category,
keyTo: 'categoryId',
expect(meta).to.eql({
name: 'categories',
type: 'hasMany',
targetsMany: true,
source: Category,
keyFrom: 'id',
target: () => Category,
keyTo: 'categoryId',
});
});
});

/****** HELPERS *******/

class Category extends Entity {}
Expand Down Expand Up @@ -147,7 +157,17 @@ describe('keyTo and keyFrom with resolveHasManyMetadata', () => {

target: () => Category,
// no keyTo
});
})
// need <unknown> to avoid Type 'RelationType.hasOne' is not comparable
// to type 'RelationType.hasMany'
.addRelation(<HasManyDefinition>(<unknown>{
name: 'category',
type: RelationType.hasOne,
targetsMany: true,
source: Category,
// no keyFrom
target: () => Category,
}));

class Product extends Entity {}

Expand Down
Loading

0 comments on commit d814165

Please sign in to comment.