apostrophe
Version:
The Apostrophe Content Management System.
228 lines (198 loc) • 5.94 kB
JavaScript
const t = require('../test-lib/test.js');
const assert = require('assert');
describe('Query Builders', function() {
this.timeout(t.timeout);
let apos;
after(function() {
return t.destroy(apos);
});
before(async function () {
apos = await t.create({
root: module,
modules: {
young: {
options: {
alias: 'young'
},
extend: '@apostrophecms/piece-type',
fields: {
add: {
age: {
label: 'Age',
type: 'integer',
required: true
}
}
},
queries(self, query) {
return {
builders: {
age: {
launder(str) {
return [ 'children', 'adult' ].includes(str) ? str : null;
},
finalize() {
const age = query.get('age');
if ([ 'children', 'adults' ].includes(age)) {
const ageCriteria = age === 'children' ? { $lte: 18 } : { $gt: 18 };
query.and({ age: ageCriteria });
}
}
}
},
methods: {
async sortByAge() {
await query.finalize();
const pipeline = [
{ $match: query.get('criteria') },
{ $sort: { age: 1 } }
];
const results = await self.apos.doc.db.aggregate(pipeline).toArray();
return results;
}
}
};
}
},
person: {
extend: 'young',
options: {
alias: 'person'
},
extendQueries(self, query) {
return {
builders: {
age: {
def: 'adult',
launder(_super, val) {
const laundered = _super();
if (laundered !== null) {
return laundered;
}
return val === 'senior' ? val : null;
},
async finalize(_super) {
await _super();
const age = query.get('age');
if (age === 'seniors') {
query.and({ age: { $gt: 60 } });
}
}
}
},
methods: {
async sortByAge(_super) {
assert(typeof _super === 'function');
await query.finalize();
const pipeline = [
{ $match: query.get('criteria') },
{ $sort: { age: -1 } }
];
const results = await self.apos.doc.db.aggregate(pipeline).toArray();
return results;
}
}
};
}
}
}
});
});
it('should insert person pieces and verify age query builder is working', async function() {
const req = apos.task.getReq();
const persons = getPersons(apos.young);
const { insertedCount } = await apos.doc.db.insertMany(persons);
assert(insertedCount === 6);
const children = await apos.young.find(req).age('children').toArray();
const adults = await apos.young.find(req).age('adults').toArray();
assert(children.length === 2);
children.forEach((child) => {
assert(child.age <= 18);
});
assert(adults.length === 4);
adults.forEach((adult) => {
assert(adult.age > 18);
});
});
it('should insert seniors and verify the query builders have been properly extended', async function() {
const req = apos.task.getReq();
const persons = getPersons(apos.person, true);
const { insertedCount } = await apos.doc.db.insertMany(persons);
assert(insertedCount === 8);
const children = await apos.person.find(req).age('children').toArray();
const adults = await apos.person.find(req).age('adults').toArray();
const seniors = await apos.person.find(req).age('seniors').toArray();
assert(children.length === 2);
children.forEach((child) => {
assert(child.age <= 18);
});
assert(adults.length === 6);
adults.forEach((adult) => {
assert(adult.age > 18);
});
assert(seniors.length === 2);
seniors.forEach((senior) => {
assert(senior.age > 60);
});
});
it('should verify that query methods work and can be extende', async function() {
const req = apos.task.getReq();
const youngSorted = await apos.young.find(req).age('adults').sortByAge();
assert(youngSorted[0].age === 25);
assert(youngSorted[1].age === 32);
assert(youngSorted[2].age === 50);
assert(youngSorted[3].age === 58);
const personsSorted = await apos.person.find(req).age('adults').sortByAge();
assert(personsSorted[0].age === 80);
assert(personsSorted[1].age === 72);
assert(personsSorted[2].age === 58);
assert(personsSorted[3].age === 50);
assert(personsSorted[4].age === 32);
});
});
function getPersons(instance, withSeniors = false) {
const moduleName = instance.__meta.name;
return [
{
title: 'Jean',
age: 32
},
{
title: 'Julie',
age: 25
},
{
title: 'Victor',
age: 14
},
{
title: 'Marc',
age: 58
},
{
title: 'Hector',
age: 7
},
{
title: 'Marie',
age: 50
},
...withSeniors
? [
{
title: 'Jules',
age: 72
},
{
title: 'Renée',
age: 80
}
]
: []
].map((p, i) => ({
_id: `${moduleName}${i}`,
...instance.newInstance(),
slug: `${moduleName}-${p.title.toLowerCase()}`,
...p
}));
}