diff --git a/packages/repository/src/__tests__/integration/repositories/resolve-belongs-to-metadata.integration.ts b/packages/repository/src/__tests__/integration/repositories/resolve-belongs-to-metadata.integration.ts new file mode 100644 index 000000000000..b6d9299561bb --- /dev/null +++ b/packages/repository/src/__tests__/integration/repositories/resolve-belongs-to-metadata.integration.ts @@ -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 to avoid Type 'RelationType.hasOne' is not comparable + // to type 'RelationType.belongsTo' + .addRelation(({ + name: 'category', + type: RelationType.hasOne, + targetsMany: false, + source: Category, + keyFrom: 'id', + target: () => Category, + keyTo: 'categoryId', + })); +}); diff --git a/packages/repository/src/__tests__/integration/repositories/resolve-has-many-metadata.integration.ts b/packages/repository/src/__tests__/integration/repositories/resolve-has-many-metadata.integration.ts index bcf494ca11ac..f086ecdcd6fe 100644 --- a/packages/repository/src/__tests__/integration/repositories/resolve-has-many-metadata.integration.ts +++ b/packages/repository/src/__tests__/integration/repositories/resolve-has-many-metadata.integration.ts @@ -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 {} @@ -147,7 +157,17 @@ describe('keyTo and keyFrom with resolveHasManyMetadata', () => { target: () => Category, // no keyTo - }); + }) + // need to avoid Type 'RelationType.hasOne' is not comparable + // to type 'RelationType.hasMany' + .addRelation(({ + name: 'category', + type: RelationType.hasOne, + targetsMany: true, + source: Category, + // no keyFrom + target: () => Category, + })); class Product extends Entity {} diff --git a/packages/repository/src/__tests__/integration/repositories/resolve-has-one-metadata.integration.ts b/packages/repository/src/__tests__/integration/repositories/resolve-has-one-metadata.integration.ts index 3db13b0d66b4..8d926a0ccb59 100644 --- a/packages/repository/src/__tests__/integration/repositories/resolve-has-one-metadata.integration.ts +++ b/packages/repository/src/__tests__/integration/repositories/resolve-has-one-metadata.integration.ts @@ -12,92 +12,103 @@ import { } from '../../..'; import {resolveHasOneMetadata} from '../../../relations/has-one/has-one.helpers'; -describe('keyTo and keyFrom with resolveHasOneMetadata', () => { - it('resolves metadata using keyTo and keyFrom', () => { - const meta = resolveHasOneMetadata(Category.definition.relations[ - 'product' - ] as HasOneDefinition); +describe('resolveHasOneMetadata', () => { + it('throws if the wrong metadata type is used', async () => { + expect(() => { + resolveHasOneMetadata(Category.definition.relations[ + 'products' + ] as HasOneDefinition); + }).to.throw( + /Invalid hasMany definition for Category#products: relation type must be HasOne/, + ); + }); - expect(meta).to.eql({ - name: 'product', - type: 'hasOne', - targetsMany: false, - source: Category, - keyFrom: 'id', - target: () => Product, - keyTo: 'categoryId', + describe('keyTo and keyFrom with resolveHasOneMetadata', () => { + it('resolves metadata using keyTo and keyFrom', () => { + const meta = resolveHasOneMetadata(Category.definition.relations[ + 'product' + ] as HasOneDefinition); + + expect(meta).to.eql({ + name: 'product', + type: 'hasOne', + targetsMany: false, + source: Category, + keyFrom: 'id', + target: () => Product, + keyTo: 'categoryId', + }); }); - }); - it('infers keyFrom if it is not provided', () => { - const meta = resolveHasOneMetadata(Category.definition.relations[ - 'item' - ] as HasOneDefinition); + it('infers keyFrom if it is not provided', () => { + const meta = resolveHasOneMetadata(Category.definition.relations[ + 'item' + ] as HasOneDefinition); - expect(meta).to.eql({ - name: 'item', - type: 'hasOne', - targetsMany: false, - source: Category, - keyFrom: 'id', - target: () => Item, - keyTo: 'categoryId', + expect(meta).to.eql({ + name: 'item', + type: 'hasOne', + targetsMany: false, + source: Category, + keyFrom: 'id', + target: () => Item, + keyTo: 'categoryId', + }); }); - }); - it('infers keyTo if it is not provided', () => { - const meta = resolveHasOneMetadata(Category.definition.relations[ - 'thing' - ] as HasOneDefinition); + it('infers keyTo if it is not provided', () => { + const meta = resolveHasOneMetadata(Category.definition.relations[ + 'thing' + ] as HasOneDefinition); - expect(meta).to.eql({ - name: 'thing', - type: 'hasOne', - targetsMany: false, - source: Category, - keyFrom: 'id', - target: () => Thing, - keyTo: 'categoryId', + expect(meta).to.eql({ + name: 'thing', + type: 'hasOne', + targetsMany: false, + 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 { - resolveHasOneMetadata(Category.definition.relations[ - 'category' - ] as HasOneDefinition); - } catch (err) { - error = err; - } + try { + resolveHasOneMetadata(Category.definition.relations[ + 'category' + ] as HasOneDefinition); + } catch (err) { + error = err; + } - expect(error.message).to.eql( - 'Invalid hasOne definition for Category#category: target model Category' + - ' is missing definition of foreign key categoryId', - ); + expect(error.message).to.eql( + 'Invalid hasOne definition for Category#category: 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 = resolveHasOneMetadata(Category.definition.relations[ - 'category' - ] as HasOneDefinition); + const meta = resolveHasOneMetadata(Category.definition.relations[ + 'category' + ] as HasOneDefinition); - expect(meta).to.eql({ - name: 'category', - type: 'hasOne', - targetsMany: false, - source: Category, - keyFrom: 'id', - target: () => Category, - keyTo: 'categoryId', + expect(meta).to.eql({ + name: 'category', + type: 'hasOne', + targetsMany: false, + source: Category, + keyFrom: 'id', + target: () => Category, + keyTo: 'categoryId', + }); }); }); - /****** HELPERS *******/ class Category extends Entity {} @@ -147,7 +158,20 @@ describe('keyTo and keyFrom with resolveHasOneMetadata', () => { target: () => Category, // no keyTo - }); + }) + // need to avoid Type 'RelationType.hasMany' is not comparable + // to type 'RelationType.hasOne' + .addRelation(({ + name: 'products', + type: RelationType.hasMany, + targetsMany: false, + source: Category, + keyFrom: 'id', + target: () => Products, + keyTo: 'categoryId', + })); + + class Products extends Entity {} class Product extends Entity {}