Added use of a slug generator to offload calculation of slugs

When we end up wiring this to the database, this generator will also ensure
uniqueness by appending/incrementing a number on the end of the slug. Long term
it would be good to offload this to a shared slug service, this could also
ensure that slugs are unique globally or between multiple tables, if desired
This commit is contained in:
Fabien "egg" O'Carroll 2023-06-28 22:50:50 +01:00 committed by Fabien 'egg' O'Carroll
parent 0a3e36cd62
commit cf83d169db
6 changed files with 47 additions and 16 deletions

View File

@ -20,9 +20,14 @@ const messages = {
} }
}; };
interface SlugService {
generate(desired: string): Promise<string>;
}
type CollectionsServiceDeps = { type CollectionsServiceDeps = {
collectionsRepository: CollectionRepository; collectionsRepository: CollectionRepository;
postsRepository: PostsRepository; postsRepository: PostsRepository;
slugService: SlugService;
DomainEvents: { DomainEvents: {
subscribe: (event: any, handler: (e: any) => void) => void; subscribe: (event: any, handler: (e: any) => void) => void;
}; };
@ -96,12 +101,14 @@ export class CollectionsService {
subscribe: (event: any, handler: (e: any) => void) => void; subscribe: (event: any, handler: (e: any) => void) => void;
}; };
private uniqueChecker: RepositoryUniqueChecker; private uniqueChecker: RepositoryUniqueChecker;
private slugService: SlugService;
constructor(deps: CollectionsServiceDeps) { constructor(deps: CollectionsServiceDeps) {
this.collectionsRepository = deps.collectionsRepository; this.collectionsRepository = deps.collectionsRepository;
this.postsRepository = deps.postsRepository; this.postsRepository = deps.postsRepository;
this.DomainEvents = deps.DomainEvents; this.DomainEvents = deps.DomainEvents;
this.uniqueChecker = new RepositoryUniqueChecker(this.collectionsRepository); this.uniqueChecker = new RepositoryUniqueChecker(this.collectionsRepository);
this.slugService = deps.slugService;
} }
private toDTO(collection: Collection): CollectionDTO { private toDTO(collection: Collection): CollectionDTO {
@ -165,9 +172,10 @@ export class CollectionsService {
} }
async createCollection(data: CollectionInputDTO): Promise<CollectionDTO> { async createCollection(data: CollectionInputDTO): Promise<CollectionDTO> {
const slug = await this.slugService.generate(data.slug || data.title);
const collection = await Collection.create({ const collection = await Collection.create({
title: data.title, title: data.title,
slug: data.slug, slug: slug,
description: data.description, description: data.description,
type: data.type, type: data.type,
filter: data.filter, filter: data.filter,

View File

@ -41,7 +41,12 @@ describe('CollectionsService', function () {
collectionsService = new CollectionsService({ collectionsService = new CollectionsService({
collectionsRepository, collectionsRepository,
postsRepository, postsRepository,
DomainEvents DomainEvents,
slugService: {
async generate(input) {
return input.replace(/\s+/g, '-').toLowerCase();
}
}
}); });
}); });
@ -199,10 +204,12 @@ describe('CollectionsService', function () {
id: savedCollection.id, id: savedCollection.id,
title: 'Edited title', title: 'Edited title',
description: 'Edited description', description: 'Edited description',
feature_image: '/assets/images/edited.jpg' feature_image: '/assets/images/edited.jpg',
slug: 'changed'
}); });
assert.equal(editedCollection?.title, 'Edited title', 'Collection title should be edited'); assert.equal(editedCollection?.title, 'Edited title', 'Collection title should be edited');
assert.equal(editedCollection?.slug, 'changed', 'Collection slug should be edited');
assert.equal(editedCollection?.description, 'Edited description', 'Collection description should be edited'); assert.equal(editedCollection?.description, 'Edited description', 'Collection description should be edited');
assert.equal(editedCollection?.feature_image, '/assets/images/edited.jpg', 'Collection feature_image should be edited'); assert.equal(editedCollection?.feature_image, '/assets/images/edited.jpg', 'Collection feature_image should be edited');
assert.equal(editedCollection?.type, 'manual', 'Collection type should not be edited'); assert.equal(editedCollection?.type, 'manual', 'Collection type should not be edited');

View File

@ -16,7 +16,12 @@ class CollectionsServiceWrapper {
const collectionsService = new CollectionsService({ const collectionsService = new CollectionsService({
collectionsRepository: collectionsRepositoryInMemory, collectionsRepository: collectionsRepositoryInMemory,
postsRepository: postsRepository, postsRepository: postsRepository,
DomainEvents: DomainEvents DomainEvents: DomainEvents,
slugService: {
async generate(input) {
return input.toLowerCase().trim().replace(/^[^a-z0-9A-Z_]+/, '').replace(/[^a-z0-9A-Z_]+$/, '').replace(/[^a-z0-9A-Z_]+/g, '-');
}
}
}); });
this.api = collectionsService; this.api = collectionsService;

View File

@ -19,7 +19,8 @@ Object {
"sort_order": 1, "sort_order": 1,
}, },
], ],
"title": "Test Collection", "slug": "test-featured-collection",
"title": "Test Featured Collection",
"type": "automatic", "type": "automatic",
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
}, },
@ -31,7 +32,7 @@ exports[`Collections API Automatic Collection Filtering Creates an automatic Col
Object { Object {
"access-control-allow-origin": "http://127.0.0.1:2369", "access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0", "cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "374", "content-length": "417",
"content-type": "application/json; charset=utf-8", "content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/, "content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
@ -81,6 +82,7 @@ Object {
"sort_order": 6, "sort_order": 6,
}, },
], ],
"slug": "test-collection-with-published_at-filter",
"title": "Test Collection with published_at filter", "title": "Test Collection with published_at filter",
"type": "automatic", "type": "automatic",
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
@ -93,7 +95,7 @@ exports[`Collections API Automatic Collection Filtering Creates an automatic Col
Object { Object {
"access-control-allow-origin": "http://127.0.0.1:2369", "access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0", "cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "681", "content-length": "731",
"content-type": "application/json; charset=utf-8", "content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/, "content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
@ -192,6 +194,7 @@ Object {
"filter": null, "filter": null,
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/, "id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
"posts": Array [], "posts": Array [],
"slug": "test-collection",
"title": "Test Collection", "title": "Test Collection",
"type": "manual", "type": "manual",
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
@ -203,6 +206,7 @@ Object {
"filter": null, "filter": null,
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/, "id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
"posts": Array [], "posts": Array [],
"slug": "test-collection-to-read",
"title": "Test Collection to Read", "title": "Test Collection to Read",
"type": "manual", "type": "manual",
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
@ -225,7 +229,7 @@ exports[`Collections API Browse Can browse Collections 2: [headers] 1`] = `
Object { Object {
"access-control-allow-origin": "http://127.0.0.1:2369", "access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0", "cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "1759", "content-length": "1817",
"content-type": "application/json; charset=utf-8", "content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/, "content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
@ -833,6 +837,7 @@ Object {
"filter": null, "filter": null,
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/, "id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
"posts": Array [], "posts": Array [],
"slug": "test-collection",
"title": "Test Collection", "title": "Test Collection",
"type": "manual", "type": "manual",
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
@ -845,7 +850,7 @@ exports[`Collections API Can add a Collection 2: [headers] 1`] = `
Object { Object {
"access-control-allow-origin": "http://127.0.0.1:2369", "access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0", "cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "263", "content-length": "288",
"content-type": "application/json; charset=utf-8", "content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/, "content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
@ -866,6 +871,7 @@ Object {
"filter": null, "filter": null,
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/, "id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
"posts": Array [], "posts": Array [],
"slug": "test-collection-to-delete",
"title": "Test Collection to Delete", "title": "Test Collection to Delete",
"type": "manual", "type": "manual",
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
@ -878,7 +884,7 @@ exports[`Collections API Can delete a Collection 2: [headers] 1`] = `
Object { Object {
"access-control-allow-origin": "http://127.0.0.1:2369", "access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0", "cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "248", "content-length": "283",
"content-type": "application/json; charset=utf-8", "content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/, "content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
@ -944,6 +950,7 @@ Object {
"filter": null, "filter": null,
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/, "id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
"posts": Array [], "posts": Array [],
"slug": "test-collection-to-read",
"title": "Test Collection to Read", "title": "Test Collection to Read",
"type": "manual", "type": "manual",
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
@ -956,7 +963,7 @@ exports[`Collections API Can read a Collection 2: [headers] 1`] = `
Object { Object {
"access-control-allow-origin": "http://127.0.0.1:2369", "access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0", "cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "246", "content-length": "279",
"content-type": "application/json; charset=utf-8", "content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/, "content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
@ -977,6 +984,7 @@ Object {
"filter": null, "filter": null,
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/, "id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
"posts": Array [], "posts": Array [],
"slug": "test-collection-to-read",
"title": "Test Collection to Read", "title": "Test Collection to Read",
"type": "manual", "type": "manual",
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
@ -989,7 +997,7 @@ exports[`Collections API Can read a Collection 4: [headers] 1`] = `
Object { Object {
"access-control-allow-origin": "http://127.0.0.1:2369", "access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0", "cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "246", "content-length": "279",
"content-type": "application/json; charset=utf-8", "content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/, "content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
@ -1039,6 +1047,7 @@ Object {
"filter": null, "filter": null,
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/, "id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
"posts": Array [], "posts": Array [],
"slug": "test-collection-to-edit",
"title": "Test Collection Edited", "title": "Test Collection Edited",
"type": "manual", "type": "manual",
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
@ -1051,7 +1060,7 @@ exports[`Collections API Edit Can edit a Collection 2: [headers] 1`] = `
Object { Object {
"access-control-allow-origin": "http://127.0.0.1:2369", "access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0", "cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "245", "content-length": "278",
"content-type": "application/json; charset=utf-8", "content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/, "content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,

View File

@ -1326,6 +1326,7 @@ Object {
"sort_order": 0, "sort_order": 0,
}, },
], ],
"slug": "collection-to-remove",
"title": "Collection to remove.", "title": "Collection to remove.",
"type": "manual", "type": "manual",
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.\\\\d\\{3\\}Z/, "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.\\\\d\\{3\\}Z/,
@ -1420,7 +1421,7 @@ exports[`Posts API Update Can add and remove collections 4: [headers] 1`] = `
Object { Object {
"access-control-allow-origin": "http://127.0.0.1:2369", "access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0", "cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "3992", "content-length": "4022",
"content-type": "application/json; charset=utf-8", "content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/, "content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
@ -1451,6 +1452,7 @@ Object {
"sort_order": 0, "sort_order": 0,
}, },
], ],
"slug": "collection-to-add",
"title": "Collection to add.", "title": "Collection to add.",
"type": "manual", "type": "manual",
"updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.\\\\d\\{3\\}Z/, "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.\\\\d\\{3\\}Z/,
@ -1545,7 +1547,7 @@ exports[`Posts API Update Can add and remove collections 6: [headers] 1`] = `
Object { Object {
"access-control-allow-origin": "http://127.0.0.1:2369", "access-control-allow-origin": "http://127.0.0.1:2369",
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0", "cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
"content-length": "3989", "content-length": "4016",
"content-type": "application/json; charset=utf-8", "content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/, "content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,

View File

@ -307,7 +307,7 @@ describe('Collections API', function () {
describe('Automatic Collection Filtering', function () { describe('Automatic Collection Filtering', function () {
it('Creates an automatic Collection with a featured filter', async function () { it('Creates an automatic Collection with a featured filter', async function () {
const collection = { const collection = {
title: 'Test Collection', title: 'Test Featured Collection',
description: 'Test Collection Description', description: 'Test Collection Description',
type: 'automatic', type: 'automatic',
filter: 'featured:true' filter: 'featured:true'