bifocal/node_modules/@tryghost/mongo-knex/test/integration/relations.test.js

1540 lines
51 KiB
JavaScript

const _ = require('lodash');
const utils = require('../utils');
const knex = utils.db.client;
const convertor = require('../../lib/convertor');
/* eslint-disable no-console*/
// @TODO: the config object is not designed yet.
const makeQuery = (mongoJSON) => {
const query = convertor(knex('posts'), mongoJSON, {
relations: {
tags: {
tableName: 'tags',
type: 'manyToMany',
joinTable: 'posts_tags',
joinFrom: 'post_id',
joinTo: 'tag_id'
},
authors: {
tableName: 'users',
tableNameAs: 'authors',
type: 'manyToMany',
joinTable: 'posts_authors',
joinFrom: 'post_id',
joinTo: 'author_id'
},
posts_meta: {
tableName: 'posts_meta',
type: 'oneToOne',
joinFrom: 'post_id'
},
comments: {
tableName: 'comments',
type: 'manyToMany',
joinTable: 'posts_comments',
joinFrom: 'post_id',
joinTo: 'comment_id',
joinToForeign: 'comment_provider_id'
}
}
});
query.orderBy('id', 'ASC');
return query;
};
// Integration tests build a test database and
// check that we get the exact data we expect from each query
describe('Relations', function () {
before(async function () {
await utils.db.teardown()();
await utils.db.setup()();
});
after(utils.db.teardown());
describe('Many-to-Many', function () {
before(utils.db.init('many-to-many'));
describe('joinToForeign', function () {
it('Allows you to join an a customer foreign key in the resulting row', function () {
const mongoJSON = {
'comments.content': 'Hello, world'
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(1);
result.should.matchIds([1]);
});
});
});
describe('EQUALS $eq', function () {
it('tags.slug equals "animal"', function () {
const mongoJSON = {
'tags.slug': 'animal'
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(3);
result.should.matchIds([2, 4, 6]);
});
});
it('tags.visibility equals "internal"', function () {
const mongoJSON = {
'tags.visibility': 'internal'
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(1);
result.should.matchIds([8]);
});
});
});
describe('NEGATION $ne', function () {
// should return posts without tags
// if a post has more than 1 tag, if one tag is animal, do not return
it('tags.slug is NOT "animal"', function () {
const mongoJSON = {
'tags.slug': {
$ne: 'animal'
}
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(5);
result.should.matchIds([1, 3, 5, 7, 8]);
});
});
it('tags.visibility is NOT "public"', function () {
const mongoJSON = {
'tags.visibility': {
$ne: 'public'
}
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(2);
result.should.matchIds([7, 8]);
});
});
});
describe('COMPARISONS $gt / $gte / $lt / $lte', function () {
it('tags.created_at is > 2015-06-21', function () {
const mongoJSON = {'tags.created_at': {
$gt: '2015-06-21'
}};
const query = makeQuery(mongoJSON);
return query
.then((result) => {
result.length.should.eql(1);
result.should.matchIds([8]);
});
});
it('tags.created_at is >= 2015-06-21', function () {
const mongoJSON = {'tags.created_at': {
$gte: '2015-06-21'
}};
const query = makeQuery(mongoJSON);
return query
.then((result) => {
result.length.should.eql(2);
result.should.matchIds([3, 8]);
});
});
it('tags.created_at is < 2015-01-02', function () {
const mongoJSON = {'tags.created_at': {
$lt: '2015-01-02'
}};
const query = makeQuery(mongoJSON);
return query
.then((result) => {
result.length.should.eql(4);
result.should.matchIds([1, 4, 5, 6]);
});
});
it('tags.created_at is <= 2015-01-02', function () {
const mongoJSON = {'tags.created_at': {
$lte: '2015-01-02'
}};
const query = makeQuery(mongoJSON);
return query
.then((result) => {
result.length.should.eql(5);
result.should.matchIds([1, 2, 4, 5, 6]);
});
});
});
describe('AND $and', function () {
it('tags.slug is animal and classic', function () {
const mongoJSON = {
$and: [
{
'tags.slug': 'animal'
},
{
'tags.slug': 'classic'
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(2);
result.should.matchIds([4, 6]);
});
});
it('tags.slug is hash-internal and tags.visibility is private', function () {
const mongoJSON = {
$and: [
{
'tags.slug': 'hash-internal'
},
{
'tags.visibility': 'internal'
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(1);
result.should.matchIds([8]);
});
});
it('tags.slug is animal and tags.slug NOT in [classic]', function () {
const mongoJSON = {
$and: [
{
'tags.slug': 'animal'
},
{
'tags.slug': {
$nin: ['classic']
}
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(1);
result.should.matchIds([2]);
});
});
it('tags.slug is animal and sort_order is 0', function () {
const mongoJSON = {
$and: [
{
'tags.slug': 'animal'
},
{
'posts_tags.sort_order': 0
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(1);
result.should.matchIds([2]);
});
});
it('(tags.slug is animal and sort_order is 0) and tags.visibility=public', function () {
const mongoJSON = {
$and: [
{
$and: [
{
'tags.slug': 'animal'
},
{
'posts_tags.sort_order': 0
}
]
},
{
'tags.visibility': 'public'
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(1);
result.should.matchIds([2]);
});
});
it('tags.slug is animal and sort_order is 0 and tags.visibility=public', function () {
const mongoJSON = {
$and: [
{
'tags.slug': 'animal'
},
{
'posts_tags.sort_order': 0
},
{
'tags.visibility': 'public'
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(1);
result.should.matchIds([2]);
});
});
it('tags.slug is NOT animal and tags.slug is NOT cgi', function () {
// equivalent to $nin: ['animal', 'cgi']
const mongoJSON = {
$and: [
{
'tags.slug': {
$ne: 'animal'
}
},
{
'tags.slug': {
$ne: 'cgi'
}
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(4);
result.should.matchIds([1, 5, 7, 8]);
});
});
it('tags.slug NOT equal "classic" and tags.visibility is equal "public"', function () {
const mongoJSON = {
'tags.visibility': 'public',
'tags.slug': {
$ne: 'classic'
}
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(2);
result.should.matchIds([2, 3]);
});
});
it('tags.slug NOT IN ["classic"] and tags.visibility is equal "public"', function () {
const mongoJSON = {
'tags.visibility': 'public',
'tags.slug': {
$nin: ['classic']
}
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(2);
result.should.matchIds([2, 3]);
});
});
it('(tags.slug NOT IN "classic" and tags.visibility is equal "public")', function () {
// this case can be generated with:
// 'tags.slug:-classic+tags.visibility:public'
const mongoJSON = {
$and: [
{
'tags.visibility': 'public'
},
{
'tags.slug': {
$nin: ['classic']
}
}
]
};
const query = makeQuery(mongoJSON);
// NOTE: this query is generating a group, this should be avoided
// as we can't group negated properties with other, unless those
// are going through connecting table
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(2);
result.should.matchIds([2, 3]);
});
});
it('any author is pat and any tag is classic (query on multiple relations)', function () {
const mongoJSON = {
$and: [
{
'authors.slug': 'pat'
},
{
'tags.slug': 'classic'
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(4);
result.should.matchIds([1, 4, 5, 6]);
});
});
it('first author is pat and first tag is classic (query on multiple relations)', function () {
const mongoJSON = {
$and: [
{
$and: [
{
'tags.slug': 'classic'
},
{
'posts_tags.sort_order': 0
}
]
},
{
$and: [
{
'authors.slug': 'pat'
},
{
'posts_authors.sort_order': 0
}
]
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(3);
result.should.matchIds([1, 5, 6]);
});
});
describe('Multiple conditions applied to the joining table and to the destination table', function () {
it('tags.slug equals "cgi" and posts_tags.sort_order is 0 and featured is true', function () {
// where primary tag is "cgi"
const mongoJSON = {
$and: [
{
$and: [
{
'tags.slug': 'cgi'
},
{
'posts_tags.sort_order': 0
}
]
},
{
featured: true
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(1);
result.should.matchIds([3]);
});
});
it('tags.slug equals "animal" and posts_tags.sort_order is 0 and featured is false', function () {
// where primary tag is "animal"
const mongoJSON = {
$and: [
{
$and: [
{
'tags.slug': 'animal'
},
{
'posts_tags.sort_order': 0
}
]
},
{
featured: false
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(1);
result.should.matchIds([2]);
});
});
it('tags.slug NOT equal "classic" and posts_tags.sort_order is 0 and featured is true', function () {
const mongoJSON = {
$and: [
{
$and: [
{
'tags.slug': {
$ne: 'classic'
}
},
{
'posts_tags.sort_order': 0
}
]
},
{
featured: true
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
// @NOTE: This should return posts without tags, because a post without tags is not tagged
// with the primary tag "classic".
result.should.be.an.Array().with.lengthOf(3);
result.should.matchIds([3, 7, 8]);
});
});
});
});
describe('OR $or', function () {
it('any author is pat or leslie', function () {
const mongoJSON = {
$or: [
{
'authors.slug': 'leslie'
},
{
'authors.slug': 'pat'
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(7);
result.should.matchIds([1, 3, 4, 5, 6, 7, 8]);
});
});
it('any author is sam or any tag is cgi', function () {
const mongoJSON = {
$or: [
{
'authors.slug': 'sam'
},
{
'tags.slug': 'cgi'
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(4);
result.should.matchIds([2, 3, 4, 8]);
});
});
it('any author is not pat or any tag is in [animal]', function () {
const mongoJSON = {
$or: [
{
'authors.slug': {
$ne: 'pat'
}
},
{
'tags.slug': {
$in: ['animal']
}
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(4);
result.should.matchIds([2, 4, 6, 8]);
});
});
it('any author is pat or leslie or lots of other do not collide when grouping', function () {
const mongoJSON = {
$or: [
{
'authors.slug': 'leslie'
},
{
'authors.slug': 'pat'
}
]
};
_.times(100, (idx) => {
const author = {'authors.slug': `author-${idx}`};
mongoJSON.$or.push(author);
});
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(7);
result.should.matchIds([1, 3, 4, 5, 6, 7, 8]);
});
});
describe('Multiple conditions applied to the joining table and to the destination table', function () {
it('tags.slug equals "animal" and posts_tags.sort_order is 0 OR author_id is 1', function () {
const mongoJSON = {
$or: [
{
$and: [
{
'tags.slug': 'animal'
},
{
'posts_tags.sort_order': 0
},
{
featured: false
}
]
},
{
author_id: 1
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(6);
result.should.matchIds([1, 2, 3, 5, 6, 7]);
});
});
it('(tags.slug = animal and sort_order = 0) OR visibility:internal', function () {
const mongoJSON = {
$or: [
{
$and: [
{
'tags.slug': 'animal'
},
{
'posts_tags.sort_order': 0
}
]
},
{
'tags.visibility': 'internal'
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(2);
result.should.matchIds([2, 8]);
});
});
it('tags.slug = animal OR sort_order = 0 OR visibility:internal', function () {
const mongoJSON = {
$or: [
{
'tags.slug': 'animal'
},
{
'posts_tags.sort_order': 0
},
{
'tags.visibility': 'internal'
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(7);
result.should.matchIds([1, 2, 3, 4, 5, 6, 8]);
});
});
});
});
describe('IN $in', function () {
it('tags.slug IN (animal)', function () {
const mongoJSON = {
'tags.slug': {
$in: ['animal']
}
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(3);
result.should.matchIds([2, 4, 6]);
});
});
it('tags.slug IN (animal, cgi)', function () {
const mongoJSON = {
'tags.slug': {
$in: ['animal', 'cgi']
}
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(4);
result.should.matchIds([2, 3, 4, 6]);
});
});
it('tags.id IN (2,3)', function () {
const mongoJSON = {
'tags.id': {
$in: [2, 3]
}
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(4);
result.should.matchIds([2, 3, 4, 6]);
});
});
it('tags.slug IN (animal) AND featured:true', function () {
const mongoJSON = {
$and: [
{
'tags.slug': {
$in: ['animal']
}
},
{
featured: true
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(2);
result.should.matchIds([4, 6]);
});
});
});
describe('NOT IN $nin', function () {
it('tags.slug NOT IN (animal)', function () {
const mongoJSON = {
'tags.slug': {
$nin: ['animal']
}
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(5);
result.should.matchIds([1, 3, 5, 7, 8]);
});
});
it('tags.slug NOT IN (animal, cgi)', function () {
const mongoJSON = {
'tags.slug': {
$nin: ['animal', 'cgi']
}
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(4);
result.should.matchIds([1, 5, 7, 8]);
});
});
it('tags.id NOT IN (2,3)', function () {
const mongoJSON = {
'tags.id': {
$nin: [2, 3]
}
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(4);
result.should.matchIds([1, 5, 7, 8]);
});
});
it('tags.slug NOT IN (classic, animal) AND featured:true', function () {
const mongoJSON = {
$and: [
{
'tags.slug': {
$nin: ['classic', 'animal']
}
},
{
featured: true
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(3);
result.should.matchIds([3, 7, 8]);
});
});
});
describe('COUNT', function () {
it.skip('can compare by count $gt', function () {
const mongoJSON = {
'authors.count': {$gt: 0}
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(3);
});
});
it.skip('can compare by count $lt', function () {
const mongoJSON = {
'authors.count': {$lt: 2}
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(3);
});
});
});
});
describe('One-to-One', function () {
describe('EQUALS $eq', function () {
it('posts_meta.meta_title equals "Meta of A Whole New World"', function () {
const mongoJSON = {
'posts_meta.meta_title': 'Meta of A Whole New World'
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(1);
result[0].title.should.equal('A Whole New World');
});
});
});
describe('NEGATION $ne', function () {
it('posts_meta.meta_title not equal "Meta of A Whole New World"', function () {
const mongoJSON = {
'posts_meta.meta_title': {
$ne: 'Meta of A Whole New World'
}
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
// result should also contain records that do not have meta_title record - null
result.should.matchIds([2, 3, 4, 5, 6, 7, 8]);
result.forEach((post) => {
'A Whole New World'.should.not.equal(post.title);
});
});
});
it('posts_meta.meta_title not equal null', function () {
const mongoJSON = {
'posts_meta.meta_title': {
$ne: null
}
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.matchIds([1, 4, 5]);
});
});
it('posts_meta.meta_title not equal null and featured is false', function () {
const mongoJSON = {
'posts_meta.meta_title': {
$ne: null
},
featured: false
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.matchIds([1]);
});
});
});
describe('COMPARISONS $gt / $gte / $lt / $lte', function () {
it('posts_meta.like_count is > 10', function () {
const mongoJSON = {'posts_meta.like_count': {
$gt: 10
}};
const query = makeQuery(mongoJSON);
return query
.then((result) => {
result.length.should.eql(2);
result.should.matchIds([4, 5]);
});
});
it('posts_meta.like_count is >= 10', function () {
const mongoJSON = {'posts_meta.like_count': {
$gte: '10'
}};
const query = makeQuery(mongoJSON);
return query
.then((result) => {
result.length.should.eql(3);
result.should.matchIds([1, 4, 5]);
});
});
it('posts_meta.like_count is < 42', function () {
const mongoJSON = {'posts_meta.like_count': {
$lt: '42'
}};
const query = makeQuery(mongoJSON);
return query
.then((result) => {
result.length.should.eql(1);
result.should.matchIds([1]);
});
});
it('posts_meta.like_count is <= 42', function () {
const mongoJSON = {'posts_meta.like_count': {
$lte: '42'
}};
const query = makeQuery(mongoJSON);
return query
.then((result) => {
result.length.should.eql(3);
result.should.matchIds([1, 4, 5]);
});
});
});
describe('AND $and', function () {
it('basic', function () {
const mongoJSON = {
$and: [
{
'posts_meta.like_count': 42
},
{
'posts_meta.meta_title': 'Meta of Circle of Life'
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(1);
result.should.matchIds([4]);
});
});
it('gruoped and with negated NOT IN statement', function () {
const mongoJSON = {
$and: [
{
'posts_meta.like_count': 10
},
{
'posts_meta.meta_title': {
$nin: ['Meta of Circle of Life']
}
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(1);
result.should.matchIds([1]);
});
});
it('grouped and', function () {
const mongoJSON = {
$and: [
{
'posts_meta.like_count': 42
},
{
'posts.title': 'Circle of Life'
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(1);
result.should.matchIds([4]);
});
});
it('(nested and on joined table with condition on original table', function () {
const mongoJSON = {
$and: [
{
$and: [
{
'posts_meta.like_count': 42
},
{
'posts_meta.meta_title': 'Meta of Circle of Life'
}
]
},
{
'posts.title': 'Circle of Life'
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(1);
result.should.matchIds([4]);
});
});
it('multiple types of fields form parent and join tables', function () {
const mongoJSON = {
$and: [
{
'posts_meta.meta_title': 'Meta of Circle of Life'
},
{
'posts.image': null
},
{
'posts_meta.like_count': 42
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(1);
result.should.matchIds([4]);
});
});
it('nested negations', function () {
// equivalent to $nin: ['animal', 'cgi']
const mongoJSON = {
$and: [
{
'posts_meta.like_count': {
$ne: 777
}
},
{
'posts_meta.like_count': {
$ne: 42
}
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(6);
result.should.matchIds([1,2,3,6,7,8]);
});
});
it('grouped negation', function () {
const mongoJSON = {
'posts_meta.like_count': 42,
'posts_meta.meta_title': {
$ne: 'Meta of Circle of Life'
}
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(1);
result.should.matchIds([5]);
});
});
it('grouped negation with IN', function () {
const mongoJSON = {
'posts_meta.like_count': 42,
'posts_meta.meta_description': {
$nin: ['Till we find our place nn the path unwinding in the circle the circle of life.']
}
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(1);
result.should.matchIds([5]);
});
});
});
describe('OR $or', function () {
it('basic case', function () {
const mongoJSON = {
$or: [
{
'posts_meta.meta_title': 'Meta of Circle of Life'
},
{
'posts_meta.meta_title': 'Meta of Be Our Guest'
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(2);
result.should.matchIds([4, 5]);
});
});
it('different fields', function () {
const mongoJSON = {
$or: [
{
'posts_meta.meta_title': 'Meta of Circle of Life'
},
{
'posts_meta.like_count': 10
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(2);
result.should.matchIds([1, 4]);
});
});
it('not equal and in grouping', function () {
const mongoJSON = {
$or: [
{
'posts_meta.like_count': {
$ne: 42
}
},
{
'posts_meta.meta_description': {
$in: [null]
}
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(6);
result.should.matchIds([1, 2, 3, 6, 7, 8]);
});
});
it('any author is pat or leslie or lots of other do not collide when grouping', function () {
const mongoJSON = {
$or: [
{
'posts_meta.meta_title': 'Meta of Circle of Life'
},
{
'posts_meta.meta_title': 'Meta of A Whole New World'
}
]
};
_.times(100, (idx) => {
const condition = {'posts_meta.meta_title': `meta-title-${idx}`};
mongoJSON.$or.push(condition);
});
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(2);
result.should.matchIds([1, 4]);
});
});
describe('Multiple conditions applied to the joining table and to the destination table', function () {
it('tags.slug equals "animal" and posts_tags.sort_order is 0 OR author_id is 1', function () {
const mongoJSON = {
$or: [
{
$and: [
{
'posts_meta.meta_title': 'Meta of Be Our Guest'
},
{
'posts_meta.like_count': 42
}
]
},
{
featured: false
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(3);
result.should.matchIds([1, 2, 5]);
});
});
});
});
describe('IN $in', function () {
it('basic case', function () {
const mongoJSON = {
'posts_meta.like_count': {
$in: [42]
}
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(2);
result.should.matchIds([4, 5]);
});
});
it('multipe parameters', function () {
const mongoJSON = {
'posts_meta.like_count': {
$in: [42, 11]
}
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(2);
result.should.matchIds([4, 5]);
});
});
it('combination with other fields', function () {
const mongoJSON = {
$and: [
{
'posts_meta.like_count': {
$in: [10]
}
},
{
title: 'A Whole New World'
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(1);
result.should.matchIds([1]);
});
});
});
describe('NOT IN $nin', function () {
it('basic case', function () {
const mongoJSON = {
'posts_meta.like_count': {
$nin: [42]
}
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(6);
result.should.matchIds([1, 2, 3, 6, 7, 8]);
});
});
it('multiple values', function () {
const mongoJSON = {
'posts_meta.like_count': {
$nin: [42, 10]
}
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(5);
result.should.matchIds([2, 3, 6, 7, 8]);
});
});
it('multiple values with filter on parent table', function () {
const mongoJSON = {
$and: [
{
'posts_meta.like_count': {
$nin: [42]
}
},
{
featured: false
}
]
};
const query = makeQuery(mongoJSON);
return query
.select()
.then((result) => {
result.should.be.an.Array().with.lengthOf(2);
result.should.matchIds([1, 2]);
});
});
});
});
describe('[NOT IMPLEMENTED] One-to-Many', function () {});
});