diff --git a/packages/repository-tests/src/relations/integration/has-many.factory.integration.ts b/packages/repository-tests/src/relations/integration/has-many.factory.integration.ts index 699c98f80855..9afe6bf51562 100644 --- a/packages/repository-tests/src/relations/integration/has-many.factory.integration.ts +++ b/packages/repository-tests/src/relations/integration/has-many.factory.integration.ts @@ -17,6 +17,13 @@ import { RelationType, } from '@loopback/repository'; import {expect} from '@loopback/testlab'; +import { + CrudFeatures, + CrudRepositoryCtor, + CrudTestContext, + DataSourceOptions, +} from '../..'; +import {withCrudCtx} from '../../helpers.repository-tests'; // Given a Customer and Order models - see definitions at the bottom let db: juggler.DataSource; @@ -24,130 +31,151 @@ 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(); - }); +export function hasManyFactorySuite( + dataSourceOptions: DataSourceOptions, + repositoryClass: CrudRepositoryCtor, + features: CrudFeatures, +) { + 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( + withCrudCtx(async function setupRepository(ctx: CrudTestContext) { + db = ctx.dataSource; + console.log(db.name); + givenCrudRepositories(db); + await givenPersistedCustomerInstance(); + givenConstrainedRepositories(); + givenRepositoryFactoryFunctions(); + await ctx.dataSource.automigrate(Customer.name); + await ctx.dataSource.automigrate(Order.name); + await ctx.dataSource.automigrate(Review.name); + }), + ); - it('can create an instance of the related model', async () => { - const order = await customerOrderRepo.create({ - description: 'an order desc', + beforeEach(async function resetDatabase() { + await orderRepo.deleteAll(); + await reviewRepo.deleteAll(); }); - const persisted = await orderRepo.findById(order.id); - expect(order).to.deepEqual(persisted); - }); + 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); - 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, - }, + expect(order).to.deepEqual(persisted); }); - 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, + 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); }); - 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: { + 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, + ); }); - 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), + ); + } }); - //--- 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 givenCrudRepositories(ds: juggler.DataSource) { + customerRepo = new DefaultCrudRepository(Customer, ds); + orderRepo = new DefaultCrudRepository(Order, ds); + reviewRepo = new DefaultCrudRepository(Review, ds); } - - function givenRepositoryFactoryFunctions() { - customerAuthoredReviewFactoryFn = createHasManyRepositoryFactory( - Customer.definition.relations.reviewsAuthored as HasManyDefinition, - Getter.fromValue(reviewRepo), - ); - customerApprovedReviewFactoryFn = createHasManyRepositoryFactory( - Customer.definition.relations.reviewsApproved as HasManyDefinition, - Getter.fromValue(reviewRepo), - ); - } -}); +} //--- HELPERS ---// @@ -221,11 +249,3 @@ class Customer extends Entity { 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); -}