From c66eeb58794cfb1fef0c51642886937c91f58d5c Mon Sep 17 00:00:00 2001 From: Hannah Wolfe Date: Fri, 18 Mar 2022 19:41:18 +0000 Subject: [PATCH] Updated settings to use new test framework - split out the two tests that use files, as the new framework doesn't support this yet - convert the 3 existing tests for the settings endpoint to use the new framework - introduced a new pattern of using a function to generate a matching array, so that we can do extra stuff - in this case, just one of the items needed a matcher for the value, which results in slightly weird code - wrapping in a function gives us somewhere to do this and leave a comment --- .../admin/__snapshots__/settings.test.js.snap | 1124 +++++++++++++++++ test/e2e-api/admin/settings-files.test.js | 50 + test/e2e-api/admin/settings.test.js | 389 ++---- 3 files changed, 1313 insertions(+), 250 deletions(-) create mode 100644 test/e2e-api/admin/__snapshots__/settings.test.js.snap create mode 100644 test/e2e-api/admin/settings-files.test.js diff --git a/test/e2e-api/admin/__snapshots__/settings.test.js.snap b/test/e2e-api/admin/__snapshots__/settings.test.js.snap new file mode 100644 index 0000000000..c12faebc78 --- /dev/null +++ b/test/e2e-api/admin/__snapshots__/settings.test.js.snap @@ -0,0 +1,1124 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Settings API Can edit a setting 1: [body] 1`] = ` +Object { + "meta": Object {}, + "settings": Array [ + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": "PUBLIC", + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "title", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "[]", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "codeinjection_head", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": null, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "navigation", + "type": "array", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "[{\\"label\\":\\"label1\\"}]", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "slack", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "slack_username", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "New Slack Username", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "private", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "is_private", + "type": "boolean", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": false, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "meta_title", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "SEO title", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "meta_description", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "SEO description", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "og_image", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "http://127.0.0.1:2369/content/images/2019/07/facebook.png", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "og_title", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "facebook title", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "og_description", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "facebook description", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "twitter_image", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "http://127.0.0.1:2369/content/images/2019/07/twitter.png", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "twitter_title", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "twitter title", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "twitter_description", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "twitter description", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "lang", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "ua", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "labs", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "labs", + "type": "object", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "{\\"multipleProducts\\":true,\\"tierWelcomePages\\":true,\\"tierName\\":true,\\"selectablePortalLinks\\":true,\\"membersTableStatus\\":true,\\"improvedOnboarding\\":true,\\"membersActivityFeed\\":true,\\"members\\":true}", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "timezone", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "Pacific/Auckland", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "unsplash", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "unsplash", + "type": "boolean", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": false, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "slack", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "slack", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "[{\\"url\\":\\"https://overrides.tld\\",\\"username\\":\\"New Slack Username\\"}]", + }, + ], +} +`; + +exports[`Settings API Can edit a setting 2: [headers] 1`] = ` +Object { + "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", + "content-length": "3979", + "content-type": "application/json; charset=utf-8", + "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, + "vary": "Origin, Accept-Encoding", + "x-cache-invalidate": "/*", + "x-powered-by": "Express", +} +`; + +exports[`Settings API Can read a setting 1: [body] 1`] = ` +Object { + "meta": Object {}, + "settings": Array [ + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "codeinjection_head", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "", + }, + ], +} +`; + +exports[`Settings API Can read a setting 2: [headers] 1`] = ` +Object { + "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", + "content-length": "220", + "content-type": "application/json; charset=utf-8", + "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, + "vary": "Origin, Accept-Encoding", + "x-powered-by": "Express", +} +`; + +exports[`Settings API Can request all settings 1: [body] 1`] = ` +Object { + "meta": Object {}, + "settings": Array [ + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": "PUBLIC", + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "title", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "Ghost", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": "PUBLIC", + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "description", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "Thoughts, stories and ideas", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "logo", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "cover_image", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "https://static.ghost.org/v4.0.0/images/publication-cover.jpg", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "icon", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": "PUBLIC", + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "accent_color", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "#FF1A75", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "lang", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "en", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "timezone", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "Etc/UTC", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "codeinjection_head", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "codeinjection_foot", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "facebook", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "ghost", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "twitter", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "@ghost", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "navigation", + "type": "array", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "[{\\"label\\":\\"Home\\",\\"url\\":\\"/\\"},{\\"label\\":\\"About\\",\\"url\\":\\"/about/\\"},{\\"label\\":\\"Collection\\",\\"url\\":\\"/tag/getting-started/\\"},{\\"label\\":\\"Author\\",\\"url\\":\\"/author/ghost/\\"},{\\"label\\":\\"Portal\\",\\"url\\":\\"/portal/\\"}]", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "secondary_navigation", + "type": "array", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "[{\\"label\\":\\"Data & privacy\\",\\"url\\":\\"/privacy/\\"},{\\"label\\":\\"Contact\\",\\"url\\":\\"/contact/\\"},{\\"label\\":\\"Contribute →\\",\\"url\\":\\"/contribute/\\"}]", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "meta_title", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": null, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "meta_description", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": null, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "og_image", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": null, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "og_title", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": null, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "og_description", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": null, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "twitter_image", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": null, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "twitter_title", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": null, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "twitter_description", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": null, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": "RO", + "group": "theme", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "active_theme", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "casper", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "private", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "is_private", + "type": "boolean", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": false, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "private", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "password", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "private", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "public_hash", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": StringMatching /\\[a-z0-9\\]\\{30\\}/, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "members", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "default_content_visibility", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "public", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "members", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "default_content_visibility_tiers", + "type": "array", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "[]", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "members", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "members_signup_access", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "all", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": "RO", + "group": "members", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "members_from_address", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "noreply", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": "PUBLIC,RO", + "group": "members", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "members_support_address", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "noreply", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "members", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "members_reply_address", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "newsletter", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "members", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "members_free_signup_redirect", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "/", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "members", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "members_paid_signup_redirect", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "/", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "members", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "stripe_product_name", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "Ghost Subscription", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "members", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "stripe_secret_key", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": null, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "members", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "stripe_publishable_key", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": null, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "members", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "stripe_plans", + "type": "array", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "[]", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "members", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "stripe_connect_publishable_key", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "pk_test_for_stripe", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "members", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "stripe_connect_secret_key", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "••••••••", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "members", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "stripe_connect_livemode", + "type": "boolean", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": null, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "members", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "stripe_connect_display_name", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": null, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "members", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "stripe_connect_account_id", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": null, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "members", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "members_free_price_name", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "Free", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "members", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "members_free_price_description", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "Free preview", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "members", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "members_monthly_price_id", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": null, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "members", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "members_yearly_price_id", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": null, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "portal", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "portal_name", + "type": "boolean", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": true, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "portal", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "portal_button", + "type": "boolean", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": true, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "portal", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "portal_plans", + "type": "array", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "[\\"free\\"]", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "portal", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "portal_products", + "type": "array", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "[]", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "portal", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "portal_button_style", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "icon-and-text", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "portal", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "portal_button_icon", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": null, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "portal", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "portal_button_signup_text", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "Subscribe", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "email", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "mailgun_domain", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": null, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "email", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "mailgun_api_key", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": null, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "email", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "mailgun_base_url", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": null, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "email", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "email_track_opens", + "type": "boolean", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": true, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": "RO", + "group": "email", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "email_verification_required", + "type": "boolean", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": false, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "amp", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "amp", + "type": "boolean", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": false, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "amp", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "amp_gtag_id", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": null, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "firstpromoter", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "firstpromoter", + "type": "boolean", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": false, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "firstpromoter", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "firstpromoter_id", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": null, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "labs", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "labs", + "type": "object", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "{\\"activitypub\\":true,\\"oauthLogin\\":true,\\"membersActivity\\":true,\\"urlCache\\":true,\\"beforeAfterCard\\":true,\\"tweetGridCard\\":true,\\"multipleProducts\\":true,\\"tierWelcomePages\\":true,\\"tierName\\":true,\\"selectablePortalLinks\\":true,\\"membersTableStatus\\":true,\\"improvedOnboarding\\":true,\\"membersActivityFeed\\":true,\\"members\\":true}", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "slack", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "slack_url", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "slack", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "slack_username", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "Ghost", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "unsplash", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "unsplash", + "type": "boolean", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": true, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "views", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "shared_views", + "type": "array", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "[]", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "newsletter", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "newsletter_show_badge", + "type": "boolean", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": true, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "newsletter", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "newsletter_header_image", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": null, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "newsletter", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "newsletter_show_header_icon", + "type": "boolean", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": true, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "newsletter", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "newsletter_show_header_title", + "type": "boolean", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": true, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "newsletter", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "newsletter_title_alignment", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "center", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "newsletter", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "newsletter_title_font_category", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "sans_serif", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "newsletter", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "newsletter_show_feature_image", + "type": "boolean", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": true, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "newsletter", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "newsletter_body_font_category", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "sans_serif", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "newsletter", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "newsletter_footer_content", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "oauth", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "oauth_client_id", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": null, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "oauth", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "oauth_client_secret", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": null, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "editor", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "editor_default_email_recipients", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "visibility", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "editor", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "editor_default_email_recipients_filter", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "all", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "editor", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "editor_is_launch_complete", + "type": "boolean", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": false, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "active_timezone", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "Etc/UTC", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "default_locale", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "en", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "slack", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "slack", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "[{\\"url\\":\\"\\",\\"username\\":\\"Ghost\\"}]", + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "flags": null, + "group": "site", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "key": "locale", + "type": "string", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "value": "en", + }, + ], +} +`; + +exports[`Settings API Can request all settings 1: [headers] 1`] = ` +Object { + "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", + "content-length": "18219", + "content-type": "application/json; charset=utf-8", + "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, + "vary": "Origin, Accept-Encoding", + "x-powered-by": "Express", +} +`; + +exports[`Settings API Can request all settings 2: [headers] 1`] = ` +Object { + "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", + "content-length": "18219", + "content-type": "application/json; charset=utf-8", + "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, + "vary": "Origin, Accept-Encoding", + "x-powered-by": "Express", +} +`; diff --git a/test/e2e-api/admin/settings-files.test.js b/test/e2e-api/admin/settings-files.test.js new file mode 100644 index 0000000000..b2fa8f8835 --- /dev/null +++ b/test/e2e-api/admin/settings-files.test.js @@ -0,0 +1,50 @@ +const should = require('should'); +const supertest = require('supertest'); +const os = require('os'); +const fs = require('fs-extra'); +const config = require('../../../core/shared/config'); +const testUtils = require('../../utils'); +const localUtils = require('./utils'); + +/** + * The new test framework doesn't yet support files + */ +describe('Settings File API', function () { + let request; + + before(async function () { + await localUtils.startGhost(); + request = supertest.agent(config.get('url')); + await localUtils.doAuth(request); + }); + + after(function () { + return testUtils.stopGhost(); + }); + + it('Can download routes.yaml', async function () { + const res = await request.get(localUtils.API.getApiQuery('settings/routes/yaml/')) + .set('Origin', config.get('url')) + .set('Accept', 'application/yaml') + .expect(200); + + res.headers['content-disposition'].should.eql('Attachment; filename="routes.yaml"'); + res.headers['content-type'].should.eql('application/yaml; charset=utf-8'); + res.headers['content-length'].should.eql('138'); + }); + + it('Can upload routes.yaml', async function () { + const newRoutesYamlPath = `${os.tmpdir()}/routes.yaml`; + + await fs.writeFile(newRoutesYamlPath, 'routes:\ncollections:\ntaxonomies:\n'); + const res = await request + .post(localUtils.API.getApiQuery('settings/routes/yaml/')) + .set('Origin', config.get('url')) + .attach('routes', newRoutesYamlPath) + .expect('Content-Type', /application\/json/) + .expect(200); + + res.headers['x-cache-invalidate'].should.eql('/*'); + await testUtils.stopGhost(); + }); +}); diff --git a/test/e2e-api/admin/settings.test.js b/test/e2e-api/admin/settings.test.js index 5503727ace..d77715c156 100644 --- a/test/e2e-api/admin/settings.test.js +++ b/test/e2e-api/admin/settings.test.js @@ -1,266 +1,155 @@ -const should = require('should'); -const _ = require('lodash'); -const supertest = require('supertest'); -const os = require('os'); -const fs = require('fs-extra'); -const config = require('../../../core/shared/config'); -const testUtils = require('../../utils'); -const localUtils = require('./utils'); -const labs = require('../../../core/shared/labs'); +const {agentProvider, fixtureManager, matchers} = require('../../utils/e2e-framework'); +const {stringMatching, anyEtag, anyObjectId, anyISODateTime} = matchers; + +const CURRENT_SETTINGS_COUNT = 86; + +const settingsMatcher = { + id: anyObjectId, + created_at: anyISODateTime, + updated_at: anyISODateTime +}; + +const publicHashSettingMatcher = { + id: anyObjectId, + value: stringMatching(/[a-z0-9]{30}/), + created_at: anyISODateTime, + updated_at: anyISODateTime +}; + +const matchSettingsArray = (length) => { + const settingsArray = new Array(length).fill(settingsMatcher); + + if (length > 25) { + // Item at index 25 is the public hash, which is always different + settingsArray[25] = publicHashSettingMatcher; + } + + return settingsArray; +}; describe('Settings API', function () { - let request; + let agent; before(async function () { - await localUtils.startGhost(); - request = supertest.agent(config.get('url')); - await localUtils.doAuth(request); - }); - - after(function () { - return testUtils.stopGhost(); + agent = await agentProvider.getAdminAPIAgent(); + await fixtureManager.init(); + await agent.loginAsOwner(); }); it('Can request all settings', async function () { - const res = await request.get(localUtils.API.getApiQuery('settings/')) - .set('Origin', config.get('url')) - .expect('Content-Type', /json/) - .expect('Cache-Control', testUtils.cacheRules.private) - .expect(200); - - should.not.exist(res.headers['x-cache-invalidate']); - const jsonResponse = res.body; - should.exist(jsonResponse); - - localUtils.API.checkResponse(jsonResponse, 'settings'); - - JSON.parse(_.find(jsonResponse.settings, {key: 'unsplash'}).value).should.eql(true); - JSON.parse(_.find(jsonResponse.settings, {key: 'amp'}).value).should.eql(false); - should.not.exist(_.find(jsonResponse.settings, {key: 'permalinks'})); - should.not.exist(_.find(jsonResponse.settings, {key: 'ghost_head'})); - should.not.exist(_.find(jsonResponse.settings, {key: 'ghost_foot'})); - - testUtils.API.isISO8601(jsonResponse.settings[0].created_at).should.be.true(); - jsonResponse.settings[0].created_at.should.be.an.instanceof(String); - - should.not.exist(_.find(jsonResponse.settings, function (setting) { - return setting.type === 'core'; - })); + await agent + .get('settings/') + .expectStatus(200) + .matchBodySnapshot({ + settings: matchSettingsArray(CURRENT_SETTINGS_COUNT) + }) + .matchHeaderSnapshot({ + etag: anyEtag + }); }); it('Can read a setting', async function () { - const res = await request.get(localUtils.API.getApiQuery('settings/codeinjection_head/')) - .set('Origin', config.get('url')) - .expect('Content-Type', /json/) - .expect('Cache-Control', testUtils.cacheRules.private) - .expect(200); - - should.not.exist(res.headers['x-cache-invalidate']); - const jsonResponse = res.body; - - should.exist(jsonResponse); - should.exist(jsonResponse.settings); - - jsonResponse.settings.length.should.eql(1); - - testUtils.API.checkResponseValue(jsonResponse.settings[0], ['id', 'group', 'key', 'value', 'type', 'flags', 'created_at', 'updated_at']); - jsonResponse.settings[0].key.should.eql('codeinjection_head'); - testUtils.API.isISO8601(jsonResponse.settings[0].created_at).should.be.true(); + await agent.get('settings/codeinjection_head/') + .expectStatus(200) + .matchBodySnapshot({ + settings: [settingsMatcher] + }) + .matchHeaderSnapshot({ + etag: anyEtag + }); }); it('Can edit a setting', async function () { - const res = await request.get(localUtils.API.getApiQuery('settings/')) - .set('Origin', config.get('url')) - .expect('Content-Type', /json/) - .expect('Cache-Control', testUtils.cacheRules.private); + const settingsToChange = [ + { + key: 'title', + value: [] + }, + { + key: 'codeinjection_head', + value: null + }, + { + key: 'navigation', + value: JSON.stringify([{ + label: 'label1' + }]) + }, + { + key: 'slack', + value: JSON.stringify([{ + url: 'https://overrides.tld', + username: 'Overrides Username' + }]) + }, + { + key: 'slack_username', + value: 'New Slack Username' + }, + { + key: 'is_private', + value: false + }, + { + key: 'meta_title', + value: 'SEO title' + }, + { + key: 'meta_description', + value: 'SEO description' + }, + { + key: 'og_image', + value: '/content/images/2019/07/facebook.png' + }, + { + key: 'og_title', + value: 'facebook title' + }, + { + key: 'og_description', + value: 'facebook description' + }, + { + key: 'twitter_image', + value: '/content/images/2019/07/twitter.png' + }, + { + key: 'twitter_title', + value: 'twitter title' + }, + { + key: 'twitter_description', + value: 'twitter description' + }, + { + key: 'lang', + value: 'ua' + }, + { + key: 'labs', + value: JSON.stringify({}) + }, + { + key: 'timezone', + value: 'Pacific/Auckland' + }, + { + key: 'unsplash', + value: false + } + ]; - const jsonResponse = res.body; - const changedValue = []; - - const settingToChange = { - settings: [ - { - key: 'title', - value: changedValue - }, - { - key: 'codeinjection_head', - value: null - }, - { - key: 'navigation', - value: JSON.stringify([{ - label: 'label1' - }]) - }, - { - key: 'slack', - value: JSON.stringify([{ - url: 'https://overrides.tld', - username: 'Overrides Username' - }]) - }, - { - key: 'slack_username', - value: 'New Slack Username' - }, - { - key: 'is_private', - value: false - }, - { - key: 'meta_title', - value: 'SEO title' - }, - { - key: 'meta_description', - value: 'SEO description' - }, - { - key: 'og_image', - value: '/content/images/2019/07/facebook.png' - }, - { - key: 'og_title', - value: 'facebook title' - }, - { - key: 'og_description', - value: 'facebook description' - }, - { - key: 'twitter_image', - value: '/content/images/2019/07/twitter.png' - }, - { - key: 'twitter_title', - value: 'twitter title' - }, - { - key: 'twitter_description', - value: 'twitter description' - }, - { - key: 'lang', - value: 'ua' - }, - { - key: 'labs', - value: JSON.stringify({}) - }, - { - key: 'timezone', - value: 'Pacific/Auckland' - }, - { - key: 'unsplash', - value: false - } - ] - }; - - should.exist(jsonResponse); - should.exist(jsonResponse.settings); - - const {body, headers} = await request.put(localUtils.API.getApiQuery('settings/')) - .set('Origin', config.get('url')) - .send(settingToChange) - .expect('Content-Type', /json/) - .expect('Cache-Control', testUtils.cacheRules.private) - .expect(200); - - const putBody = body; - headers['x-cache-invalidate'].should.eql('/*'); - should.exist(putBody); - - putBody.settings.length.should.equal(settingToChange.settings.length); - - putBody.settings[0].key.should.eql('title'); - putBody.settings[0].value.should.eql(JSON.stringify(changedValue)); - - putBody.settings[1].key.should.eql('codeinjection_head'); - should.equal(putBody.settings[1].value, null); - - putBody.settings[2].key.should.eql('navigation'); - should.equal(putBody.settings[2].value, JSON.stringify([{label: 'label1'}])); - - putBody.settings[3].key.should.eql('slack_username'); - should.equal(putBody.settings[3].value, 'New Slack Username'); - - putBody.settings[4].key.should.eql('is_private'); - should.equal(putBody.settings[4].value, false); - - putBody.settings[5].key.should.eql('meta_title'); - should.equal(putBody.settings[5].value, 'SEO title'); - - putBody.settings[6].key.should.eql('meta_description'); - should.equal(putBody.settings[6].value, 'SEO description'); - - putBody.settings[6].key.should.eql('meta_description'); - should.equal(putBody.settings[6].value, 'SEO description'); - - putBody.settings[7].key.should.eql('og_image'); - should.equal(putBody.settings[7].value, `${config.get('url')}/content/images/2019/07/facebook.png`); - - putBody.settings[8].key.should.eql('og_title'); - should.equal(putBody.settings[8].value, 'facebook title'); - - putBody.settings[9].key.should.eql('og_description'); - should.equal(putBody.settings[9].value, 'facebook description'); - - putBody.settings[10].key.should.eql('twitter_image'); - should.equal(putBody.settings[10].value, `${config.get('url')}/content/images/2019/07/twitter.png`); - - putBody.settings[11].key.should.eql('twitter_title'); - should.equal(putBody.settings[11].value, 'twitter title'); - - putBody.settings[12].key.should.eql('twitter_description'); - should.equal(putBody.settings[12].value, 'twitter description'); - - putBody.settings[13].key.should.eql('lang'); - should.equal(putBody.settings[13].value, 'ua'); - - putBody.settings[14].key.should.eql('labs'); - should.equal(putBody.settings[14].value, JSON.stringify(labs.getAll())); - - putBody.settings[15].key.should.eql('timezone'); - should.equal(putBody.settings[15].value, 'Pacific/Auckland'); - - putBody.settings[16].key.should.eql('unsplash'); - should.equal(putBody.settings[16].value, false); - - putBody.settings[17].key.should.eql('slack'); - should.equal(putBody.settings[17].value, JSON.stringify([{ - url: 'https://overrides.tld', - username: 'New Slack Username' - }])); - - localUtils.API.checkResponse(putBody, 'settings'); - }); - - it('Can download routes.yaml', async function () { - const res = await request.get(localUtils.API.getApiQuery('settings/routes/yaml/')) - .set('Origin', config.get('url')) - .set('Accept', 'application/yaml') - .expect(200); - - res.headers['content-disposition'].should.eql('Attachment; filename="routes.yaml"'); - res.headers['content-type'].should.eql('application/yaml; charset=utf-8'); - res.headers['content-length'].should.eql('138'); - }); - - it('Can upload routes.yaml', async function () { - const newRoutesYamlPath = `${os.tmpdir()}/routes.yaml`; - - await fs.writeFile(newRoutesYamlPath, 'routes:\ncollections:\ntaxonomies:\n'); - const res = await request - .post(localUtils.API.getApiQuery('settings/routes/yaml/')) - .set('Origin', config.get('url')) - .attach('routes', newRoutesYamlPath) - .expect('Content-Type', /application\/json/) - .expect(200); - - res.headers['x-cache-invalidate'].should.eql('/*'); - await testUtils.stopGhost(); + await agent.put('settings/') + .body({ + settings: settingsToChange + }) + .expectStatus(200) + .matchBodySnapshot({ + settings: matchSettingsArray(settingsToChange.length) + }) + .matchHeaderSnapshot({ + etag: anyEtag + }); }); });