Skip to content

Commit

Permalink
Merge aca6cda into bc5dc91
Browse files Browse the repository at this point in the history
  • Loading branch information
achrinza committed Dec 26, 2020
2 parents bc5dc91 + aca6cda commit 897a7cc
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 40 deletions.
Expand Up @@ -4,6 +4,7 @@
// License text available at https://opensource.org/licenses/MIT

import {expect, toJSON} from '@loopback/testlab';
import {cloneDeep} from 'lodash';
import {
bindModel,
DefaultCrudRepository,
Expand Down Expand Up @@ -263,41 +264,73 @@ describe('DefaultCrudRepository', () => {
expect(notes.length).to.eql(2);
});

it('implements Repository.find()', async () => {
const repo = new DefaultCrudRepository(Note, ds);
await repo.createAll([
{title: 't1', content: 'c1'},
{title: 't2', content: 'c2'},
]);
const notes = await repo.find({where: {title: 't1'}});
expect(notes.length).to.eql(1);
});
describe('find', () => {
it('is implemented', async () => {
const repo = new DefaultCrudRepository(Note, ds);
await repo.createAll([
{title: 't1', content: 'c1'},
{title: 't2', content: 'c2'},
]);
const notes = await repo.find({where: {title: 't1'}});
expect(notes.length).to.eql(1);
});

it('implements Repository.findOne()', async () => {
const repo = new DefaultCrudRepository(Note, ds);
await repo.createAll([
{title: 't1', content: 'c1'},
{title: 't1', content: 'c2'},
]);
const note = await repo.findOne({
where: {title: 't1'},
order: ['content DESC'],
it('does not manipulate the original filter', async () => {
const repo = new DefaultCrudRepository(Note, ds);
const filter = {where: {title: 't1'}};
const originalFilter = cloneDeep(filter);
await repo.createAll([
{title: 't1', content: 'c1'},
{title: 't2', content: 'c2'},
]);
await repo.find(filter);
expect(filter).to.deepEqual(originalFilter);
});
expect(note).to.not.be.null();
expect(note?.title).to.eql('t1');
expect(note?.content).to.eql('c2');
});
it('returns null if Repository.findOne() does not return a value', async () => {
const repo = new DefaultCrudRepository(Note, ds);
await repo.createAll([
{title: 't1', content: 'c1'},
{title: 't1', content: 'c2'},
]);
const note = await repo.findOne({
where: {title: 't5'},
order: ['content DESC'],

describe('findOne', () => {
it('is implemented', async () => {
const repo = new DefaultCrudRepository(Note, ds);
await repo.createAll([
{title: 't1', content: 'c1'},
{title: 't1', content: 'c2'},
]);
const note = await repo.findOne({
where: {title: 't1'},
order: ['content DESC'],
});
expect(note).to.not.be.null();
expect(note?.title).to.eql('t1');
expect(note?.content).to.eql('c2');
});

it('returns null if instances were found', async () => {
const repo = new DefaultCrudRepository(Note, ds);
await repo.createAll([
{title: 't1', content: 'c1'},
{title: 't1', content: 'c2'},
]);
const note = await repo.findOne({
where: {title: 't5'},
order: ['content DESC'],
});
expect(note).to.be.null();
});

it('does not manipulate the original filter', async () => {
const repo = new DefaultCrudRepository(Note, ds);
const filter = {
where: {title: 't5'},
order: ['content DESC'],
};
const originalFilter = cloneDeep(filter);
await repo.createAll([
{title: 't1', content: 'c1'},
{title: 't1', content: 'c2'},
]);
await repo.findOne(filter);
expect(filter).to.deepEqual(originalFilter);
});
expect(note).to.be.null();
});

describe('findById', () => {
Expand All @@ -315,6 +348,15 @@ describe('DefaultCrudRepository', () => {
expect(result?.toJSON()).to.eql({title: 'a-title'});
});

it('does not manipulate the original filter', async () => {
const repo = new DefaultCrudRepository(Note, ds);
const filter = {fields: {title: true, content: true}};
const originalFilter = cloneDeep(filter);
const note = await repo.create({title: 'a-title', content: 'a-content'});
await repo.findById(note.id, filter);
expect(filter).to.deepEqual(originalFilter);
});

it('throws when the instance does not exist', async () => {
const repo = new DefaultCrudRepository(Note, ds);
await expect(repo.findById(999999)).to.be.rejectedWith({
Expand Down
Expand Up @@ -9,6 +9,7 @@ import {
sinon,
StubbedInstanceWithSinonAccessor,
} from '@loopback/testlab';
import {cloneDeep} from 'lodash';
import {findByForeignKeys} from '../../../..';
import {
createProduct,
Expand Down Expand Up @@ -153,4 +154,21 @@ describe('findByForeignKeys', () => {
include: ['nested inclusion'],
});
});

it('does not manipulate non-primitive params', async () => {
const fkValues = [1];
const scope = {
where: {id: 2},
};
const fkValuesOriginal = cloneDeep(fkValues);
const scopeOriginal = cloneDeep(scope);

productRepo.stubs.find.resolves([]);
await productRepo.create({id: 1, name: 'product', categoryId: 1});
await productRepo.create({id: 2, name: 'product', categoryId: 1});
await findByForeignKeys(productRepo, 'categoryId', fkValues, scope);

expect(fkValues).to.deepEqual(fkValuesOriginal);
expect(scope).to.deepEqual(scopeOriginal);
});
});
Expand Up @@ -4,6 +4,7 @@
// License text available at https://opensource.org/licenses/MIT

import {expect, toJSON} from '@loopback/testlab';
import {cloneDeep} from 'lodash';
import {includeRelatedModels, InclusionResolver} from '../../../..';
import {
Category,
Expand Down Expand Up @@ -39,6 +40,19 @@ describe('includeRelatedModels', () => {
expect(result).to.eql([category]);
});

it('does not manipulate non-primitive params', async () => {
const category = await categoryRepo.create({name: 'category'});
const categoryOriginal = cloneDeep(category);
const filter = ['products'];
const filterOriginal = cloneDeep(filter);

categoryRepo.inclusionResolvers.set('products', hasManyResolver);
await includeRelatedModels(categoryRepo, [category], filter);

expect(category).to.deepEqual(categoryOriginal);
expect(filter).to.deepEqual(filterOriginal);
});

context(
'throws error if the target repository does not have registered resolvers',
() => {
Expand Down
14 changes: 5 additions & 9 deletions packages/repository/src/relations/relation.helpers.ts
Expand Up @@ -5,7 +5,7 @@

import assert from 'assert';
import debugFactory from 'debug';
import _ from 'lodash';
import _, {cloneDeep} from 'lodash';
import {
AnyObject,
Entity,
Expand Down Expand Up @@ -39,17 +39,11 @@ export async function findByForeignKeys<
options?: Options,
): Promise<(Target & TargetRelations)[]> {
let value;
scope = cloneDeep(scope);

if (Array.isArray(fkValues)) {
if (fkValues.length === 0) return [];
value =
fkValues.length === 1
? fkValues[0]
: {
// Create a copy to prevent query coercion algorithm
// inside connectors from modifying the original values
inq: [...fkValues],
};
value = fkValues.length === 1 ? fkValues[0] : {inq: fkValues};
} else {
value = fkValues;
}
Expand Down Expand Up @@ -87,6 +81,8 @@ export async function includeRelatedModels<
include?: InclusionFilter[],
options?: Options,
): Promise<(T & Relations)[]> {
entities = cloneDeep(entities);
include = cloneDeep(include);
const result = entities as (T & Relations)[];
if (!include) return result;

Expand Down

0 comments on commit 897a7cc

Please sign in to comment.