From 8f8ca481a61058eaa724ea9d65fd6b7939e919b9 Mon Sep 17 00:00:00 2001 From: Simon Backx Date: Mon, 30 Jan 2023 14:06:20 +0100 Subject: [PATCH] Fixed configUtils and adapter cache issues in E2E tests (#16167) no issue There are a couple of issues with resetting the Ghost instance between E2E test files: These issues came to the surface because of new tests written in https://github.com/TryGhost/Ghost/pull/16117 **1. configUtils.restore does not work correctly** `config.reset()` is a callback based method. On top of that, it doesn't really work reliably (https://github.com/indexzero/nconf/issues/93) What kinda happens, is that you first call `config.reset` but immediately after you correcty reset the config using the `config.set` calls afterwards. But since `config.reset` is async, that reset will happen after all those sets, and the end result is that it isn't reset correctly. This mainly caused issues in the new updated images tests, which were updating the config `imageOptimization.contentImageSizes`, which is a deeply nested config value. Maybe some references to objects are reused in nconf that cause this issue? Wrapping `config.reset()` in a promise does fix the issue. **2. Adapters cache not reset between tests** At the start of each test, we set `paths:contentPath` to a nice new temporary directory. But if a previous test already requests a localStorage adapter, that adapter would have been created and in the constructor `paths:contentPath` would have been passed. That same instance will be reused in the next test run. So it won't read the new config again. To fix this, we need to reset the adapter instances between E2E tests. How was this visible? Test uploads were stored in the actual git repository, and not in a temporary directory. When writing the new image upload tests, this also resulted in unreliable test runs because some image names were already taken (from previous test runs). **3. Old 2E2 test Ghost server not stopped** Sometimes we still need access to the frontend test server using `getAgentsWithFrontend`. But that does start a new Ghost server which is actually listening for HTTP traffic. This could result in a fatal error in tests because the port is already in use. The issue is that old E2E tests also start a HTTP server, but they don't stop the server. When you used the old `startGhost` util, it would check if a server was already running and stop it first. The new `getAgentsWithFrontend` now also has the same functionality to fix that issue. --- ghost/adapter-manager/lib/AdapterManager.js | 11 +++- .../server/services/adapter-manager/index.js | 7 +++ ghost/core/test/e2e-api/admin/members.test.js | 2 +- .../core/test/e2e-api/content/authors.test.js | 4 +- ghost/core/test/e2e-api/content/tags.test.js | 4 +- .../e2e-api/members-comments/comments.test.js | 4 +- .../test/e2e-api/members/feedback.test.js | 6 +-- .../e2e-frontend/advanced_url_config.test.js | 4 +- .../test/e2e-frontend/default_routes.test.js | 2 +- ghost/core/test/e2e-server/admin.test.js | 8 +-- .../services/member-attribution.test.js | 4 +- .../email-service/batch-sending.test.js | 4 +- .../core/test/integration/url_service.test.js | 4 +- .../regression/api/content/authors.test.js | 4 +- .../test/regression/api/content/pages.test.js | 4 +- .../test/regression/api/content/posts.test.js | 4 +- .../test/regression/api/content/tags.test.js | 4 +- .../api-vs-frontend.test.js | 52 +++++++++---------- .../parent-app-vhosts.test.js | 16 +++--- .../regression/models/model_posts.test.js | 4 +- .../regression/site/dynamic_routing.test.js | 24 ++++----- .../test/regression/site/frontend.test.js | 13 +++-- .../apps/private-blogging/controller.test.js | 4 +- .../test/unit/frontend/helpers/asset.test.js | 8 +-- .../frontend/helpers/comment_count.test.js | 4 +- .../unit/frontend/helpers/comments.test.js | 4 +- .../test/unit/frontend/helpers/get.test.js | 4 +- .../unit/frontend/helpers/ghost_head.test.js | 4 +- .../unit/frontend/helpers/img_url.test.js | 24 ++++----- .../test/unit/frontend/helpers/link.test.js | 4 +- .../unit/frontend/helpers/link_class.test.js | 4 +- .../unit/frontend/helpers/meta_title.test.js | 4 +- .../test/unit/frontend/helpers/url.test.js | 8 +-- .../test/unit/frontend/meta/asset-url.test.js | 8 +-- .../unit/frontend/meta/paginated-url.test.js | 4 +- .../services/routing/ParentRouter.test.js | 4 +- .../services/routing/RSSRouter.test.js | 4 +- .../routing/StaticRoutesRouter.test.js | 4 +- .../routing/controllers/entry.test.js | 8 +-- .../routing/controllers/previews.test.js | 4 +- .../unit/frontend/services/rss/cache.test.js | 4 +- .../services/rss/generate-feed.test.js | 4 +- .../unit/frontend/utils/frontend-apps.test.js | 4 +- .../web/middleware/serve-favicon.test.js | 4 +- .../server/adapters/scheduling/utils.test.js | 4 +- .../storage/LocalImagesStorage.test.js | 4 +- .../server/adapters/storage/index.test.js | 4 +- .../unit/server/data/importer/index.test.js | 4 +- .../test/unit/server/lib/mobiledoc.test.js | 4 +- .../unit/server/lib/request-external.test.js | 8 +-- .../test/unit/server/models/member.test.js | 4 +- .../unit/server/models/permission.test.js | 4 +- ghost/core/test/unit/server/notify.test.js | 4 +- .../test/unit/server/services/labs.test.js | 4 +- .../test/unit/server/services/limits.test.js | 4 +- .../server/services/mail/GhostMailer.test.js | 4 +- .../server/services/members/config.test.js | 4 +- .../settings-helpers/settings-helpers.test.js | 4 +- .../test/unit/server/services/slack.test.js | 4 +- .../server/services/stripe/config.test.js | 4 +- .../test/unit/server/services/xmlrpc.test.js | 4 +- .../unit/server/web/admin/controller.test.js | 4 +- .../server/web/api/middleware/cors.test.js | 4 +- .../api/middleware/normalize-image.test.js | 4 +- .../shared/middleware/url-redirects.test.js | 4 +- .../unit/shared/config/adapter_config.test.js | 8 +-- .../test/unit/shared/config/helpers.test.js | 4 +- .../test/unit/shared/config/loader.test.js | 8 +-- ghost/core/test/unit/shared/sentry.test.js | 4 +- ghost/core/test/utils/configUtils.js | 8 ++- .../test/utils/e2e-framework-mock-manager.js | 3 +- ghost/core/test/utils/e2e-framework.js | 10 ++++ ghost/core/test/utils/e2e-utils.js | 7 +++ ghost/core/test/utils/urlUtils.js | 3 +- 74 files changed, 245 insertions(+), 211 deletions(-) diff --git a/ghost/adapter-manager/lib/AdapterManager.js b/ghost/adapter-manager/lib/AdapterManager.js index 9c866687d0..2679384bb6 100644 --- a/ghost/adapter-manager/lib/AdapterManager.js +++ b/ghost/adapter-manager/lib/AdapterManager.js @@ -53,6 +53,15 @@ module.exports = class AdapterManager { this.baseClasses[type] = BaseClass; } + /** + * Force recreation of all instances instead of reusing cached instances. Use when editing config file during tests. + */ + clearInstanceCache() { + for (const key of Object.keys(this.instanceCache)) { + this.instanceCache[key] = {}; + } + } + /** * getAdapter * @@ -75,7 +84,7 @@ module.exports = class AdapterManager { } else { adapterType = adapterName; } - + const adapterCache = this.instanceCache[adapterType]; if (!adapterCache) { diff --git a/ghost/core/core/server/services/adapter-manager/index.js b/ghost/core/core/server/services/adapter-manager/index.js index 4cc634f7e9..f862c3a508 100644 --- a/ghost/core/core/server/services/adapter-manager/index.js +++ b/ghost/core/core/server/services/adapter-manager/index.js @@ -29,5 +29,12 @@ module.exports = { const {adapterClassName, adapterConfig} = resolveAdapterOptions(name, adapterServiceConfig); return adapterManager.getAdapter(name, adapterClassName, adapterConfig); + }, + + /** + * Force recreation of all instances instead of reusing cached instances. Use when editing config file during tests. + */ + clearCache() { + adapterManager.clearInstanceCache(); } }; diff --git a/ghost/core/test/e2e-api/admin/members.test.js b/ghost/core/test/e2e-api/admin/members.test.js index 910c20d171..552c3448d5 100644 --- a/ghost/core/test/e2e-api/admin/members.test.js +++ b/ghost/core/test/e2e-api/admin/members.test.js @@ -791,7 +791,7 @@ describe('Members API', function () { await agent.delete(`/members/${memberPassVerification.id}`); await agent.delete(`/members/${memberFailVerification.id}`); - configUtils.restore(); + await configUtils.restore(); }); it('Can add and send a signup confirmation email', async function () { diff --git a/ghost/core/test/e2e-api/content/authors.test.js b/ghost/core/test/e2e-api/content/authors.test.js index 0c57cae8aa..102b794dce 100644 --- a/ghost/core/test/e2e-api/content/authors.test.js +++ b/ghost/core/test/e2e-api/content/authors.test.js @@ -17,8 +17,8 @@ describe('Authors Content API', function () { await testUtils.initFixtures('owner:post', 'users', 'user:inactive', 'posts', 'api_keys'); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); }); const validKey = localUtils.getValidKey(); diff --git a/ghost/core/test/e2e-api/content/tags.test.js b/ghost/core/test/e2e-api/content/tags.test.js index 0a6b2d9a0e..7712e16cbd 100644 --- a/ghost/core/test/e2e-api/content/tags.test.js +++ b/ghost/core/test/e2e-api/content/tags.test.js @@ -18,8 +18,8 @@ describe('Tags Content API', function () { await testUtils.initFixtures('users', 'user:inactive', 'posts', 'tags:extra', 'api_keys'); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); }); const validKey = localUtils.getValidKey(); diff --git a/ghost/core/test/e2e-api/members-comments/comments.test.js b/ghost/core/test/e2e-api/members-comments/comments.test.js index 9918180d83..c80d4cb114 100644 --- a/ghost/core/test/e2e-api/members-comments/comments.test.js +++ b/ghost/core/test/e2e-api/members-comments/comments.test.js @@ -191,8 +191,8 @@ describe('Comments API', function () { mockManager.mockMail(); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); mockManager.restore(); }); diff --git a/ghost/core/test/e2e-api/members/feedback.test.js b/ghost/core/test/e2e-api/members/feedback.test.js index 1288c5db3b..fcda365dcf 100644 --- a/ghost/core/test/e2e-api/members/feedback.test.js +++ b/ghost/core/test/e2e-api/members/feedback.test.js @@ -20,10 +20,10 @@ describe('Members Feedback', function () { mockManager.mockMail(); }); - afterEach(function () { + afterEach(async function () { clock?.restore(); clock = undefined; - configUtils.restore(); + await configUtils.restore(); mockManager.restore(); }); @@ -273,7 +273,7 @@ describe('Members Feedback', function () { } ] }); - + const model3 = await models.MemberFeedback.findOne({id: feedbackId}, {require: true}); assert.equal(body3.feedback[0].id, feedbackId); assert.equal(body3.feedback[0].score, 1); diff --git a/ghost/core/test/e2e-frontend/advanced_url_config.test.js b/ghost/core/test/e2e-frontend/advanced_url_config.test.js index 4081ff8bda..3c913c253a 100644 --- a/ghost/core/test/e2e-frontend/advanced_url_config.test.js +++ b/ghost/core/test/e2e-frontend/advanced_url_config.test.js @@ -28,8 +28,8 @@ describe('Advanced URL Configurations', function () { request = supertest.agent(configUtils.config.get('server:host') + ':' + configUtils.config.get('server:port')); }); - after(function () { - configUtils.restore(); + after(async function () { + await configUtils.restore(); urlUtils.restore(); }); diff --git a/ghost/core/test/e2e-frontend/default_routes.test.js b/ghost/core/test/e2e-frontend/default_routes.test.js index 0475ba16a3..166a830d52 100644 --- a/ghost/core/test/e2e-frontend/default_routes.test.js +++ b/ghost/core/test/e2e-frontend/default_routes.test.js @@ -170,7 +170,7 @@ describe('Default Frontend routing', function () { }); after(async function () { - configUtils.restore(); + await configUtils.restore(); await testUtils.startGhost({forceStart: true}); request = supertest.agent(configUtils.config.get('url')); diff --git a/ghost/core/test/e2e-server/admin.test.js b/ghost/core/test/e2e-server/admin.test.js index 1d9f04159d..09c6fc4bb6 100644 --- a/ghost/core/test/e2e-server/admin.test.js +++ b/ghost/core/test/e2e-server/admin.test.js @@ -63,9 +63,9 @@ describe('Admin Routing', function () { request = supertest.agent(config.get('server:host') + ':' + config.get('server:port')); }); - after(function () { + after(async function () { urlUtils.restore(); - configUtils.restore(); + await configUtils.restore(); }); it('should redirect admin access over non-HTTPS', async function () { @@ -90,8 +90,8 @@ describe('Admin Routing', function () { configUtils.set('paths', configPaths); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); }); it('serves assets in production', async function () { diff --git a/ghost/core/test/e2e-server/services/member-attribution.test.js b/ghost/core/test/e2e-server/services/member-attribution.test.js index eaf47e3aac..f4e25e8fcb 100644 --- a/ghost/core/test/e2e-server/services/member-attribution.test.js +++ b/ghost/core/test/e2e-server/services/member-attribution.test.js @@ -191,8 +191,8 @@ describe('Member Attribution Service', function () { configUtils.set('url', 'https://siteurl.com/subdirectory/'); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); }); it('resolves urls', async function () { diff --git a/ghost/core/test/integration/services/email-service/batch-sending.test.js b/ghost/core/test/integration/services/email-service/batch-sending.test.js index 0c7103d158..2beca1af8f 100644 --- a/ghost/core/test/integration/services/email-service/batch-sending.test.js +++ b/ghost/core/test/integration/services/email-service/batch-sending.test.js @@ -184,7 +184,7 @@ describe('Batch sending tests', function () { }); afterEach(async function () { - configUtils.restore(); + await configUtils.restore(); await models.Settings.edit([{ key: 'email_verification_required', value: false @@ -653,7 +653,7 @@ describe('Batch sending tests', function () { sinon.assert.calledOnce(getSignupEvents); assert.equal(settingsCache.get('email_verification_required'), true); - configUtils.restore(); + await configUtils.restore(); }); describe('Analytics', function () { diff --git a/ghost/core/test/integration/url_service.test.js b/ghost/core/test/integration/url_service.test.js index fead092fec..e4207f39ab 100644 --- a/ghost/core/test/integration/url_service.test.js +++ b/ghost/core/test/integration/url_service.test.js @@ -240,9 +240,9 @@ describe('Integration: services/url/UrlService', function () { })(); }); - afterEach(function () { + afterEach(async function () { urlService.resetGenerators(); - configUtils.restore(); + await configUtils.restore(); }); it('getUrl', function () { diff --git a/ghost/core/test/regression/api/content/authors.test.js b/ghost/core/test/regression/api/content/authors.test.js index b75910ac4e..c72764e24e 100644 --- a/ghost/core/test/regression/api/content/authors.test.js +++ b/ghost/core/test/regression/api/content/authors.test.js @@ -15,8 +15,8 @@ describe('Authors Content API', function () { await testUtils.initFixtures('owner:post', 'users', 'user:inactive', 'posts', 'api_keys'); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); }); it('can read authors with fields', function () { diff --git a/ghost/core/test/regression/api/content/pages.test.js b/ghost/core/test/regression/api/content/pages.test.js index 8acb633bfe..423b0e6a69 100644 --- a/ghost/core/test/regression/api/content/pages.test.js +++ b/ghost/core/test/regression/api/content/pages.test.js @@ -16,8 +16,8 @@ describe('api/endpoints/content/pages', function () { await testUtils.initFixtures('users', 'user:inactive', 'posts', 'tags:extra', 'api_keys'); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); }); it('Returns a validation error when unsupported "page" filter is used', function () { diff --git a/ghost/core/test/regression/api/content/posts.test.js b/ghost/core/test/regression/api/content/posts.test.js index 4cba3af827..597848bb94 100644 --- a/ghost/core/test/regression/api/content/posts.test.js +++ b/ghost/core/test/regression/api/content/posts.test.js @@ -16,8 +16,8 @@ describe('api/endpoints/content/posts', function () { await testUtils.initFixtures('users', 'user:inactive', 'posts', 'tags:extra', 'api_keys'); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); urlUtils.restore(); }); diff --git a/ghost/core/test/regression/api/content/tags.test.js b/ghost/core/test/regression/api/content/tags.test.js index c2c3074911..883dc2a0c4 100644 --- a/ghost/core/test/regression/api/content/tags.test.js +++ b/ghost/core/test/regression/api/content/tags.test.js @@ -17,8 +17,8 @@ describe('api/endpoints/content/tags', function () { await testUtils.initFixtures('users', 'user:inactive', 'posts', 'tags:extra', 'api_keys'); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); }); it('Can read tags with fields', function () { diff --git a/ghost/core/test/regression/mock-express-style/api-vs-frontend.test.js b/ghost/core/test/regression/mock-express-style/api-vs-frontend.test.js index fb35438e8f..638e335107 100644 --- a/ghost/core/test/regression/mock-express-style/api-vs-frontend.test.js +++ b/ghost/core/test/regression/mock-express-style/api-vs-frontend.test.js @@ -43,8 +43,8 @@ describe('Frontend behavior tests', function () { sinon.restore(); }); - after(function () { - configUtils.restore(); + after(async function () { + await configUtils.restore(); urlUtils.restore(); sinon.restore(); }); @@ -292,9 +292,9 @@ describe('Frontend behavior tests', function () { urlUtils.stubUrlUtilsFromConfig(); }); - after(function () { + after(async function () { urlUtils.restore(); - configUtils.restore(); + await configUtils.restore(); }); describe('protocol', function () { @@ -398,8 +398,8 @@ describe('Frontend behavior tests', function () { localUtils.overrideGhostConfig(configUtils); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); urlUtils.restore(); }); @@ -505,8 +505,8 @@ describe('Frontend behavior tests', function () { localUtils.overrideGhostConfig(configUtils); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); urlUtils.restore(); }); @@ -558,8 +558,8 @@ describe('Frontend behavior tests', function () { localUtils.overrideGhostConfig(configUtils); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); urlUtils.restore(); }); @@ -650,8 +650,8 @@ describe('Frontend behavior tests', function () { localUtils.overrideGhostConfig(configUtils); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); urlUtils.restore(); }); @@ -726,8 +726,8 @@ describe('Frontend behavior tests', function () { localUtils.overrideGhostConfig(configUtils); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); urlUtils.restore(); }); @@ -873,8 +873,8 @@ describe('Frontend behavior tests', function () { localUtils.overrideGhostConfig(configUtils); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); urlUtils.restore(); }); @@ -978,8 +978,8 @@ describe('Frontend behavior tests', function () { localUtils.overrideGhostConfig(configUtils); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); urlUtils.restore(); sinon.restore(); }); @@ -1036,8 +1036,8 @@ describe('Frontend behavior tests', function () { localUtils.overrideGhostConfig(configUtils); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); urlUtils.restore(); }); @@ -1087,8 +1087,8 @@ describe('Frontend behavior tests', function () { localUtils.overrideGhostConfig(configUtils); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); urlUtils.restore(); sinon.restore(); }); @@ -1262,8 +1262,8 @@ describe('Frontend behavior tests', function () { localUtils.overrideGhostConfig(configUtils); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); urlUtils.restore(); }); @@ -1495,8 +1495,8 @@ describe('Frontend behavior tests', function () { localUtils.overrideGhostConfig(configUtils); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); urlUtils.restore(); }); diff --git a/ghost/core/test/regression/mock-express-style/parent-app-vhosts.test.js b/ghost/core/test/regression/mock-express-style/parent-app-vhosts.test.js index f3c1de893e..18966f018b 100644 --- a/ghost/core/test/regression/mock-express-style/parent-app-vhosts.test.js +++ b/ghost/core/test/regression/mock-express-style/parent-app-vhosts.test.js @@ -13,8 +13,8 @@ describe('Integration - Web - vhosts', function () { before(testUtils.teardownDb); - after(function () { - configUtils.restore(); + after(async function () { + await configUtils.restore(); urlUtils.restore(); sinon.restore(); }); @@ -36,8 +36,8 @@ describe('Integration - Web - vhosts', function () { urlUtils.stubUrlUtilsFromConfig(); }); - after(function () { - configUtils.restore(); + after(async function () { + await configUtils.restore(); urlUtils.restore(); sinon.restore(); }); @@ -144,8 +144,8 @@ describe('Integration - Web - vhosts', function () { urlUtils.stubUrlUtilsFromConfig(); }); - after(function () { - configUtils.restore(); + after(async function () { + await configUtils.restore(); urlUtils.restore(); sinon.restore(); }); @@ -297,8 +297,8 @@ describe('Integration - Web - vhosts', function () { urlUtils.stubUrlUtilsFromConfig(); }); - after(function () { - configUtils.restore(); + after(async function () { + await configUtils.restore(); urlUtils.restore(); sinon.restore(); }); diff --git a/ghost/core/test/regression/models/model_posts.test.js b/ghost/core/test/regression/models/model_posts.test.js index 460d13a63b..17f4946b65 100644 --- a/ghost/core/test/regression/models/model_posts.test.js +++ b/ghost/core/test/regression/models/model_posts.test.js @@ -41,8 +41,8 @@ describe('Post Model', function () { }); describe('Single author posts', function () { - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); }); describe('fetchOne/fetchAll/fetchPage', function () { diff --git a/ghost/core/test/regression/site/dynamic_routing.test.js b/ghost/core/test/regression/site/dynamic_routing.test.js index ec9239c084..69470391aa 100644 --- a/ghost/core/test/regression/site/dynamic_routing.test.js +++ b/ghost/core/test/regression/site/dynamic_routing.test.js @@ -229,14 +229,12 @@ describe('Dynamic Routing', function () { }); }); - after(function () { - configUtils.restore(); + after(async function () { + await configUtils.restore(); - return testUtils.startGhost({forceStart: true}) - .then(function () { - sinon.stub(themeEngine.getActive(), 'config').withArgs('posts_per_page').returns(5); - request = supertest.agent(config.get('url')); - }); + await testUtils.startGhost({forceStart: true}); + sinon.stub(themeEngine.getActive(), 'config').withArgs('posts_per_page').returns(5); + request = supertest.agent(config.get('url')); }); it('should redirect without slash', function (done) { @@ -431,14 +429,12 @@ describe('Dynamic Routing', function () { }); }); - after(function () { - configUtils.restore(); + after(async function () { + await configUtils.restore(); - return testUtils.startGhost({forceStart: true}) - .then(function () { - sinon.stub(themeEngine.getActive(), 'config').withArgs('posts_per_page').returns(5); - request = supertest.agent(config.get('url')); - }); + await testUtils.startGhost({forceStart: true}); + sinon.stub(themeEngine.getActive(), 'config').withArgs('posts_per_page').returns(5); + request = supertest.agent(config.get('url')); }); it('should redirect without slash', function (done) { diff --git a/ghost/core/test/regression/site/frontend.test.js b/ghost/core/test/regression/site/frontend.test.js index 175fcc1055..5723cbcc8a 100644 --- a/ghost/core/test/regression/site/frontend.test.js +++ b/ghost/core/test/regression/site/frontend.test.js @@ -211,13 +211,12 @@ describe('Frontend Routing', function () { }); after(function (done) { - configUtils.restore(); - - testUtils.startGhost({forceStart: true}) - .then(function () { - request = supertest.agent(config.get('url')); - addPosts(done); - }); + configUtils.restore().then(() => { + return testUtils.startGhost({forceStart: true}); + }).then(function () { + request = supertest.agent(config.get('url')); + addPosts(done); + }); }); it('should redirect without slash', function (done) { diff --git a/ghost/core/test/unit/frontend/apps/private-blogging/controller.test.js b/ghost/core/test/unit/frontend/apps/private-blogging/controller.test.js index 4fbe505577..e5d794f87e 100644 --- a/ghost/core/test/unit/frontend/apps/private-blogging/controller.test.js +++ b/ghost/core/test/unit/frontend/apps/private-blogging/controller.test.js @@ -48,9 +48,9 @@ describe('Private Controller', function () { }); }); - afterEach(function () { + afterEach(async function () { sinon.restore(); - configUtils.restore(); + await configUtils.restore(); }); it('Should render default password page when theme has no password template', function (done) { diff --git a/ghost/core/test/unit/frontend/helpers/asset.test.js b/ghost/core/test/unit/frontend/helpers/asset.test.js index f9d806535b..507b773e42 100644 --- a/ghost/core/test/unit/frontend/helpers/asset.test.js +++ b/ghost/core/test/unit/frontend/helpers/asset.test.js @@ -21,8 +21,8 @@ describe('{{asset}} helper', function () { }); }); - after(function () { - configUtils.restore(); + after(async function () { + await configUtils.restore(); sinon.restore(); }); @@ -92,8 +92,8 @@ describe('{{asset}} helper', function () { configUtils.set({'admin:url': 'http://localhost'}); }); - after(function () { - configUtils.restore(); + after(async function () { + await configUtils.restore(); }); it('handles favicon correctly', function () { diff --git a/ghost/core/test/unit/frontend/helpers/comment_count.test.js b/ghost/core/test/unit/frontend/helpers/comment_count.test.js index c6078be3e5..b32d65ea2a 100644 --- a/ghost/core/test/unit/frontend/helpers/comment_count.test.js +++ b/ghost/core/test/unit/frontend/helpers/comment_count.test.js @@ -27,10 +27,10 @@ describe('{{comment_count}} helper', function () { sinon.stub(settingsCache, 'get'); }); - afterEach(function () { + afterEach(async function () { mockManager.restore(); sinon.restore(); - configUtils.restore(); + await configUtils.restore(); }); it('returns a script with the post id when autowrap is disabled', async function () { diff --git a/ghost/core/test/unit/frontend/helpers/comments.test.js b/ghost/core/test/unit/frontend/helpers/comments.test.js index a2686dca80..4c2ad04973 100644 --- a/ghost/core/test/unit/frontend/helpers/comments.test.js +++ b/ghost/core/test/unit/frontend/helpers/comments.test.js @@ -24,10 +24,10 @@ describe('{{comments}} helper', function () { configUtils.set('comments:version', 'test.version'); }); - afterEach(function () { + afterEach(async function () { mockManager.restore(); sinon.restore(); - configUtils.restore(); + await configUtils.restore(); }); it('returns undefined if not used withing post context', function (done) { diff --git a/ghost/core/test/unit/frontend/helpers/get.test.js b/ghost/core/test/unit/frontend/helpers/get.test.js index 55b5c13d25..f7f53a852c 100644 --- a/ghost/core/test/unit/frontend/helpers/get.test.js +++ b/ghost/core/test/unit/frontend/helpers/get.test.js @@ -338,8 +338,8 @@ describe('{{#get}} helper', function () { }; }); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); }); it('should log a warning if it hits the notify threshold', async function () { diff --git a/ghost/core/test/unit/frontend/helpers/ghost_head.test.js b/ghost/core/test/unit/frontend/helpers/ghost_head.test.js index 952e4f8d19..56801dc240 100644 --- a/ghost/core/test/unit/frontend/helpers/ghost_head.test.js +++ b/ghost/core/test/unit/frontend/helpers/ghost_head.test.js @@ -362,9 +362,9 @@ describe('{{ghost_head}} helper', function () { makeFixtures(); }); - afterEach(function () { + afterEach(async function () { sinon.restore(); - configUtils.restore(); + await configUtils.restore(); }); describe('without Code Injection', function () { diff --git a/ghost/core/test/unit/frontend/helpers/img_url.test.js b/ghost/core/test/unit/frontend/helpers/img_url.test.js index 9cd385caa6..e3f0bf952d 100644 --- a/ghost/core/test/unit/frontend/helpers/img_url.test.js +++ b/ghost/core/test/unit/frontend/helpers/img_url.test.js @@ -23,8 +23,8 @@ describe('{{img_url}} helper', function () { configUtils.set({url: 'http://localhost:65535/'}); }); - after(function () { - configUtils.restore(); + after(async function () { + await configUtils.restore(); }); it('should output relative url of image', function () { @@ -85,8 +85,8 @@ describe('{{img_url}} helper', function () { configUtils.set({url: 'http://localhost:65535/blog'}); }); - after(function () { - configUtils.restore(); + after(async function () { + await configUtils.restore(); }); it('should output relative url of image', function () { @@ -113,8 +113,8 @@ describe('{{img_url}} helper', function () { configUtils.set({url: 'http://localhost:65535/'}); }); - after(function () { - configUtils.restore(); + after(async function () { + await configUtils.restore(); }); it('should output correct url for absolute paths which are internal', function () { @@ -204,7 +204,7 @@ describe('{{img_url}} helper', function () { const rendered = img_url('/content/images/author-image-relative-url.png', { hash: { size: 'medium' - }, + }, data: { config: { image_sizes: { @@ -222,7 +222,7 @@ describe('{{img_url}} helper', function () { const rendered = img_url('/content/images/author-image-relative-url.png', { hash: { format: 'webp' - }, + }, data: { config: { image_sizes: { @@ -241,7 +241,7 @@ describe('{{img_url}} helper', function () { hash: { size: 'w600', format: 'webp' - }, + }, data: { config: { image_sizes: { @@ -260,7 +260,7 @@ describe('{{img_url}} helper', function () { hash: { size: 'w600', format: 'invalid' - }, + }, data: { config: { image_sizes: { @@ -280,8 +280,8 @@ describe('{{img_url}} helper', function () { configUtils.set({url: 'http://localhost:65535/'}); }); - after(function () { - configUtils.restore(); + after(async function () { + await configUtils.restore(); }); it('works without size option', function () { diff --git a/ghost/core/test/unit/frontend/helpers/link.test.js b/ghost/core/test/unit/frontend/helpers/link.test.js index 2496083600..5c7ede460e 100644 --- a/ghost/core/test/unit/frontend/helpers/link.test.js +++ b/ghost/core/test/unit/frontend/helpers/link.test.js @@ -34,8 +34,8 @@ describe('{{link}} helper', function () { }; }); - after(function () { - configUtils.restore(); + after(async function () { + await configUtils.restore(); }); describe('basic behavior: simple links without context', function () { diff --git a/ghost/core/test/unit/frontend/helpers/link_class.test.js b/ghost/core/test/unit/frontend/helpers/link_class.test.js index 8d8c5c6d85..8aca103ed9 100644 --- a/ghost/core/test/unit/frontend/helpers/link_class.test.js +++ b/ghost/core/test/unit/frontend/helpers/link_class.test.js @@ -32,8 +32,8 @@ describe('{{link_class}} helper', function () { }; }); - after(function () { - configUtils.restore(); + after(async function () { + await configUtils.restore(); }); it('throws an error for missing for=""', function () { diff --git a/ghost/core/test/unit/frontend/helpers/meta_title.test.js b/ghost/core/test/unit/frontend/helpers/meta_title.test.js index f7fb2f55ca..31ad59323e 100644 --- a/ghost/core/test/unit/frontend/helpers/meta_title.test.js +++ b/ghost/core/test/unit/frontend/helpers/meta_title.test.js @@ -14,8 +14,8 @@ describe('{{meta_title}} helper', function () { }); }); - after(function () { - configUtils.restore(); + after(async function () { + await configUtils.restore(); sinon.restore(); }); diff --git a/ghost/core/test/unit/frontend/helpers/url.test.js b/ghost/core/test/unit/frontend/helpers/url.test.js index 8b6860e93b..2eda03cef0 100644 --- a/ghost/core/test/unit/frontend/helpers/url.test.js +++ b/ghost/core/test/unit/frontend/helpers/url.test.js @@ -30,8 +30,8 @@ describe('{{url}} helper', function () { configUtils.set({url: 'http://localhost:65535/'}); }); - after(function () { - configUtils.restore(); + after(async function () { + await configUtils.restore(); }); it('should return the slug with a prefix slash if the context is a post', function () { @@ -239,8 +239,8 @@ describe('{{url}} helper', function () { configUtils.set({url: 'http://localhost:65535/blog'}); }); - after(function () { - configUtils.restore(); + after(async function () { + await configUtils.restore(); }); it('external urls should be retained in a nav context with subdir', function () { diff --git a/ghost/core/test/unit/frontend/meta/asset-url.test.js b/ghost/core/test/unit/frontend/meta/asset-url.test.js index 074ebd7e48..a3e3fcde4b 100644 --- a/ghost/core/test/unit/frontend/meta/asset-url.test.js +++ b/ghost/core/test/unit/frontend/meta/asset-url.test.js @@ -8,8 +8,8 @@ const config = configUtils.config; const getAssetUrl = require('../../../../core/frontend/meta/asset-url'); describe('getAssetUrl', function () { - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); sinon.restore(); }); @@ -93,8 +93,8 @@ describe('getAssetUrl', function () { configUtils.set({url: 'http://localhost:65535/blog'}); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); }); it('should return asset url with just context', function () { diff --git a/ghost/core/test/unit/frontend/meta/paginated-url.test.js b/ghost/core/test/unit/frontend/meta/paginated-url.test.js index 19df5c8368..cd16894edf 100644 --- a/ghost/core/test/unit/frontend/meta/paginated-url.test.js +++ b/ghost/core/test/unit/frontend/meta/paginated-url.test.js @@ -128,8 +128,8 @@ describe('getPaginatedUrl', function () { configUtils.set({url: 'http://localhost:65535/blog'}); }); - after(function () { - configUtils.restore(); + after(async function () { + await configUtils.restore(); }); it('should calculate correct urls for index', function () { diff --git a/ghost/core/test/unit/frontend/services/routing/ParentRouter.test.js b/ghost/core/test/unit/frontend/services/routing/ParentRouter.test.js index 48f7c1c833..e7f812417f 100644 --- a/ghost/core/test/unit/frontend/services/routing/ParentRouter.test.js +++ b/ghost/core/test/unit/frontend/services/routing/ParentRouter.test.js @@ -25,9 +25,9 @@ describe('UNIT - services/routing/ParentRouter', function () { res.locals = {}; }); - afterEach(function () { + afterEach(async function () { sinon.restore(); - configUtils.restore(); + await configUtils.restore(); }); describe('fn: _getSiteRouter', function () { diff --git a/ghost/core/test/unit/frontend/services/routing/RSSRouter.test.js b/ghost/core/test/unit/frontend/services/routing/RSSRouter.test.js index e878bff106..4b8028c953 100644 --- a/ghost/core/test/unit/frontend/services/routing/RSSRouter.test.js +++ b/ghost/core/test/unit/frontend/services/routing/RSSRouter.test.js @@ -14,9 +14,9 @@ describe('UNIT - services/routing/RSSRouter', function () { sinon.stub(urlUtils, 'urlJoin'); }); - afterEach(function () { + afterEach(async function () { sinon.restore(); - configUtils.restore(); + await configUtils.restore(); }); it('default', function () { diff --git a/ghost/core/test/unit/frontend/services/routing/StaticRoutesRouter.test.js b/ghost/core/test/unit/frontend/services/routing/StaticRoutesRouter.test.js index 2dffe53d98..8c31249a7f 100644 --- a/ghost/core/test/unit/frontend/services/routing/StaticRoutesRouter.test.js +++ b/ghost/core/test/unit/frontend/services/routing/StaticRoutesRouter.test.js @@ -10,8 +10,8 @@ describe('UNIT - services/routing/StaticRoutesRouter', function () { let next; let routerCreatedSpy; - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); }); beforeEach(function () { diff --git a/ghost/core/test/unit/frontend/services/routing/controllers/entry.test.js b/ghost/core/test/unit/frontend/services/routing/controllers/entry.test.js index ecf59b2263..048ec8f9f0 100644 --- a/ghost/core/test/unit/frontend/services/routing/controllers/entry.test.js +++ b/ghost/core/test/unit/frontend/services/routing/controllers/entry.test.js @@ -139,13 +139,13 @@ describe('Unit - services/routing/controllers/entry', function () { entry: post }); - urlUtils.redirectToAdmin.callsFake(function (statusCode, _res, editorUrl) { - configUtils.restore(); + urlUtils.redirectToAdmin.callsFake(async function (statusCode, _res, editorUrl) { + await configUtils.restore(); done(new Error('redirectToAdmin was called')); }); - controllers.entry(req, res, (err) => { - configUtils.restore(); + controllers.entry(req, res, async (err) => { + await configUtils.restore(); urlUtils.redirectToAdmin.called.should.eql(false); should.not.exist(err); done(err); diff --git a/ghost/core/test/unit/frontend/services/routing/controllers/previews.test.js b/ghost/core/test/unit/frontend/services/routing/controllers/previews.test.js index 64fff0b894..d865c7dbef 100644 --- a/ghost/core/test/unit/frontend/services/routing/controllers/previews.test.js +++ b/ghost/core/test/unit/frontend/services/routing/controllers/previews.test.js @@ -22,9 +22,9 @@ describe('Unit - services/routing/controllers/previews', function () { }; } - afterEach(function () { + afterEach(async function () { sinon.restore(); - configUtils.restore(); + await configUtils.restore(); }); let previewStub; diff --git a/ghost/core/test/unit/frontend/services/rss/cache.test.js b/ghost/core/test/unit/frontend/services/rss/cache.test.js index 91fbb75d37..63b6871db5 100644 --- a/ghost/core/test/unit/frontend/services/rss/cache.test.js +++ b/ghost/core/test/unit/frontend/services/rss/cache.test.js @@ -8,8 +8,8 @@ describe('RSS: Cache', function () { let generateSpy; let generateFeedReset; - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); sinon.restore(); generateFeedReset(); }); diff --git a/ghost/core/test/unit/frontend/services/rss/generate-feed.test.js b/ghost/core/test/unit/frontend/services/rss/generate-feed.test.js index d3e7f3fb1c..52903d0f3e 100644 --- a/ghost/core/test/unit/frontend/services/rss/generate-feed.test.js +++ b/ghost/core/test/unit/frontend/services/rss/generate-feed.test.js @@ -37,9 +37,9 @@ describe('RSS: Generate Feed', function () { }); }); - afterEach(function () { + afterEach(async function () { sinon.restore(); - configUtils.restore(); + await configUtils.restore(); }); beforeEach(function () { diff --git a/ghost/core/test/unit/frontend/utils/frontend-apps.test.js b/ghost/core/test/unit/frontend/utils/frontend-apps.test.js index 4719b47417..d9ce5d44ed 100644 --- a/ghost/core/test/unit/frontend/utils/frontend-apps.test.js +++ b/ghost/core/test/unit/frontend/utils/frontend-apps.test.js @@ -10,8 +10,8 @@ describe('Frontend apps:', function () { configUtils.set({'portal:styles': 'https://cdn.example.com/~{version}/main.css'}); }); - after(function () { - configUtils.restore(); + after(async function () { + await configUtils.restore(); }); it('should return app urls and version from config', async function () { diff --git a/ghost/core/test/unit/frontend/web/middleware/serve-favicon.test.js b/ghost/core/test/unit/frontend/web/middleware/serve-favicon.test.js index 373afdd8f0..62ad852eb9 100644 --- a/ghost/core/test/unit/frontend/web/middleware/serve-favicon.test.js +++ b/ghost/core/test/unit/frontend/web/middleware/serve-favicon.test.js @@ -29,9 +29,9 @@ describe('Serve Favicon', function () { originalStoragePath = storage.getStorage().storagePath; }); - afterEach(function () { + afterEach(async function () { sinon.restore(); - configUtils.restore(); + await configUtils.restore(); localSettingsCache = {}; storage.getStorage().storagePath = originalStoragePath; }); diff --git a/ghost/core/test/unit/server/adapters/scheduling/utils.test.js b/ghost/core/test/unit/server/adapters/scheduling/utils.test.js index 87ac10d5a3..3e9f6bfa4a 100644 --- a/ghost/core/test/unit/server/adapters/scheduling/utils.test.js +++ b/ghost/core/test/unit/server/adapters/scheduling/utils.test.js @@ -14,13 +14,13 @@ describe('Scheduling: utils', function () { } }); - afterEach(function () { + afterEach(async function () { if (scope.adapter) { fs.unlinkSync(scope.adapter); scope.adapter = null; } - configUtils.restore(); + await configUtils.restore(); }); describe('success', function () { diff --git a/ghost/core/test/unit/server/adapters/storage/LocalImagesStorage.test.js b/ghost/core/test/unit/server/adapters/storage/LocalImagesStorage.test.js index bcce71ead0..4096e0f531 100644 --- a/ghost/core/test/unit/server/adapters/storage/LocalImagesStorage.test.js +++ b/ghost/core/test/unit/server/adapters/storage/LocalImagesStorage.test.js @@ -25,9 +25,9 @@ describe('Local Images Storage', function () { momentStub = sinon.stub(moment.fn, 'format'); }); - afterEach(function () { + afterEach(async function () { sinon.restore(); - configUtils.restore(); + await configUtils.restore(); }); beforeEach(function () { diff --git a/ghost/core/test/unit/server/adapters/storage/index.test.js b/ghost/core/test/unit/server/adapters/storage/index.test.js index d861ba09b8..7b90171e3d 100644 --- a/ghost/core/test/unit/server/adapters/storage/index.test.js +++ b/ghost/core/test/unit/server/adapters/storage/index.test.js @@ -15,13 +15,13 @@ describe('storage: index_spec', function () { } }); - afterEach(function () { + afterEach(async function () { if (scope.adapter) { fs.unlinkSync(scope.adapter); scope.adapter = null; } - configUtils.restore(); + await configUtils.restore(); }); it('default image storage is local file storage', function () { diff --git a/ghost/core/test/unit/server/data/importer/index.test.js b/ghost/core/test/unit/server/data/importer/index.test.js index 8a3d6e3137..f29f4aa6cb 100644 --- a/ghost/core/test/unit/server/data/importer/index.test.js +++ b/ghost/core/test/unit/server/data/importer/index.test.js @@ -22,10 +22,10 @@ const storage = require('../../../../../core/server/adapters/storage'); const configUtils = require('../../../../utils/configUtils'); describe('Importer', function () { - afterEach(function () { + afterEach(async function () { sinon.restore(); ImageHandler = rewire('../../../../../core/server/data/importer/handlers/image'); - configUtils.restore(); + await configUtils.restore(); }); describe('ImportManager', function () { diff --git a/ghost/core/test/unit/server/lib/mobiledoc.test.js b/ghost/core/test/unit/server/lib/mobiledoc.test.js index 4d789ead0b..847f58d54d 100644 --- a/ghost/core/test/unit/server/lib/mobiledoc.test.js +++ b/ghost/core/test/unit/server/lib/mobiledoc.test.js @@ -9,10 +9,10 @@ const urlUtils = require('../../../../core/shared/url-utils'); const mockUtils = require('../../../utils/mocks'); describe('lib/mobiledoc', function () { - afterEach(function () { + afterEach(async function () { sinon.restore(); nock.cleanAll(); - configUtils.restore(); + await configUtils.restore(); // ensure config changes are reset and picked up by next test mobiledocLib.reload(); mockUtils.modules.unmockNonExistentModule(/sharp/); diff --git a/ghost/core/test/unit/server/lib/request-external.test.js b/ghost/core/test/unit/server/lib/request-external.test.js index 365966fab4..8ad9818108 100644 --- a/ghost/core/test/unit/server/lib/request-external.test.js +++ b/ghost/core/test/unit/server/lib/request-external.test.js @@ -15,8 +15,8 @@ describe('External Request', function () { }); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); sinon.restore(); nock.cleanAll(); }); @@ -179,8 +179,8 @@ describe('External Request', function () { }); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); sinon.restore(); nock.cleanAll(); }); diff --git a/ghost/core/test/unit/server/models/member.test.js b/ghost/core/test/unit/server/models/member.test.js index dabbc52418..72b6739e85 100644 --- a/ghost/core/test/unit/server/models/member.test.js +++ b/ghost/core/test/unit/server/models/member.test.js @@ -15,8 +15,8 @@ describe('Unit: models/member', function () { config.set('assetHash', '1'); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); sinon.restore(); }); diff --git a/ghost/core/test/unit/server/models/permission.test.js b/ghost/core/test/unit/server/models/permission.test.js index 7729f100d3..9596337cff 100644 --- a/ghost/core/test/unit/server/models/permission.test.js +++ b/ghost/core/test/unit/server/models/permission.test.js @@ -9,9 +9,9 @@ describe('Unit: models/permission', function () { models.init(); }); - after(function () { + after(async function () { sinon.restore(); - configUtils.restore(); + await configUtils.restore(); }); describe('add', function () { diff --git a/ghost/core/test/unit/server/notify.test.js b/ghost/core/test/unit/server/notify.test.js index 80501b8cbb..64dfdf0a92 100644 --- a/ghost/core/test/unit/server/notify.test.js +++ b/ghost/core/test/unit/server/notify.test.js @@ -27,9 +27,9 @@ describe('Notify', function () { eventSpy = sinon.spy(events, 'emit'); }); - afterEach(function () { + afterEach(async function () { process.send = undefined; - configUtils.restore(); + await configUtils.restore(); socketStub.restore(); eventSpy.restore(); }); diff --git a/ghost/core/test/unit/server/services/labs.test.js b/ghost/core/test/unit/server/services/labs.test.js index 9d910fbedd..59e6a1d6d1 100644 --- a/ghost/core/test/unit/server/services/labs.test.js +++ b/ghost/core/test/unit/server/services/labs.test.js @@ -16,9 +16,9 @@ function expectedLabsObject(obj) { } describe('Labs Service', function () { - afterEach(function () { + afterEach(async function () { sinon.restore(); - configUtils.restore(); + await configUtils.restore(); }); it('can getAll, even if empty with enabled members', function () { diff --git a/ghost/core/test/unit/server/services/limits.test.js b/ghost/core/test/unit/server/services/limits.test.js index 9685c695c7..22a0801991 100644 --- a/ghost/core/test/unit/server/services/limits.test.js +++ b/ghost/core/test/unit/server/services/limits.test.js @@ -23,8 +23,8 @@ describe('Limit Service Init', function () { }); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); sinon.restore(); }); diff --git a/ghost/core/test/unit/server/services/mail/GhostMailer.test.js b/ghost/core/test/unit/server/services/mail/GhostMailer.test.js index 15691f576e..a56051945b 100644 --- a/ghost/core/test/unit/server/services/mail/GhostMailer.test.js +++ b/ghost/core/test/unit/server/services/mail/GhostMailer.test.js @@ -39,9 +39,9 @@ const mailDataIncomplete = { const sandbox = sinon.createSandbox(); describe('Mail: Ghostmailer', function () { - afterEach(function () { + afterEach(async function () { mailer = null; - configUtils.restore(); + await configUtils.restore(); sandbox.restore(); }); diff --git a/ghost/core/test/unit/server/services/members/config.test.js b/ghost/core/test/unit/server/services/members/config.test.js index db5862bb50..54c1f46766 100644 --- a/ghost/core/test/unit/server/services/members/config.test.js +++ b/ghost/core/test/unit/server/services/members/config.test.js @@ -59,8 +59,8 @@ describe('Members - config', function () { }); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); urlUtils.restore(); sinon.restore(); }); diff --git a/ghost/core/test/unit/server/services/settings-helpers/settings-helpers.test.js b/ghost/core/test/unit/server/services/settings-helpers/settings-helpers.test.js index d486ae8629..5d5fa1f580 100644 --- a/ghost/core/test/unit/server/services/settings-helpers/settings-helpers.test.js +++ b/ghost/core/test/unit/server/services/settings-helpers/settings-helpers.test.js @@ -40,8 +40,8 @@ describe('Settings Helpers - getActiveStripeKeys', function () { }); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); }); it('Uses direct keys when stripeDirect is true, regardles of which keys exist', function () { diff --git a/ghost/core/test/unit/server/services/slack.test.js b/ghost/core/test/unit/server/services/slack.test.js index 6c28ed73d6..8715713ada 100644 --- a/ghost/core/test/unit/server/services/slack.test.js +++ b/ghost/core/test/unit/server/services/slack.test.js @@ -23,9 +23,9 @@ describe('Slack', function () { eventStub = sinon.stub(events, 'on'); }); - afterEach(function () { + afterEach(async function () { sinon.restore(); - configUtils.restore(); + await configUtils.restore(); }); it('listen() should initialise event correctly', function () { diff --git a/ghost/core/test/unit/server/services/stripe/config.test.js b/ghost/core/test/unit/server/services/stripe/config.test.js index 768d5f949c..fbbc23211b 100644 --- a/ghost/core/test/unit/server/services/stripe/config.test.js +++ b/ghost/core/test/unit/server/services/stripe/config.test.js @@ -34,8 +34,8 @@ describe('Stripe - config', function () { }); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); }); it('Returns null if Stripe not connected', function () { diff --git a/ghost/core/test/unit/server/services/xmlrpc.test.js b/ghost/core/test/unit/server/services/xmlrpc.test.js index 92c6f8c47b..d6439b2d93 100644 --- a/ghost/core/test/unit/server/services/xmlrpc.test.js +++ b/ghost/core/test/unit/server/services/xmlrpc.test.js @@ -16,9 +16,9 @@ describe('XMLRPC', function () { configUtils.set('privacy:useRpcPing', true); }); - afterEach(function () { + afterEach(async function () { sinon.restore(); - configUtils.restore(); + await configUtils.restore(); nock.cleanAll(); }); diff --git a/ghost/core/test/unit/server/web/admin/controller.test.js b/ghost/core/test/unit/server/web/admin/controller.test.js index 08295d6613..c669bc9ce1 100644 --- a/ghost/core/test/unit/server/web/admin/controller.test.js +++ b/ghost/core/test/unit/server/web/admin/controller.test.js @@ -9,12 +9,12 @@ describe('Admin App', function () { const req = {}; let res; - beforeEach(function () { + beforeEach(async function () { res = { sendFile: sinon.spy() }; - configUtils.restore(); + await configUtils.restore(); configUtils.set('paths:adminAssets', path.resolve('test/utils/fixtures/admin-build')); }); diff --git a/ghost/core/test/unit/server/web/api/middleware/cors.test.js b/ghost/core/test/unit/server/web/api/middleware/cors.test.js index fd11f1cbb4..49e1128286 100644 --- a/ghost/core/test/unit/server/web/api/middleware/cors.test.js +++ b/ghost/core/test/unit/server/web/api/middleware/cors.test.js @@ -34,9 +34,9 @@ describe('cors', function () { next = sinon.spy(); }); - afterEach(function () { + afterEach(async function () { sinon.restore(); - configUtils.restore(); + await configUtils.restore(); cors = rewire('../../../../../../core/server/web/api/middleware/cors')[1]; }); diff --git a/ghost/core/test/unit/server/web/api/middleware/normalize-image.test.js b/ghost/core/test/unit/server/web/api/middleware/normalize-image.test.js index d849dcc050..795fb9d624 100644 --- a/ghost/core/test/unit/server/web/api/middleware/normalize-image.test.js +++ b/ghost/core/test/unit/server/web/api/middleware/normalize-image.test.js @@ -22,9 +22,9 @@ describe('normalize', function () { sinon.stub(logging, 'error'); }); - afterEach(function () { + afterEach(async function () { sinon.restore(); - configUtils.restore(); + await configUtils.restore(); }); it('should do manipulation by default', function (done) { diff --git a/ghost/core/test/unit/server/web/shared/middleware/url-redirects.test.js b/ghost/core/test/unit/server/web/shared/middleware/url-redirects.test.js index 46fc5aaaef..ed98fc3994 100644 --- a/ghost/core/test/unit/server/web/shared/middleware/url-redirects.test.js +++ b/ghost/core/test/unit/server/web/shared/middleware/url-redirects.test.js @@ -29,9 +29,9 @@ describe('UNIT: url redirects', function () { next = sinon.spy(); }); - afterEach(function () { + afterEach(async function () { sinon.restore(); - configUtils.restore(); + await configUtils.restore(); host = null; }); diff --git a/ghost/core/test/unit/shared/config/adapter_config.test.js b/ghost/core/test/unit/shared/config/adapter_config.test.js index 952b506e2d..d480675f4e 100644 --- a/ghost/core/test/unit/shared/config/adapter_config.test.js +++ b/ghost/core/test/unit/shared/config/adapter_config.test.js @@ -8,12 +8,12 @@ const configUtils = require('../../../utils/configUtils'); */ describe('Adapter Config', function () { - before(function () { - configUtils.restore(); + before(async function () { + await configUtils.restore(); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); }); describe('Storage', function () { diff --git a/ghost/core/test/unit/shared/config/helpers.test.js b/ghost/core/test/unit/shared/config/helpers.test.js index a762a74b61..1c211de0b0 100644 --- a/ghost/core/test/unit/shared/config/helpers.test.js +++ b/ghost/core/test/unit/shared/config/helpers.test.js @@ -6,8 +6,8 @@ describe('vhost utils', function () { configUtils.set('url', 'http://ghost.blog'); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); }); // url = 'https://ghost.blog' diff --git a/ghost/core/test/unit/shared/config/loader.test.js b/ghost/core/test/unit/shared/config/loader.test.js index b9139b2446..b98b45e45c 100644 --- a/ghost/core/test/unit/shared/config/loader.test.js +++ b/ghost/core/test/unit/shared/config/loader.test.js @@ -5,12 +5,12 @@ const _ = require('lodash'); const configUtils = require('../../../utils/configUtils'); describe('Config Loader', function () { - before(function () { - configUtils.restore(); + before(async function () { + await configUtils.restore(); }); - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); }); describe('hierarchy of config channels', function () { diff --git a/ghost/core/test/unit/shared/sentry.test.js b/ghost/core/test/unit/shared/sentry.test.js index 0a0279ac1f..1fa9d2fefe 100644 --- a/ghost/core/test/unit/shared/sentry.test.js +++ b/ghost/core/test/unit/shared/sentry.test.js @@ -9,8 +9,8 @@ const fakeDSN = 'https://aaabbbccc000111222333444555667@sentry.io/1234567'; let sentry; describe('UNIT: sentry', function () { - afterEach(function () { - configUtils.restore(); + afterEach(async function () { + await configUtils.restore(); sinon.restore(); }); diff --git a/ghost/core/test/utils/configUtils.js b/ghost/core/test/utils/configUtils.js index a39ab69885..7cef41987c 100644 --- a/ghost/core/test/utils/configUtils.js +++ b/ghost/core/test/utils/configUtils.js @@ -26,12 +26,16 @@ configUtils.set = function () { * important: do not delete cloneDeep for value * nconf keeps this as a reference and then it can happen that the defaultConfig get's overridden by new values */ -configUtils.restore = function () { +configUtils.restore = async function () { /** * we have to reset the whole config object * config keys, which get set via a test and do not exist in the config files, won't get reseted */ - config.reset(); + await new Promise((resolve) => { + config.reset(() => { + resolve(); + }); + }); _.each(configUtils.defaultConfig, function (value, key) { config.set(key, _.cloneDeep(value)); diff --git a/ghost/core/test/utils/e2e-framework-mock-manager.js b/ghost/core/test/utils/e2e-framework-mock-manager.js index a1b4383a10..2f0b5a00fa 100644 --- a/ghost/core/test/utils/e2e-framework-mock-manager.js +++ b/ghost/core/test/utils/e2e-framework-mock-manager.js @@ -185,7 +185,8 @@ const mockLabsDisabled = (flag, alpha = true) => { }; const restore = () => { - configUtils.restore(); + // eslint-disable-next-line no-console + configUtils.restore().catch(console.error); sinon.restore(); mocks = {}; fakedLabsFlags = {}; diff --git a/ghost/core/test/utils/e2e-framework.js b/ghost/core/test/utils/e2e-framework.js index 307874deb9..9503992e48 100644 --- a/ghost/core/test/utils/e2e-framework.js +++ b/ghost/core/test/utils/e2e-framework.js @@ -34,6 +34,8 @@ const db = require('./db-utils'); // Services that need resetting const settingsService = require('../../core/server/services/settings/settings-service'); const supertest = require('supertest'); +const {stopGhost} = require('./e2e-utils'); +const adapterManager = require('../../core/server/services/adapter-manager'); /** * @param {Object} [options={}] @@ -53,6 +55,9 @@ const startGhost = async (options = {}) => { // NOTE: need to pass this config to the server instance configUtils.set('paths:contentPath', contentFolder); + // Adapter cache has to be cleared to avoid reusing cached adapter instances between restarts + adapterManager.clearCache(); + const defaults = { backend: true, frontend: false, @@ -335,6 +340,11 @@ const getAgentsWithFrontend = async () => { server: true }; try { + // Possible that we still have a running Ghost server from a previous old E2E test + // Those tests never stopped the server in the tests manually + await stopGhost(); + + // Start a new Ghost server with real HTTP listener ghostServer = await startGhost(bootOptions); const app = ghostServer.rootApp; diff --git a/ghost/core/test/utils/e2e-utils.js b/ghost/core/test/utils/e2e-utils.js index 8e09c72f50..9aaab997cd 100644 --- a/ghost/core/test/utils/e2e-utils.js +++ b/ghost/core/test/utils/e2e-utils.js @@ -20,6 +20,7 @@ const routeSettingsService = require('../../core/server/services/route-settings' const themeService = require('../../core/server/services/themes'); const limits = require('../../core/server/services/limits'); const customRedirectsService = require('../../core/server/services/custom-redirects'); +const adapterManager = require('../../core/server/services/adapter-manager'); // Other Test Utilities const configUtils = require('./configUtils'); @@ -112,6 +113,9 @@ const restartModeGhostStart = async ({frontend, copyThemes, copySettings}) => { debug('init done'); + // Adapter cache has to be cleared to avoid reusing cached adapter instances between restarts + adapterManager.clearCache(); + // Reset the settings cache await settingsService.init(); debug('settings done'); @@ -160,6 +164,9 @@ const freshModeGhostStart = async (options) => { // Stop the server (forceStart Mode) await stopGhost(); + // Adapter cache has to be cleared to avoid reusing cached adapter instances between restarts + adapterManager.clearCache(); + // Reset the settings cache and disable listeners so they don't get triggered further settingsService.reset(); diff --git a/ghost/core/test/utils/urlUtils.js b/ghost/core/test/utils/urlUtils.js index 2ad8bfb358..cf6a196c3a 100644 --- a/ghost/core/test/utils/urlUtils.js +++ b/ghost/core/test/utils/urlUtils.js @@ -53,7 +53,8 @@ const stubUrlUtilsFromConfig = () => { const restore = () => { defaultSandbox.restore(); - configUtils.restore(); + // eslint-disable-next-line no-console + configUtils.restore().catch(console.error); }; module.exports.stubUrlUtilsFromConfig = stubUrlUtilsFromConfig;