From c8f2d4507a5d9f6470c1fb7478a1d9f3a7bbcbb8 Mon Sep 17 00:00:00 2001 From: Nora Date: Wed, 14 Aug 2019 11:04:59 -0400 Subject: [PATCH] chore: remove tests from repository package --- .../belongs-to.relation.acceptance.ts | 95 ------ ...has-many-without-di.relation.acceptance.ts | 169 ----------- .../has-many.relation.acceptance.ts | 252 ---------------- .../acceptance/has-one.relation.acceptance.ts | 261 ---------------- .../acceptance/repository.acceptance.ts | 122 -------- .../fixtures/models/address.model.ts | 37 --- .../fixtures/models/customer.model.ts | 43 --- .../src/__tests__/fixtures/models/index.ts | 10 - .../__tests__/fixtures/models/order.model.ts | 42 --- .../fixtures/models/product.model.ts | 32 -- .../fixtures/models/shipment.model.ts | 32 -- .../repositories/address.repository.ts | 37 --- .../repositories/customer.repository.ts | 66 ---- .../__tests__/fixtures/repositories/index.ts | 10 - .../fixtures/repositories/order.repository.ts | 47 --- .../repositories/product.repository.ts | 18 -- .../repositories/shipment.repository.ts | 37 --- .../relation.factory.integration.ts | 285 ------------------ 18 files changed, 1595 deletions(-) delete mode 100644 packages/repository/src/__tests__/acceptance/belongs-to.relation.acceptance.ts delete mode 100644 packages/repository/src/__tests__/acceptance/has-many-without-di.relation.acceptance.ts delete mode 100644 packages/repository/src/__tests__/acceptance/has-many.relation.acceptance.ts delete mode 100644 packages/repository/src/__tests__/acceptance/has-one.relation.acceptance.ts delete mode 100644 packages/repository/src/__tests__/acceptance/repository.acceptance.ts delete mode 100644 packages/repository/src/__tests__/fixtures/models/address.model.ts delete mode 100644 packages/repository/src/__tests__/fixtures/models/customer.model.ts delete mode 100644 packages/repository/src/__tests__/fixtures/models/index.ts delete mode 100644 packages/repository/src/__tests__/fixtures/models/order.model.ts delete mode 100644 packages/repository/src/__tests__/fixtures/models/product.model.ts delete mode 100644 packages/repository/src/__tests__/fixtures/models/shipment.model.ts delete mode 100644 packages/repository/src/__tests__/fixtures/repositories/address.repository.ts delete mode 100644 packages/repository/src/__tests__/fixtures/repositories/customer.repository.ts delete mode 100644 packages/repository/src/__tests__/fixtures/repositories/index.ts delete mode 100644 packages/repository/src/__tests__/fixtures/repositories/order.repository.ts delete mode 100644 packages/repository/src/__tests__/fixtures/repositories/product.repository.ts delete mode 100644 packages/repository/src/__tests__/fixtures/repositories/shipment.repository.ts delete mode 100644 packages/repository/src/__tests__/integration/repositories/relation.factory.integration.ts diff --git a/packages/repository/src/__tests__/acceptance/belongs-to.relation.acceptance.ts b/packages/repository/src/__tests__/acceptance/belongs-to.relation.acceptance.ts deleted file mode 100644 index 4142e36e0f9f..000000000000 --- a/packages/repository/src/__tests__/acceptance/belongs-to.relation.acceptance.ts +++ /dev/null @@ -1,95 +0,0 @@ -// 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 {Application} from '@loopback/core'; -import {expect} from '@loopback/testlab'; -import { - ApplicationWithRepositories, - juggler, - repository, - RepositoryMixin, -} from '../..'; -import { - CustomerRepository, - OrderRepository, - ShipmentRepository, -} from '../fixtures/repositories'; - -describe('BelongsTo relation', () => { - // Given a Customer and Order models - see definitions at the bottom - - let app: ApplicationWithRepositories; - let controller: OrderController; - let customerRepo: CustomerRepository; - let orderRepo: OrderRepository; - let shipmentRepo: ShipmentRepository; - - before(givenApplicationWithMemoryDB); - before(givenBoundCrudRepositories); - before(givenOrderController); - - beforeEach(async () => { - await orderRepo.deleteAll(); - }); - - it('can find customer of order', async () => { - const customer = await customerRepo.create({name: 'Order McForder'}); - const order = await orderRepo.create({ - customerId: customer.id, - description: 'Order from Order McForder, the hoarder of Mordor', - }); - const result = await controller.findOwnerOfOrder(order.id); - expect(result).to.deepEqual(customer); - }); - - it('can find shipment of order with a custom foreign key name', async () => { - const shipment = await shipmentRepo.create({ - name: 'Tuesday morning shipment', - }); - const order = await orderRepo.create({ - // eslint-disable-next-line @typescript-eslint/camelcase - shipment_id: shipment.id, - description: 'Order that is shipped Tuesday morning', - }); - const result = await controller.findOrderShipment(order.id); - expect(result).to.deepEqual(shipment); - }); - - //--- HELPERS ---// - - class OrderController { - constructor( - @repository(OrderRepository) protected orderRepository: OrderRepository, - ) {} - - async findOwnerOfOrder(orderId: string) { - return this.orderRepository.customer(orderId); - } - - async findOrderShipment(orderId: string) { - return this.orderRepository.shipment(orderId); - } - } - - function givenApplicationWithMemoryDB() { - class TestApp extends RepositoryMixin(Application) {} - app = new TestApp(); - app.dataSource(new juggler.DataSource({name: 'db', connector: 'memory'})); - } - - async function givenBoundCrudRepositories() { - app.repository(CustomerRepository); - app.repository(OrderRepository); - app.repository(ShipmentRepository); - customerRepo = await app.getRepository(CustomerRepository); - orderRepo = await app.getRepository(OrderRepository); - shipmentRepo = await app.getRepository(ShipmentRepository); - } - - async function givenOrderController() { - app.controller(OrderController); - controller = await app.get('controllers.OrderController'); - } -}); diff --git a/packages/repository/src/__tests__/acceptance/has-many-without-di.relation.acceptance.ts b/packages/repository/src/__tests__/acceptance/has-many-without-di.relation.acceptance.ts deleted file mode 100644 index 60a50e01ea7d..000000000000 --- a/packages/repository/src/__tests__/acceptance/has-many-without-di.relation.acceptance.ts +++ /dev/null @@ -1,169 +0,0 @@ -// 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 { - DefaultCrudRepository, - Entity, - EntityCrudRepository, - Getter, - hasMany, - HasManyRepositoryFactory, - juggler, - model, - property, -} from '../..'; - -describe('HasMany relation', () => { - // Given a Customer and Order models - see definitions at the bottom - - let existingCustomerId: number; - let ds: juggler.DataSource; - let customerRepo: CustomerRepository; - let orderRepo: OrderRepository; - - before(givenDataSource); - before(givenOrderRepository); - before(givenCustomerRepository); - beforeEach(async () => { - await orderRepo.deleteAll(); - existingCustomerId = (await givenPersistedCustomerInstance()).id; - }); - - it('can create an instance of the related model', async () => { - async function createCustomerOrders( - customerId: number, - orderData: Partial, - ): Promise { - return customerRepo.orders(customerId).create(orderData); - } - const order = await createCustomerOrders(existingCustomerId, { - description: 'order 1', - }); - expect(order.toObject()).to.containDeep({ - customerId: existingCustomerId, - description: 'order 1', - }); - - const persisted = await orderRepo.findById(order.id); - expect(persisted.toObject()).to.deepEqual(order.toObject()); - }); - - it('can find instances of the related model', async () => { - async function createCustomerOrders( - customerId: number, - orderData: Partial, - ): Promise { - return customerRepo.orders(customerId).create(orderData); - } - async function findCustomerOrders(customerId: number) { - return customerRepo.orders(customerId).find(); - } - - const order = await createCustomerOrders(existingCustomerId, { - description: 'order 1', - }); - const notMyOrder = await createCustomerOrders(existingCustomerId + 1, { - description: 'order 2', - }); - const orders = await findCustomerOrders(existingCustomerId); - - expect(orders).to.containEql(order); - expect(orders).to.not.containEql(notMyOrder); - - const persisted = await orderRepo.find({ - where: {customerId: existingCustomerId}, - }); - expect(persisted).to.deepEqual(orders); - }); - - //--- HELPERS ---// - - @model() - class Order extends Entity { - @property({ - type: 'number', - id: true, - }) - id: number; - - @property({ - type: 'string', - required: true, - }) - description: string; - - @property({ - type: 'number', - required: true, - }) - customerId: number; - } - - @model() - class Customer extends Entity { - @property({ - type: 'number', - id: true, - }) - id: number; - - @property({ - type: 'string', - }) - name: string; - - @hasMany(() => Order) - orders: Order[]; - } - - class OrderRepository extends DefaultCrudRepository< - Order, - typeof Order.prototype.id - > { - constructor(db: juggler.DataSource) { - super(Order, db); - } - } - - class CustomerRepository extends DefaultCrudRepository< - Customer, - typeof Customer.prototype.id - > { - public readonly orders: HasManyRepositoryFactory< - Order, - typeof Customer.prototype.id - >; - - constructor( - protected db: juggler.DataSource, - orderRepositoryGetter: Getter< - EntityCrudRepository - >, - ) { - super(Customer, db); - this.orders = this._createHasManyRepositoryFactoryFor( - 'orders', - orderRepositoryGetter, - ); - } - } - - function givenDataSource() { - ds = new juggler.DataSource({connector: 'memory'}); - } - - function givenOrderRepository() { - orderRepo = new OrderRepository(ds); - } - - function givenCustomerRepository() { - customerRepo = new CustomerRepository(ds, Getter.fromValue(orderRepo)); - } - - async function givenPersistedCustomerInstance() { - return customerRepo.create({name: 'a customer'}); - } -}); diff --git a/packages/repository/src/__tests__/acceptance/has-many.relation.acceptance.ts b/packages/repository/src/__tests__/acceptance/has-many.relation.acceptance.ts deleted file mode 100644 index 8337baa60c8a..000000000000 --- a/packages/repository/src/__tests__/acceptance/has-many.relation.acceptance.ts +++ /dev/null @@ -1,252 +0,0 @@ -// 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 {Application} from '@loopback/core'; -import {expect} from '@loopback/testlab'; -import * as _ from 'lodash'; -import { - ApplicationWithRepositories, - juggler, - repository, - RepositoryMixin, -} from '../..'; -import {Customer, Order} from '../fixtures/models'; -import {CustomerRepository, OrderRepository} from '../fixtures/repositories'; - -describe('HasMany relation', () => { - // Given a Customer and Order models - see definitions at the bottom - - let app: ApplicationWithRepositories; - let controller: CustomerController; - let customerRepo: CustomerRepository; - let orderRepo: OrderRepository; - let existingCustomerId: number; - - before(givenApplicationWithMemoryDB); - before(givenBoundCrudRepositoriesForCustomerAndOrder); - before(givenCustomerController); - - beforeEach(async () => { - await orderRepo.deleteAll(); - }); - - beforeEach(async () => { - existingCustomerId = (await givenPersistedCustomerInstance()).id; - }); - - it('can create an instance of the related model', async () => { - const order = await controller.createCustomerOrders(existingCustomerId, { - description: 'order 1', - }); - expect(order.toObject()).to.containDeep({ - customerId: existingCustomerId, - description: 'order 1', - }); - - const persisted = await orderRepo.findById(order.id); - expect(persisted.toObject()).to.deepEqual(order.toObject()); - }); - - it('can find instances of the related model', async () => { - const order = await controller.createCustomerOrders(existingCustomerId, { - description: 'order 1', - }); - const notMyOrder = await controller.createCustomerOrders( - existingCustomerId + 1, - { - description: 'order 2', - }, - ); - const foundOrders = await controller.findCustomerOrders(existingCustomerId); - expect(foundOrders).to.containEql(order); - expect(foundOrders).to.not.containEql(notMyOrder); - - const persisted = await orderRepo.find({ - where: {customerId: existingCustomerId}, - }); - expect(persisted).to.deepEqual(foundOrders); - }); - - it('can patch many instances', async () => { - await controller.createCustomerOrders(existingCustomerId, { - description: 'order 1', - isShipped: false, - }); - await controller.createCustomerOrders(existingCustomerId, { - description: 'order 2', - isShipped: false, - }); - const patchObject = {isShipped: true}; - const arePatched = await controller.patchCustomerOrders( - existingCustomerId, - patchObject, - ); - expect(arePatched.count).to.equal(2); - const patchedData = _.map( - await controller.findCustomerOrders(existingCustomerId), - d => _.pick(d, ['customerId', 'description', 'isShipped']), - ); - expect(patchedData).to.eql([ - { - customerId: existingCustomerId, - description: 'order 1', - isShipped: true, - }, - { - customerId: existingCustomerId, - description: 'order 2', - isShipped: true, - }, - ]); - }); - - it('throws error when query tries to change the foreignKey', async () => { - await expect( - controller.patchCustomerOrders(existingCustomerId, { - customerId: existingCustomerId + 1, - }), - ).to.be.rejectedWith(/Property "customerId" cannot be changed!/); - }); - - it('can delete many instances', async () => { - await controller.createCustomerOrders(existingCustomerId, { - description: 'order 1', - }); - await controller.createCustomerOrders(existingCustomerId, { - description: 'order 2', - }); - const deletedOrders = await controller.deleteCustomerOrders( - existingCustomerId, - ); - expect(deletedOrders.count).to.equal(2); - const relatedOrders = await controller.findCustomerOrders( - existingCustomerId, - ); - expect(relatedOrders).to.be.empty(); - }); - - it("does not delete instances that don't belong to the constrained instance", async () => { - const newOrder = { - customerId: existingCustomerId + 1, - description: 'another order', - }; - await orderRepo.create(newOrder); - await controller.deleteCustomerOrders(existingCustomerId); - const orders = await orderRepo.find(); - expect(orders).to.have.length(1); - expect(_.pick(orders[0], ['customerId', 'description'])).to.eql(newOrder); - }); - - it('does not create an array of the related model', async () => { - await expect( - customerRepo.create({ - name: 'a customer', - orders: [ - { - description: 'order 1', - }, - ], - }), - ).to.be.rejectedWith(/`orders` is not defined/); - }); - - context('when targeting the source model', () => { - it('gets the parent entity through the child entity', async () => { - const parent = await customerRepo.create({name: 'parent customer'}); - const child = await customerRepo.create({ - name: 'child customer', - parentId: parent.id, - }); - - const childsParent = await controller.getParentCustomer(child.id); - - expect(_.pick(childsParent, ['id', 'name'])).to.eql( - _.pick(parent, ['id', 'name']), - ); - }); - - it('creates a child entity through the parent entity', async () => { - const parent = await customerRepo.create({ - name: 'parent customer', - }); - const child = await controller.createCustomerChildren(parent.id, { - name: 'child customer', - }); - expect(child.parentId).to.equal(parent.id); - - const children = await controller.findCustomerChildren(parent.id); - expect(children).to.containEql(child); - }); - }); - - // This should be enforced by the database to avoid race conditions - it.skip('reject create request when the customer does not exist'); - - class CustomerController { - constructor( - @repository(CustomerRepository) - protected customerRepository: CustomerRepository, - ) {} - - async createCustomerOrders( - customerId: number, - orderData: Partial, - ): Promise { - return this.customerRepository.orders(customerId).create(orderData); - } - - async findCustomerOrders(customerId: number) { - return this.customerRepository.orders(customerId).find(); - } - - async patchCustomerOrders(customerId: number, order: Partial) { - return this.customerRepository.orders(customerId).patch(order); - } - - async deleteCustomerOrders(customerId: number) { - return this.customerRepository.orders(customerId).delete(); - } - - async getParentCustomer(customerId: number) { - return this.customerRepository.parent(customerId); - } - - async createCustomerChildren( - customerId: number, - customerData: Partial, - ) { - return this.customerRepository.customers(customerId).create(customerData); - } - - async findCustomerChildren(customerId: number) { - return this.customerRepository.customers(customerId).find(); - } - } - - function givenApplicationWithMemoryDB() { - class TestApp extends RepositoryMixin(Application) {} - - app = new TestApp(); - app.dataSource(new juggler.DataSource({name: 'db', connector: 'memory'})); - } - - async function givenBoundCrudRepositoriesForCustomerAndOrder() { - app.repository(CustomerRepository); - app.repository(OrderRepository); - customerRepo = await app.getRepository(CustomerRepository); - orderRepo = await app.getRepository(OrderRepository); - } - - async function givenCustomerController() { - app.controller(CustomerController); - controller = await app.get( - 'controllers.CustomerController', - ); - } - - async function givenPersistedCustomerInstance() { - return customerRepo.create({name: 'a customer'}); - } -}); diff --git a/packages/repository/src/__tests__/acceptance/has-one.relation.acceptance.ts b/packages/repository/src/__tests__/acceptance/has-one.relation.acceptance.ts deleted file mode 100644 index 3c50eebd3325..000000000000 --- a/packages/repository/src/__tests__/acceptance/has-one.relation.acceptance.ts +++ /dev/null @@ -1,261 +0,0 @@ -// 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 {Application} from '@loopback/core'; -import {expect, toJSON} from '@loopback/testlab'; -import { - ApplicationWithRepositories, - EntityNotFoundError, - Filter, - juggler, - repository, - RepositoryMixin, -} from '../..'; -import {Address} from '../fixtures/models'; -import {AddressRepository, CustomerRepository} from '../fixtures/repositories'; - -describe('hasOne relation', () => { - // Given a Customer and Address models - see definitions at the bottom - - let app: ApplicationWithRepositories; - let controller: CustomerController; - let customerRepo: CustomerRepository; - let addressRepo: AddressRepository; - let existingCustomerId: number; - - before(givenApplicationWithMemoryDB); - before(givenBoundCrudRepositoriesForCustomerAndAddress); - before(givenCustomerController); - - beforeEach(async () => { - await addressRepo.deleteAll(); - existingCustomerId = (await givenPersistedCustomerInstance()).id; - }); - - it('can create an instance of the related model', async () => { - const address = await controller.createCustomerAddress(existingCustomerId, { - street: '123 test avenue', - }); - expect(address.toObject()).to.containDeep({ - customerId: existingCustomerId, - street: '123 test avenue', - }); - - const persisted = await addressRepo.findById(address.zipcode); - expect(persisted.toObject()).to.deepEqual(address.toObject()); - }); - - // We do not enforce referential integrity at the moment. It is up to - // our users to set up unique constraint(s) between related models at the - // database level - it.skip('refuses to create related model instance twice', async () => { - const address = await controller.createCustomerAddress(existingCustomerId, { - street: '123 test avenue', - }); - await expect( - controller.createCustomerAddress(existingCustomerId, { - street: '456 test street', - }), - ).to.be.rejectedWith(/Duplicate entry for Address.customerId/); - expect(address.toObject()).to.containDeep({ - customerId: existingCustomerId, - street: '123 test avenue', - }); - - const persisted = await addressRepo.findById(address.zipcode); - expect(persisted.toObject()).to.deepEqual(address.toObject()); - }); - - it('can find instance of the related model', async () => { - const address = await controller.createCustomerAddress(existingCustomerId, { - street: '123 test avenue', - }); - const foundAddress = await controller.findCustomerAddress( - existingCustomerId, - ); - expect(foundAddress).to.containEql(address); - expect(toJSON(foundAddress)).to.deepEqual(toJSON(address)); - - const persisted = await addressRepo.find({ - where: {customerId: existingCustomerId}, - }); - expect(persisted[0]).to.deepEqual(foundAddress); - }); - - // FIXME(b-admike): make sure the test fails with compiler error - it.skip('ignores where filter to find related model instance', async () => { - const foundAddress = await controller.findCustomerAddressWithFilter( - existingCustomerId, - // the compiler should complain that the where field is - // not accepted in the filter object for the get() method - // if the following line is uncommented - { - where: {street: '456 test road'}, - }, - ); - - const persisted = await addressRepo.find({ - where: {customerId: existingCustomerId}, - }); - // TODO: make sure this test fails when where condition is supplied - // compiler should have errored out (?) - expect(persisted[0]).to.deepEqual(foundAddress); - }); - - it('reports EntityNotFound error when related model is deleted', async () => { - const address = await controller.createCustomerAddress(existingCustomerId, { - street: '123 test avenue', - }); - await addressRepo.deleteById(address.zipcode); - - await expect( - controller.findCustomerAddress(existingCustomerId), - ).to.be.rejectedWith(EntityNotFoundError); - }); - - it('can PATCH hasOne instances', async () => { - const address = await controller.createCustomerAddress(existingCustomerId, { - street: '1 Amedee Bonnet', - zipcode: '69740', - city: 'Genas', - province: 'Rhone', - }); - - const patchObject = {city: 'Lyon-Genas'}; - const arePatched = await controller.patchCustomerAddress( - existingCustomerId, - patchObject, - ); - - expect(arePatched).to.deepEqual({count: 1}); - const patchedData = await addressRepo.findById(address.zipcode); - expect(toJSON(patchedData)).to.deepEqual({ - customerId: existingCustomerId, - street: '1 Amedee Bonnet', - zipcode: '69740', - city: 'Lyon-Genas', - province: 'Rhone', - }); - }); - - it('patches the related instance only', async () => { - const bob = await customerRepo.create({name: 'Bob'}); - await customerRepo.address(bob.id).create({city: 'Paris'}); - - const alice = await customerRepo.create({name: 'Alice'}); - await customerRepo.address(alice.id).create({city: 'London'}); - - const result = await controller.patchCustomerAddress(alice.id, { - city: 'New York', - }); - - expect(result).to.deepEqual({count: 1}); - - const found = await customerRepo.address(bob.id).get(); - expect(toJSON(found)).to.containDeep({city: 'Paris'}); - }); - - it('throws an error when PATCH tries to change the foreignKey', async () => { - await expect( - controller.patchCustomerAddress(existingCustomerId, { - customerId: existingCustomerId + 1, - }), - ).to.be.rejectedWith(/Property "customerId" cannot be changed!/); - }); - - it('can DELETE hasOne relation instances', async () => { - await controller.createCustomerAddress(existingCustomerId, { - street: '1 Amedee Bonnet', - zipcode: '69740', - city: 'Genas', - province: 'Rhone', - }); - - const areDeleted = await controller.deleteCustomerAddress( - existingCustomerId, - ); - expect(areDeleted).to.deepEqual({count: 1}); - - await expect( - controller.findCustomerAddress(existingCustomerId), - ).to.be.rejectedWith(EntityNotFoundError); - }); - - it('deletes the related model instance only', async () => { - const bob = await customerRepo.create({name: 'Bob'}); - await customerRepo.address(bob.id).create({city: 'Paris'}); - - const alice = await customerRepo.create({name: 'Alice'}); - await customerRepo.address(alice.id).create({city: 'London'}); - - const result = await controller.deleteCustomerAddress(alice.id); - - expect(result).to.deepEqual({count: 1}); - - const found = await addressRepo.find(); - expect(found).to.have.length(1); - }); - - /*---------------- HELPERS -----------------*/ - - class CustomerController { - constructor( - @repository(CustomerRepository) - protected customerRepository: CustomerRepository, - ) {} - - async createCustomerAddress( - customerId: number, - addressData: Partial
, - ): Promise
{ - return this.customerRepository.address(customerId).create(addressData); - } - - async findCustomerAddress(customerId: number) { - return this.customerRepository.address(customerId).get(); - } - - async findCustomerAddressWithFilter( - customerId: number, - filter: Filter
, - ) { - return this.customerRepository.address(customerId).get(filter); - } - async patchCustomerAddress( - customerId: number, - addressData: Partial
, - ) { - return this.customerRepository.address(customerId).patch(addressData); - } - - async deleteCustomerAddress(customerId: number) { - return this.customerRepository.address(customerId).delete(); - } - } - - function givenApplicationWithMemoryDB() { - class TestApp extends RepositoryMixin(Application) {} - app = new TestApp(); - app.dataSource(new juggler.DataSource({name: 'db', connector: 'memory'})); - } - - async function givenBoundCrudRepositoriesForCustomerAndAddress() { - app.repository(CustomerRepository); - app.repository(AddressRepository); - customerRepo = await app.getRepository(CustomerRepository); - addressRepo = await app.getRepository(AddressRepository); - } - - async function givenCustomerController() { - app.controller(CustomerController); - controller = await app.get( - 'controllers.CustomerController', - ); - } - - async function givenPersistedCustomerInstance() { - return customerRepo.create({name: 'a customer'}); - } -}); diff --git a/packages/repository/src/__tests__/acceptance/repository.acceptance.ts b/packages/repository/src/__tests__/acceptance/repository.acceptance.ts deleted file mode 100644 index b6d68dc7f816..000000000000 --- a/packages/repository/src/__tests__/acceptance/repository.acceptance.ts +++ /dev/null @@ -1,122 +0,0 @@ -// 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 {DataSource} from 'loopback-datasource-juggler'; -import {AnyObject, DefaultCrudRepository, Entity, model, property} from '../..'; -import {Product} from '../fixtures/models/product.model'; -import {ProductRepository} from '../fixtures/repositories/product.repository'; - -// This test shows the recommended way how to use @loopback/repository -// together with existing connectors when building LoopBack applications -describe('Repository in Thinking in LoopBack', () => { - let repo: ProductRepository; - beforeEach(givenProductRepository); - - it('counts models in empty database', async () => { - expect(await repo.count()).to.deepEqual({count: 0}); - }); - - it('creates a new model', async () => { - const p: Product = await repo.create({name: 'Ink Pen', slug: 'pen'}); - expect(p).instanceof(Product); - expect.exists(p.id); - }); - - it('can save a model', async () => { - const p = await repo.create({slug: 'pencil'}); - - p.name = 'Red Pencil'; - await repo.save(p); - - await repo.findById(p.id); - expect(p).to.have.properties({ - slug: 'pencil', - name: 'Red Pencil', - }); - }); - - it('rejects extra model properties (defaults to strict mode)', async () => { - await expect( - repo.create({name: 'custom', extra: 'additional-data'} as AnyObject), - ).to.be.rejectedWith(/extra.*not defined/); - }); - - it('allows models to allow additional properties', async () => { - // TODO(bajtos) Add syntactic sugar to allow the following usage: - // @model({strict: false}) - @model({settings: {strict: false}}) - class Flexible extends Entity { - @property({id: true}) - id: number; - } - - const flexibleRepo = new DefaultCrudRepository< - Flexible, - typeof Flexible.prototype.id - >(Flexible, new DataSource({connector: 'memory'})); - - const created = await flexibleRepo.create({ - extra: 'additional data', - } as AnyObject); - const stored = await flexibleRepo.findById(created.id); - expect(stored).to.containDeep({extra: 'additional data'}); - }); - - it('allows models to allow nested model properties', async () => { - @model() - class Role extends Entity { - @property() - name: string; - } - - @model() - class Address extends Entity { - @property() - street: string; - } - - @model() - class User extends Entity { - @property({ - type: 'number', - id: true, - }) - id: number; - - @property({type: 'string'}) - name: string; - - @property.array(Role) - roles: Role[]; - - @property() - address: Address; - } - - const userRepo = new DefaultCrudRepository( - User, - new DataSource({connector: 'memory'}), - ); - - const user = { - id: 1, - name: 'foo', - roles: [{name: 'admin'}, {name: 'user'}], - address: {street: 'backstreet'}, - }; - const created = await userRepo.create(user); - - const stored = await userRepo.findById(created.id); - expect(stored).to.containDeep(user); - }); - - function givenProductRepository() { - const db = new DataSource({ - connector: 'memory', - }); - repo = new ProductRepository(db); - } -}); diff --git a/packages/repository/src/__tests__/fixtures/models/address.model.ts b/packages/repository/src/__tests__/fixtures/models/address.model.ts deleted file mode 100644 index c886c6d76214..000000000000 --- a/packages/repository/src/__tests__/fixtures/models/address.model.ts +++ /dev/null @@ -1,37 +0,0 @@ -// 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 {belongsTo, Entity, model, property} from '../../..'; -import {Customer, CustomerWithRelations} from './customer.model'; - -@model() -export class Address extends Entity { - @property({ - type: 'string', - }) - street: string; - @property({ - type: 'string', - id: true, - }) - zipcode: string; - @property({ - type: 'string', - }) - city: string; - @property({ - type: 'string', - }) - province: string; - - @belongsTo(() => Customer) - customerId: number; -} - -export interface AddressRelations { - customer?: CustomerWithRelations; -} - -export type AddressWithRelations = Address & AddressRelations; diff --git a/packages/repository/src/__tests__/fixtures/models/customer.model.ts b/packages/repository/src/__tests__/fixtures/models/customer.model.ts deleted file mode 100644 index fd18dc9e82dd..000000000000 --- a/packages/repository/src/__tests__/fixtures/models/customer.model.ts +++ /dev/null @@ -1,43 +0,0 @@ -// 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 {belongsTo, Entity, hasMany, hasOne, model, property} from '../../..'; -import {Address, AddressWithRelations} from './address.model'; -import {Order, OrderWithRelations} from './order.model'; - -@model() -export class Customer extends Entity { - @property({ - type: 'number', - id: true, - }) - id: number; - - @property({ - type: 'string', - }) - name: string; - - @hasMany(() => Order) - orders: Order[]; - - @hasOne(() => Address) - address: Address; - - @hasMany(() => Customer, {keyTo: 'parentId'}) - customers?: Customer[]; - - @belongsTo(() => Customer) - parentId?: number; -} - -export interface CustomerRelations { - address?: AddressWithRelations; - orders?: OrderWithRelations[]; - customers?: CustomerWithRelations[]; - parentCustomer?: CustomerWithRelations; -} - -export type CustomerWithRelations = Customer & CustomerRelations; diff --git a/packages/repository/src/__tests__/fixtures/models/index.ts b/packages/repository/src/__tests__/fixtures/models/index.ts deleted file mode 100644 index 9c1ee60840f0..000000000000 --- a/packages/repository/src/__tests__/fixtures/models/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -// 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 - -export * from './address.model'; -export * from './customer.model'; -export * from './order.model'; -export * from './product.model'; -export * from './shipment.model'; diff --git a/packages/repository/src/__tests__/fixtures/models/order.model.ts b/packages/repository/src/__tests__/fixtures/models/order.model.ts deleted file mode 100644 index f4256925d89a..000000000000 --- a/packages/repository/src/__tests__/fixtures/models/order.model.ts +++ /dev/null @@ -1,42 +0,0 @@ -// 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 {belongsTo, Entity, model, property} from '../../..'; -import {Customer, CustomerWithRelations} from './customer.model'; -import {Shipment, ShipmentWithRelations} from './shipment.model'; - -@model() -export class Order extends Entity { - @property({ - type: 'string', - id: true, - }) - id: string; - - @property({ - type: 'string', - required: true, - }) - description: string; - - @property({ - type: 'boolean', - required: false, - }) - isShipped: boolean; - - @belongsTo(() => Customer) - customerId: number; - - @belongsTo(() => Shipment, {name: 'shipment'}) - shipment_id: number; -} - -export interface OrderRelations { - customer?: CustomerWithRelations; - shipment?: ShipmentWithRelations; -} - -export type OrderWithRelations = Order & OrderRelations; diff --git a/packages/repository/src/__tests__/fixtures/models/product.model.ts b/packages/repository/src/__tests__/fixtures/models/product.model.ts deleted file mode 100644 index 7612e577e8e1..000000000000 --- a/packages/repository/src/__tests__/fixtures/models/product.model.ts +++ /dev/null @@ -1,32 +0,0 @@ -// 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 {Entity, model, property} from '../../..'; - -@model() -export class Product extends Entity { - @property({ - type: 'number', - id: true, - description: 'The unique identifier for a product', - }) - id: number; - - @property({type: 'string'}) - name: string; - - @property({type: 'string'}) - slug: string; - - constructor(data?: Partial) { - super(data); - } -} - -export interface ProductRelations { - // describe navigational properties here -} - -export type ProductWithRelations = Product & ProductRelations; diff --git a/packages/repository/src/__tests__/fixtures/models/shipment.model.ts b/packages/repository/src/__tests__/fixtures/models/shipment.model.ts deleted file mode 100644 index cf9787af8448..000000000000 --- a/packages/repository/src/__tests__/fixtures/models/shipment.model.ts +++ /dev/null @@ -1,32 +0,0 @@ -// 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 {Entity, hasMany, model, property} from '../../..'; -import {Order, OrderWithRelations} from './order.model'; - -@model() -export class Shipment extends Entity { - @property({ - type: 'number', - id: true, - }) - id: number; - - @property({type: 'string'}) - name: string; - - @hasMany(() => Order, {keyTo: 'shipment_id'}) - shipmentOrders: Order[]; - - constructor(data?: Partial) { - super(data); - } -} - -export interface ShipmentRelations { - orders?: OrderWithRelations[]; -} - -export type ShipmentWithRelations = Shipment & ShipmentRelations; diff --git a/packages/repository/src/__tests__/fixtures/repositories/address.repository.ts b/packages/repository/src/__tests__/fixtures/repositories/address.repository.ts deleted file mode 100644 index 3be973cef13c..000000000000 --- a/packages/repository/src/__tests__/fixtures/repositories/address.repository.ts +++ /dev/null @@ -1,37 +0,0 @@ -// 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 {Getter, inject} from '@loopback/context'; -import { - BelongsToAccessor, - DefaultCrudRepository, - juggler, - repository, -} from '../../..'; -import {Address, AddressRelations, Customer} from '../models'; -import {CustomerRepository} from '../repositories'; - -export class AddressRepository extends DefaultCrudRepository< - Address, - typeof Address.prototype.zipcode, - AddressRelations -> { - public readonly customer: BelongsToAccessor< - Customer, - typeof Address.prototype.zipcode - >; - - constructor( - @inject('datasources.db') protected db: juggler.DataSource, - @repository.getter('CustomerRepository') - customerRepositoryGetter: Getter, - ) { - super(Address, db); - this.customer = this._createBelongsToAccessorFor( - 'customer', - customerRepositoryGetter, - ); - } -} diff --git a/packages/repository/src/__tests__/fixtures/repositories/customer.repository.ts b/packages/repository/src/__tests__/fixtures/repositories/customer.repository.ts deleted file mode 100644 index 9a2dcb302c98..000000000000 --- a/packages/repository/src/__tests__/fixtures/repositories/customer.repository.ts +++ /dev/null @@ -1,66 +0,0 @@ -// 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 {Getter, inject} from '@loopback/context'; -import { - BelongsToAccessor, - DefaultCrudRepository, - HasManyRepositoryFactory, - juggler, - repository, -} from '../../..'; -import {HasOneRepositoryFactory} from '../../../'; -import {Address, Customer, CustomerRelations, Order} from '../models'; -import {AddressRepository} from './address.repository'; -import {OrderRepository} from './order.repository'; - -export class CustomerRepository extends DefaultCrudRepository< - Customer, - typeof Customer.prototype.id, - CustomerRelations -> { - public readonly orders: HasManyRepositoryFactory< - Order, - typeof Customer.prototype.id - >; - public readonly address: HasOneRepositoryFactory< - Address, - typeof Customer.prototype.id - >; - public readonly customers: HasManyRepositoryFactory< - Customer, - typeof Customer.prototype.id - >; - public readonly parent: BelongsToAccessor< - Customer, - typeof Customer.prototype.id - >; - - constructor( - @inject('datasources.db') protected db: juggler.DataSource, - @repository.getter('OrderRepository') - orderRepositoryGetter: Getter, - @repository.getter('AddressRepository') - addressRepositoryGetter: Getter, - ) { - super(Customer, db); - this.orders = this.createHasManyRepositoryFactoryFor( - 'orders', - orderRepositoryGetter, - ); - this.address = this.createHasOneRepositoryFactoryFor( - 'address', - addressRepositoryGetter, - ); - this.customers = this.createHasManyRepositoryFactoryFor( - 'customers', - Getter.fromValue(this), - ); - this.parent = this.createBelongsToAccessorFor( - 'parent', - Getter.fromValue(this), - ); - } -} diff --git a/packages/repository/src/__tests__/fixtures/repositories/index.ts b/packages/repository/src/__tests__/fixtures/repositories/index.ts deleted file mode 100644 index 30f070573c57..000000000000 --- a/packages/repository/src/__tests__/fixtures/repositories/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -// 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 - -export * from './address.repository'; -export * from './customer.repository'; -export * from './order.repository'; -export * from './product.repository'; -export * from './shipment.repository'; diff --git a/packages/repository/src/__tests__/fixtures/repositories/order.repository.ts b/packages/repository/src/__tests__/fixtures/repositories/order.repository.ts deleted file mode 100644 index bd7bf0a7b32f..000000000000 --- a/packages/repository/src/__tests__/fixtures/repositories/order.repository.ts +++ /dev/null @@ -1,47 +0,0 @@ -// 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 {Getter, inject} from '@loopback/context'; -import { - BelongsToAccessor, - DefaultCrudRepository, - juggler, - repository, -} from '../../..'; -import {Customer, Order, OrderRelations, Shipment} from '../models'; -import {CustomerRepository, ShipmentRepository} from '../repositories'; - -export class OrderRepository extends DefaultCrudRepository< - Order, - typeof Order.prototype.id, - OrderRelations -> { - public readonly customer: BelongsToAccessor< - Customer, - typeof Order.prototype.id - >; - public readonly shipment: BelongsToAccessor< - Shipment, - typeof Order.prototype.id - >; - - constructor( - @inject('datasources.db') protected db: juggler.DataSource, - @repository.getter('CustomerRepository') - customerRepositoryGetter: Getter, - @repository.getter('ShipmentRepository') - shipmentRepositoryGetter: Getter, - ) { - super(Order, db); - this.customer = this.createBelongsToAccessorFor( - 'customer', - customerRepositoryGetter, - ); - this.shipment = this.createBelongsToAccessorFor( - 'shipment', - shipmentRepositoryGetter, - ); - } -} diff --git a/packages/repository/src/__tests__/fixtures/repositories/product.repository.ts b/packages/repository/src/__tests__/fixtures/repositories/product.repository.ts deleted file mode 100644 index 2ab4b0408e7d..000000000000 --- a/packages/repository/src/__tests__/fixtures/repositories/product.repository.ts +++ /dev/null @@ -1,18 +0,0 @@ -// 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 {DefaultCrudRepository, juggler} from '../../..'; -import {Product, ProductRelations} from '../models/product.model'; -export {Product}; - -export class ProductRepository extends DefaultCrudRepository< - Product, - typeof Product.prototype.id, - ProductRelations -> { - constructor(dataSource: juggler.DataSource) { - super(Product, dataSource); - } -} diff --git a/packages/repository/src/__tests__/fixtures/repositories/shipment.repository.ts b/packages/repository/src/__tests__/fixtures/repositories/shipment.repository.ts deleted file mode 100644 index 9b7aea3b768a..000000000000 --- a/packages/repository/src/__tests__/fixtures/repositories/shipment.repository.ts +++ /dev/null @@ -1,37 +0,0 @@ -// 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 {Getter, inject} from '@loopback/context'; -import {OrderRepository} from '.'; -import { - DefaultCrudRepository, - HasManyRepositoryFactory, - juggler, - repository, -} from '../../..'; -import {Order, Shipment, ShipmentRelations} from '../models'; - -export class ShipmentRepository extends DefaultCrudRepository< - Shipment, - typeof Shipment.prototype.id, - ShipmentRelations -> { - public readonly orders: HasManyRepositoryFactory< - Order, - typeof Shipment.prototype.id - >; - - constructor( - @inject('datasources.db') protected db: juggler.DataSource, - @repository.getter('OrderRepository') - orderRepositoryGetter: Getter, - ) { - super(Shipment, db); - this.orders = this.createHasManyRepositoryFactoryFor( - 'shipmentOrders', - orderRepositoryGetter, - ); - } -} diff --git a/packages/repository/src/__tests__/integration/repositories/relation.factory.integration.ts b/packages/repository/src/__tests__/integration/repositories/relation.factory.integration.ts deleted file mode 100644 index e347ae765f08..000000000000 --- a/packages/repository/src/__tests__/integration/repositories/relation.factory.integration.ts +++ /dev/null @@ -1,285 +0,0 @@ -// 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 { - BelongsToAccessor, - BelongsToDefinition, - createBelongsToAccessor, - createHasManyRepositoryFactory, - DefaultCrudRepository, - Entity, - EntityCrudRepository, - EntityNotFoundError, - Getter, - HasManyDefinition, - HasManyRepository, - HasManyRepositoryFactory, - juggler, - ModelDefinition, - RelationType, -} from '../../..'; - -// Given a Customer and Order models - see definitions at the bottom -let db: juggler.DataSource; -let customerRepo: EntityCrudRepository; -let orderRepo: EntityCrudRepository; -let reviewRepo: EntityCrudRepository; - -describe('HasMany relation', () => { - let existingCustomerId: number; - - let customerOrderRepo: HasManyRepository; - let customerAuthoredReviewFactoryFn: HasManyRepositoryFactory< - Review, - typeof Customer.prototype.id - >; - let customerApprovedReviewFactoryFn: HasManyRepositoryFactory< - Review, - typeof Customer.prototype.id - >; - - before(givenCrudRepositories); - before(givenPersistedCustomerInstance); - before(givenConstrainedRepositories); - before(givenRepositoryFactoryFunctions); - - beforeEach(async function resetDatabase() { - await orderRepo.deleteAll(); - await reviewRepo.deleteAll(); - }); - - it('can create an instance of the related model', async () => { - const order = await customerOrderRepo.create({ - description: 'an order desc', - }); - const persisted = await orderRepo.findById(order.id); - - expect(order).to.deepEqual(persisted); - }); - - it('can find an instance of the related model', async () => { - const order = await customerOrderRepo.create({ - description: 'an order desc', - }); - const notMyOrder = await orderRepo.create({ - description: "someone else's order desc", - customerId: existingCustomerId + 1, // a different customerId, - }); - const persistedOrders = await orderRepo.find({ - where: { - customerId: existingCustomerId, - }, - }); - - const orders = await customerOrderRepo.find(); - - expect(orders).to.containEql(order); - expect(orders).to.not.containEql(notMyOrder); - expect(orders).to.deepEqual(persistedOrders); - }); - - it('finds appropriate related model instances for multiple relations', async () => { - // note(shimks): roundabout way of creating reviews with 'approves' - // ideally, the review repository should have a approve function - // which should 'approve' a review - // On another note, this test should be separated for 'create' and 'find' - await customerAuthoredReviewFactoryFn(existingCustomerId).create({ - description: 'my wonderful review', - approvedId: existingCustomerId + 1, - }); - await customerAuthoredReviewFactoryFn(existingCustomerId + 1).create({ - description: 'smash that progenitor loving approve button', - approvedId: existingCustomerId, - }); - - const reviewsApprovedByCustomerOne = await customerApprovedReviewFactoryFn( - existingCustomerId, - ).find(); - const reviewsApprovedByCustomerTwo = await customerApprovedReviewFactoryFn( - existingCustomerId + 1, - ).find(); - - const persistedReviewsApprovedByCustomerOne = await reviewRepo.find({ - where: { - approvedId: existingCustomerId, - }, - }); - const persistedReviewsApprovedByCustomerTwo = await reviewRepo.find({ - where: { - approvedId: existingCustomerId + 1, - }, - }); - - expect(reviewsApprovedByCustomerOne).to.eql( - persistedReviewsApprovedByCustomerOne, - ); - expect(reviewsApprovedByCustomerTwo).to.eql( - persistedReviewsApprovedByCustomerTwo, - ); - }); - - //--- HELPERS ---// - - async function givenPersistedCustomerInstance() { - const customer = await customerRepo.create({name: 'a customer'}); - existingCustomerId = customer.id; - } - - function givenConstrainedRepositories() { - const orderFactoryFn = createHasManyRepositoryFactory< - Order, - typeof Order.prototype.id, - typeof Customer.prototype.id - >( - Customer.definition.relations.orders as HasManyDefinition, - Getter.fromValue(orderRepo), - ); - - customerOrderRepo = orderFactoryFn(existingCustomerId); - } - - function givenRepositoryFactoryFunctions() { - customerAuthoredReviewFactoryFn = createHasManyRepositoryFactory( - Customer.definition.relations.reviewsAuthored as HasManyDefinition, - Getter.fromValue(reviewRepo), - ); - customerApprovedReviewFactoryFn = createHasManyRepositoryFactory( - Customer.definition.relations.reviewsApproved as HasManyDefinition, - Getter.fromValue(reviewRepo), - ); - } -}); - -describe('BelongsTo relation', () => { - let findCustomerOfOrder: BelongsToAccessor< - Customer, - typeof Order.prototype.id - >; - - before(givenCrudRepositories); - before(givenAccessor); - beforeEach(async function resetDatabase() { - await Promise.all([ - customerRepo.deleteAll(), - orderRepo.deleteAll(), - reviewRepo.deleteAll(), - ]); - }); - - it('finds an instance of the related model', async () => { - const customer = await customerRepo.create({name: 'Order McForder'}); - const order = await orderRepo.create({ - customerId: customer.id, - description: 'Order from Order McForder, the hoarder of Mordor', - }); - - const result = await findCustomerOfOrder(order.id); - - expect(result).to.deepEqual(customer); - }); - - it('throws EntityNotFound error when the related model does not exist', async () => { - const order = await orderRepo.create({ - customerId: 999, // does not exist - description: 'Order of a fictional customer', - }); - - await expect(findCustomerOfOrder(order.id)).to.be.rejectedWith( - EntityNotFoundError, - ); - }); - - //--- HELPERS ---// - - function givenAccessor() { - findCustomerOfOrder = createBelongsToAccessor( - Order.definition.relations.customer as BelongsToDefinition, - Getter.fromValue(customerRepo), - orderRepo, - ); - } -}); - -//--- HELPERS ---// - -class Order extends Entity { - id: number; - description: string; - customerId: number; - - static definition = new ModelDefinition('Order') - .addProperty('id', {type: 'number', id: true}) - .addProperty('description', {type: 'string', required: true}) - .addProperty('customerId', {type: 'number', required: true}) - .addRelation({ - name: 'customer', - type: RelationType.belongsTo, - source: Order, - target: () => Customer, - keyFrom: 'customerId', - keyTo: 'id', - }); -} - -class Review extends Entity { - id: number; - description: string; - authorId: number; - approvedId: number; - - static definition = new ModelDefinition('Review') - .addProperty('id', {type: 'number', id: true}) - .addProperty('description', {type: 'string', required: true}) - .addProperty('authorId', {type: 'number', required: false}) - .addProperty('approvedId', {type: 'number', required: false}); -} - -class Customer extends Entity { - id: number; - name: string; - orders: Order[]; - reviewsAuthored: Review[]; - reviewsApproved: Review[]; - - static definition: ModelDefinition = new ModelDefinition('Customer') - .addProperty('id', {type: 'number', id: true}) - .addProperty('name', {type: 'string', required: true}) - .addProperty('orders', {type: Order, array: true}) - .addProperty('reviewsAuthored', {type: Review, array: true}) - .addProperty('reviewsApproved', {type: Review, array: true}) - .addRelation({ - name: 'orders', - type: RelationType.hasMany, - targetsMany: true, - source: Customer, - target: () => Order, - keyTo: 'customerId', - }) - .addRelation({ - name: 'reviewsAuthored', - type: RelationType.hasMany, - targetsMany: true, - source: Customer, - target: () => Review, - keyTo: 'authorId', - }) - .addRelation({ - name: 'reviewsApproved', - type: RelationType.hasMany, - targetsMany: true, - source: Customer, - target: () => Review, - keyTo: 'approvedId', - }); -} - -function givenCrudRepositories() { - db = new juggler.DataSource({connector: 'memory'}); - - customerRepo = new DefaultCrudRepository(Customer, db); - orderRepo = new DefaultCrudRepository(Order, db); - reviewRepo = new DefaultCrudRepository(Review, db); -}