2023-05-24 12:00:59 +03:00
|
|
|
import assert from 'assert';
|
|
|
|
import ObjectID from 'bson-objectid';
|
|
|
|
import {Collection} from '../src/index';
|
|
|
|
|
2023-06-29 00:33:32 +03:00
|
|
|
const uniqueChecker = {
|
|
|
|
async isUniqueSlug() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-05-24 12:00:59 +03:00
|
|
|
describe('Collection', function () {
|
|
|
|
it('Create Collection entity', async function () {
|
|
|
|
const collection = await Collection.create({
|
|
|
|
title: 'Test Collection'
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.ok(collection instanceof Collection);
|
|
|
|
assert.ok(collection.id, 'generated id should be set');
|
|
|
|
assert.ok(ObjectID.isValid(collection.id), 'generated id should be valid ObjectID');
|
|
|
|
|
|
|
|
assert.equal(collection.title, 'Test Collection');
|
|
|
|
assert.ok(collection.createdAt instanceof Date);
|
|
|
|
assert.ok(collection.updatedAt instanceof Date);
|
|
|
|
assert.ok((collection.deleted === false), 'deleted should be false');
|
|
|
|
});
|
|
|
|
|
2023-06-29 00:44:53 +03:00
|
|
|
it('Cannot create a collection without a title', async function () {
|
|
|
|
assert.rejects(async () => {
|
|
|
|
await Collection.create({});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2023-05-24 12:56:41 +03:00
|
|
|
it('Can serialize Collection to JSON', async function () {
|
|
|
|
const collection = await Collection.create({
|
2023-05-25 18:34:59 +03:00
|
|
|
title: 'Serialize me',
|
|
|
|
posts: [{
|
|
|
|
id: 'post-1'
|
|
|
|
}, {
|
|
|
|
id: 'post-2'
|
|
|
|
}]
|
2023-05-24 12:56:41 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
const json = collection.toJSON();
|
|
|
|
|
|
|
|
assert.ok(json);
|
|
|
|
assert.equal(json.id, collection.id);
|
|
|
|
assert.equal(json.title, 'Serialize me');
|
|
|
|
assert.ok(collection.createdAt instanceof Date);
|
|
|
|
assert.ok(collection.updatedAt instanceof Date);
|
2023-05-25 18:34:59 +03:00
|
|
|
assert.equal(Object.keys(json).length, 10, 'should only have 9 keys + 1 posts relation');
|
2023-05-24 12:56:41 +03:00
|
|
|
assert.deepEqual(Object.keys(json), [
|
|
|
|
'id',
|
|
|
|
'title',
|
|
|
|
'slug',
|
|
|
|
'description',
|
|
|
|
'type',
|
|
|
|
'filter',
|
|
|
|
'featureImage',
|
|
|
|
'createdAt',
|
2023-05-25 18:34:59 +03:00
|
|
|
'updatedAt',
|
|
|
|
'posts'
|
|
|
|
]);
|
|
|
|
|
|
|
|
assert.equal(json.posts.length, 2, 'should have 2 posts');
|
|
|
|
const serializedPost = json.posts[0];
|
2023-06-01 07:13:50 +03:00
|
|
|
assert.equal(Object.keys(serializedPost).length, 1, 'should only have 1 key');
|
2023-05-25 18:34:59 +03:00
|
|
|
assert.deepEqual(Object.keys(serializedPost), [
|
2023-06-01 07:13:50 +03:00
|
|
|
'id'
|
2023-05-24 12:56:41 +03:00
|
|
|
]);
|
|
|
|
});
|
|
|
|
|
2023-05-24 12:00:59 +03:00
|
|
|
it('Can create a Collection with predefined ID', async function () {
|
|
|
|
const id = new ObjectID();
|
|
|
|
const savedCollection = await Collection.create({
|
2023-06-29 00:44:53 +03:00
|
|
|
id: id.toHexString(),
|
|
|
|
title: 'Blah'
|
2023-05-24 12:00:59 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
assert.equal(savedCollection.id, id.toHexString(), 'Collection should have same id');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Can create a Collection with predefined ObjectID instance', async function () {
|
|
|
|
const id = new ObjectID();
|
|
|
|
const savedCollection = await Collection.create({
|
2023-06-29 00:44:53 +03:00
|
|
|
id: id,
|
|
|
|
title: 'Bleh'
|
2023-05-24 12:00:59 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
assert.equal(savedCollection.id, id.toHexString(), 'Collection should have same id');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Can create a Collection with predefined created_at and updated_at values', async function () {
|
|
|
|
const createdAt = new Date();
|
|
|
|
const updatedAt = new Date();
|
|
|
|
const savedCollection = await Collection.create({
|
|
|
|
created_at: createdAt,
|
2023-06-29 00:44:53 +03:00
|
|
|
updated_at: updatedAt,
|
|
|
|
title: 'Bluh'
|
2023-05-24 12:00:59 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
assert.equal(savedCollection.createdAt, createdAt, 'Collection should have same created_at');
|
|
|
|
assert.equal(savedCollection.updatedAt, updatedAt, 'Collection should have same updated_at');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Throws an error when trying to create a Collection with an invalid ID', async function () {
|
2023-06-01 13:05:40 +03:00
|
|
|
await assert.rejects(async () => {
|
2023-05-24 12:00:59 +03:00
|
|
|
await Collection.create({
|
|
|
|
id: 12345
|
|
|
|
});
|
|
|
|
}, (err: any) => {
|
|
|
|
assert.equal(err.message, 'Invalid ID provided for Collection', 'Error message should match');
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Throws an error when trying to create a Collection with invalid created_at date', async function () {
|
2023-06-01 13:05:40 +03:00
|
|
|
await assert.rejects(async () => {
|
2023-05-24 12:00:59 +03:00
|
|
|
await Collection.create({
|
2023-06-29 00:44:53 +03:00
|
|
|
created_at: 'invalid date',
|
|
|
|
title: 'Blih'
|
2023-05-24 12:00:59 +03:00
|
|
|
});
|
|
|
|
}, (err: any) => {
|
|
|
|
assert.equal(err.message, 'Invalid date provided for created_at', 'Error message should match');
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
});
|
2023-06-01 07:13:50 +03:00
|
|
|
|
2023-06-01 13:05:40 +03:00
|
|
|
it('Throws an error when trying to create an automatic Collection without a filter', async function () {
|
|
|
|
await assert.rejects(async () => {
|
|
|
|
await Collection.create({
|
|
|
|
type: 'automatic',
|
|
|
|
filter: null
|
|
|
|
});
|
|
|
|
}, (err: any) => {
|
|
|
|
assert.equal(err.message, 'Invalid filter provided for automatic Collection', 'Error message should match');
|
|
|
|
assert.equal(err.context, 'Automatic type of collection should always have a filter value', 'Error message should match');
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2023-06-29 00:33:32 +03:00
|
|
|
describe('setSlug', function () {
|
|
|
|
it('Does not bother checking uniqueness if slug is unchanged', async function () {
|
|
|
|
const collection = await Collection.create({
|
|
|
|
slug: 'test-collection',
|
|
|
|
title: 'Testing edits',
|
|
|
|
type: 'automatic',
|
|
|
|
filter: 'featured:true'
|
|
|
|
});
|
|
|
|
|
|
|
|
await collection.setSlug('test-collection', {
|
|
|
|
isUniqueSlug: () => {
|
|
|
|
throw new Error('Should not have checked uniqueness');
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Throws an error if slug is not unique', async function () {
|
|
|
|
const collection = await Collection.create({
|
|
|
|
slug: 'test-collection',
|
|
|
|
title: 'Testing edits',
|
|
|
|
type: 'automatic',
|
|
|
|
filter: 'featured:true'
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.rejects(async () => {
|
|
|
|
await collection.setSlug('not-unique', {
|
|
|
|
async isUniqueSlug() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2023-06-23 09:53:25 +03:00
|
|
|
describe('edit', function () {
|
|
|
|
it('Can edit Collection values', async function () {
|
|
|
|
const collection = await Collection.create({
|
|
|
|
slug: 'test-collection',
|
|
|
|
title: 'Testing edits',
|
|
|
|
type: 'automatic',
|
|
|
|
filter: 'featured:true'
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.equal(collection.title, 'Testing edits');
|
|
|
|
|
2023-06-29 00:33:32 +03:00
|
|
|
await collection.edit({
|
2023-06-23 09:53:25 +03:00
|
|
|
title: 'Edited title',
|
|
|
|
slug: 'edited-slug'
|
2023-06-29 00:33:32 +03:00
|
|
|
}, uniqueChecker);
|
2023-06-23 09:53:25 +03:00
|
|
|
|
|
|
|
assert.equal(collection.title, 'Edited title');
|
|
|
|
assert.equal(collection.slug, 'edited-slug');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Throws when the collection filter is empty', async function () {
|
|
|
|
const collection = await Collection.create({
|
|
|
|
title: 'Testing edits',
|
|
|
|
type: 'automatic',
|
|
|
|
filter: 'featured:true'
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.rejects(async () => {
|
|
|
|
await collection.edit({
|
|
|
|
filter: null
|
2023-06-29 00:33:32 +03:00
|
|
|
}, uniqueChecker);
|
2023-06-23 09:53:25 +03:00
|
|
|
}, (err: any) => {
|
|
|
|
assert.equal(err.message, 'Invalid filter provided for automatic Collection', 'Error message should match');
|
|
|
|
assert.equal(err.context, 'Automatic type of collection should always have a filter value', 'Error message should match');
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
});
|
2023-07-10 07:33:16 +03:00
|
|
|
|
2023-07-10 05:19:04 +03:00
|
|
|
it('Does not throw when collection filter is empty for automatic "latest" collection', async function (){
|
2023-07-10 07:33:16 +03:00
|
|
|
const collection = await Collection.create({
|
2023-07-10 05:19:04 +03:00
|
|
|
title: 'Latest',
|
|
|
|
slug: 'latest',
|
2023-07-10 07:33:16 +03:00
|
|
|
type: 'automatic',
|
|
|
|
filter: ''
|
|
|
|
});
|
|
|
|
|
|
|
|
const editedCollection = await collection.edit({
|
2023-07-10 05:19:04 +03:00
|
|
|
title: 'Edited latest',
|
2023-07-10 07:33:16 +03:00
|
|
|
filter: ''
|
|
|
|
}, uniqueChecker);
|
|
|
|
|
2023-07-10 05:19:04 +03:00
|
|
|
assert.equal(editedCollection.title, 'Edited latest');
|
2023-07-10 07:33:16 +03:00
|
|
|
assert.equal(editedCollection.filter, '');
|
|
|
|
});
|
2023-06-23 09:53:25 +03:00
|
|
|
});
|
|
|
|
|
2023-06-01 07:13:50 +03:00
|
|
|
it('Can add posts to different positions', async function () {
|
|
|
|
const collection = await Collection.create({
|
2023-06-23 09:56:06 +03:00
|
|
|
title: 'Testing adding posts',
|
|
|
|
type: 'manual'
|
2023-06-01 07:13:50 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
assert(collection.posts.length === 0);
|
|
|
|
|
|
|
|
const posts = [{
|
2023-07-27 16:03:14 +03:00
|
|
|
id: '0',
|
|
|
|
featured: false,
|
|
|
|
published_at: new Date(),
|
|
|
|
tags: []
|
2023-06-01 07:13:50 +03:00
|
|
|
}, {
|
2023-07-27 16:03:14 +03:00
|
|
|
id: '1',
|
|
|
|
featured: false,
|
|
|
|
published_at: new Date(),
|
|
|
|
tags: []
|
2023-06-01 07:13:50 +03:00
|
|
|
}, {
|
2023-07-27 16:03:14 +03:00
|
|
|
id: '2',
|
|
|
|
featured: false,
|
|
|
|
published_at: new Date(),
|
|
|
|
tags: []
|
2023-06-01 07:13:50 +03:00
|
|
|
}, {
|
2023-07-27 16:03:14 +03:00
|
|
|
id: '3',
|
|
|
|
featured: false,
|
|
|
|
published_at: new Date(),
|
|
|
|
tags: []
|
2023-06-01 07:13:50 +03:00
|
|
|
}];
|
|
|
|
|
|
|
|
collection.addPost(posts[0]);
|
|
|
|
collection.addPost(posts[1]);
|
|
|
|
collection.addPost(posts[2], 1);
|
|
|
|
collection.addPost(posts[3], 0);
|
|
|
|
|
|
|
|
assert(collection.posts.length as number === 4);
|
|
|
|
assert(collection.posts[0] === '3');
|
|
|
|
|
|
|
|
collection.addPost(posts[3], -1);
|
|
|
|
assert(collection.posts.length as number === 4);
|
|
|
|
assert(collection.posts[collection.posts.length - 2] === '3');
|
|
|
|
});
|
2023-06-01 10:57:47 +03:00
|
|
|
|
2023-06-23 09:56:06 +03:00
|
|
|
it('Adds a post to an automatic collection when it matches the filter', async function () {
|
|
|
|
const collection = await Collection.create({
|
|
|
|
title: 'Testing adding posts',
|
|
|
|
type: 'automatic',
|
|
|
|
filter: 'featured:true'
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.equal(collection.posts.length, 0, 'Collection should have no posts');
|
|
|
|
|
|
|
|
const added = await collection.addPost({
|
|
|
|
id: '0',
|
2023-07-27 16:03:14 +03:00
|
|
|
featured: false,
|
|
|
|
published_at: new Date(),
|
|
|
|
tags: []
|
2023-06-23 09:56:06 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
assert.equal(added, false);
|
|
|
|
assert.equal(collection.posts.length, 0, 'The non-featured post should not have been added');
|
|
|
|
|
|
|
|
const featuredAdded = await collection.addPost({
|
|
|
|
id: '1',
|
2023-07-27 16:03:14 +03:00
|
|
|
featured: true,
|
|
|
|
published_at: new Date(),
|
|
|
|
tags: []
|
2023-06-23 09:56:06 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
assert.equal(featuredAdded, true);
|
|
|
|
assert.equal(collection.posts.length, 1, 'The featured post should have been added');
|
|
|
|
});
|
|
|
|
|
2023-06-01 10:57:47 +03:00
|
|
|
it('Removes a post by id', async function () {
|
|
|
|
const collection = await Collection.create({
|
|
|
|
title: 'Testing adding posts'
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.equal(collection.posts.length, 0);
|
|
|
|
|
|
|
|
collection.addPost({
|
2023-07-27 16:03:14 +03:00
|
|
|
id: '0',
|
|
|
|
featured: false,
|
|
|
|
published_at: new Date(),
|
|
|
|
tags: []
|
|
|
|
|
2023-06-01 10:57:47 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
assert.equal(collection.posts.length, 1);
|
|
|
|
|
|
|
|
collection.removePost('0');
|
|
|
|
|
|
|
|
assert.equal(collection.posts.length, 0);
|
|
|
|
});
|
2023-06-06 18:04:02 +03:00
|
|
|
|
2023-07-10 05:19:04 +03:00
|
|
|
it('Cannot set "latest" collection to deleted', async function () {
|
2023-06-06 18:04:02 +03:00
|
|
|
const collection = await Collection.create({
|
|
|
|
title: 'Testing adding posts',
|
2023-07-10 05:19:04 +03:00
|
|
|
slug: 'latest'
|
2023-06-06 18:04:02 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
assert.equal(collection.deleted, false);
|
|
|
|
|
|
|
|
collection.deleted = true;
|
|
|
|
|
|
|
|
assert.equal(collection.deleted, false);
|
|
|
|
});
|
|
|
|
|
2023-06-29 00:36:36 +03:00
|
|
|
it('Cannot set featured collection to deleted', async function () {
|
2023-06-06 18:04:02 +03:00
|
|
|
const collection = await Collection.create({
|
|
|
|
title: 'Testing adding posts',
|
2023-06-29 00:36:36 +03:00
|
|
|
slug: 'featured'
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.equal(collection.deleted, false);
|
|
|
|
|
|
|
|
collection.deleted = true;
|
|
|
|
|
|
|
|
assert.equal(collection.deleted, false);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Can set other collection to deleted', async function () {
|
|
|
|
const collection = await Collection.create({
|
|
|
|
title: 'Testing adding posts',
|
|
|
|
slug: 'non-internal-slug'
|
2023-06-06 18:04:02 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
assert.equal(collection.deleted, false);
|
|
|
|
|
|
|
|
collection.deleted = true;
|
|
|
|
|
|
|
|
assert.equal(collection.deleted, true);
|
|
|
|
});
|
2023-06-26 12:26:53 +03:00
|
|
|
|
|
|
|
describe('postMatchesFilter', function () {
|
|
|
|
it('Can match a post with a filter', async function () {
|
|
|
|
const collection = await Collection.create({
|
|
|
|
title: 'Testing filtering posts',
|
2023-06-26 12:29:32 +03:00
|
|
|
type: 'automatic',
|
|
|
|
filter: 'featured:true'
|
2023-06-26 12:26:53 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
const featuredPost = {
|
|
|
|
id: '0',
|
2023-07-27 16:03:14 +03:00
|
|
|
featured: true,
|
|
|
|
published_at: new Date(),
|
|
|
|
tags: []
|
2023-06-26 12:26:53 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
const nonFeaturedPost = {
|
|
|
|
id: '1',
|
2023-07-27 16:03:14 +03:00
|
|
|
featured: false,
|
|
|
|
published_at: new Date(),
|
|
|
|
tags: []
|
2023-06-26 12:26:53 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
assert.ok(collection.postMatchesFilter(featuredPost), 'Post should match the filter');
|
|
|
|
assert.ok(!collection.postMatchesFilter(nonFeaturedPost), 'Post should not match the filter');
|
|
|
|
});
|
2023-07-24 16:49:43 +03:00
|
|
|
|
|
|
|
it('Can match a post with a tag filter', async function () {
|
|
|
|
const collection = await Collection.create({
|
|
|
|
title: 'Testing filtering posts',
|
|
|
|
type: 'automatic',
|
|
|
|
filter: 'tag:avocado'
|
|
|
|
});
|
|
|
|
|
|
|
|
const avocadoPost = {
|
|
|
|
id: '0',
|
2023-07-27 16:03:14 +03:00
|
|
|
featured: false,
|
2023-07-24 16:49:43 +03:00
|
|
|
tags: [{
|
|
|
|
slug: 'avocado'
|
2023-07-27 16:03:14 +03:00
|
|
|
}],
|
|
|
|
published_at: new Date()
|
2023-07-24 16:49:43 +03:00
|
|
|
};
|
|
|
|
const nonAvocadoPost = {
|
|
|
|
id: '1',
|
2023-07-27 16:03:14 +03:00
|
|
|
featured: false,
|
2023-07-24 16:49:43 +03:00
|
|
|
tags: [{
|
|
|
|
slug: 'not-avocado'
|
2023-07-27 16:03:14 +03:00
|
|
|
}],
|
|
|
|
published_at: new Date()
|
2023-07-24 16:49:43 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
assert.ok(collection.postMatchesFilter(avocadoPost), 'Post should match the filter');
|
|
|
|
assert.ok(!collection.postMatchesFilter(nonAvocadoPost), 'Post should not match the filter');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Can match a post with a tags filter', async function () {
|
|
|
|
const collection = await Collection.create({
|
|
|
|
title: 'Testing filtering posts',
|
|
|
|
type: 'automatic',
|
|
|
|
filter: 'tags:avocado'
|
|
|
|
});
|
|
|
|
|
|
|
|
const avocadoPost = {
|
|
|
|
id: '0',
|
2023-07-27 16:03:14 +03:00
|
|
|
featured: false,
|
2023-07-24 16:49:43 +03:00
|
|
|
tags: [{
|
|
|
|
slug: 'avocado'
|
2023-07-27 16:03:14 +03:00
|
|
|
}],
|
|
|
|
published_at: new Date()
|
2023-07-24 16:49:43 +03:00
|
|
|
};
|
|
|
|
const nonAvocadoPost = {
|
|
|
|
id: '1',
|
2023-07-27 16:03:14 +03:00
|
|
|
featured: false,
|
2023-07-24 16:49:43 +03:00
|
|
|
tags: [{
|
|
|
|
slug: 'not-avocado'
|
2023-07-27 16:03:14 +03:00
|
|
|
}],
|
|
|
|
published_at: new Date()
|
2023-07-24 16:49:43 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
assert.ok(collection.postMatchesFilter(avocadoPost), 'Post should match the filter');
|
|
|
|
assert.ok(!collection.postMatchesFilter(nonAvocadoPost), 'Post should not match the filter');
|
|
|
|
});
|
2023-06-26 12:26:53 +03:00
|
|
|
});
|
2023-05-24 12:00:59 +03:00
|
|
|
});
|