Updated Config API testing to use snapshot + unit tests (#20854)

- Swap the e2e config API test to use our newer framework, and match against a
snapshot for the default case
- Move the individual test cases to unit tests (new file) - there are more to add
here, but this is parity with what we had before
- We use unit tests for checking through various cases for how config
changes modify the output as this is faster and more explicit
This commit is contained in:
Hannah Wolfe 2024-08-28 14:29:17 +01:00 committed by GitHub
parent ac345aa84d
commit 0a7093b7dd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 165 additions and 60 deletions

View File

@ -0,0 +1,68 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Config API Can retrieve config and all expected properties 1: [body] 1`] = `
Object {
"config": Object {
"clientExtensions": Object {},
"database": StringMatching /sqlite3\\|mysql\\|mysql2/,
"emailAnalytics": true,
"enableDeveloperExperiments": false,
"environment": StringMatching /\\^testing/,
"labs": Object {
"ActivityPub": true,
"NestPlayground": true,
"activitypub": true,
"additionalPaymentMethods": true,
"adminXDemo": true,
"announcementBar": true,
"audienceFeedback": true,
"collections": true,
"collectionsCard": true,
"contentVisibility": true,
"editorExcerpt": true,
"emailCustomization": true,
"i18n": true,
"importMemberTier": true,
"lexicalIndicators": true,
"lexicalMultiplayer": true,
"mailEvents": true,
"members": true,
"newEmailAddresses": true,
"outboundLinkTagging": true,
"postAnalyticsRefresh": true,
"publishFlowEndScreen": true,
"stripeAutomaticTax": true,
"themeErrorsNotification": true,
"tipsAndDonations": true,
"urlCache": true,
"webmentions": true,
},
"mail": "",
"mailgunIsConfigured": false,
"signupForm": Object {
"url": "https://cdn.jsdelivr.net/ghost/signup-form@~{version}/umd/signup-form.min.js",
"version": "0.1",
},
"stripeDirect": false,
"tenor": Object {
"contentFilter": "off",
"googleApiKey": null,
},
"useGravatar": false,
"version": StringMatching /\\\\d\\+\\\\\\.\\\\d\\+\\\\\\.\\\\d\\+/,
},
}
`;
exports[`Config API Can retrieve config and all expected properties 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": StringMatching /\\\\d\\+/,
"content-type": "application/json; charset=utf-8",
"content-version": StringMatching /v\\\\d\\+\\\\\\.\\\\d\\+/,
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
"vary": "Accept-Version, Origin, Accept-Encoding",
"x-powered-by": "Express",
}
`;

View File

@ -1,69 +1,35 @@
const should = require('should');
const supertest = require('supertest');
const testUtils = require('../../utils');
const localUtils = require('./utils');
const config = require('../../../core/shared/config');
const configUtils = require('../../utils/configUtils');
const {agentProvider, fixtureManager, matchers} = require('../../utils/e2e-framework');
const {anyContentVersion, anyEtag, anyContentLength, stringMatching} = matchers;
/**
* This is a snapshot test for the happy path of the config API
* It does not test the full range of possible config values
* as that should be tested in the unit tests for the public-config service
*/
describe('Config API', function () {
let request;
let agent;
before(async function () {
await localUtils.startGhost();
request = supertest.agent(config.get('url'));
await localUtils.doAuth(request);
agent = await agentProvider.getAdminAPIAgent();
await fixtureManager.init();
await agent.loginAsOwner();
});
afterEach(function () {
configUtils.set('tenor:googleApiKey', undefined);
});
it('can retrieve config and all expected properties', async function () {
// set any non-default keys so we can be sure they're exposed
configUtils.set('tenor:googleApiKey', 'TENOR_KEY');
const res = await request
.get(localUtils.API.getApiQuery('config/'))
.set('Origin', config.get('url'))
.expect('Content-Type', /json/)
.expect('Cache-Control', testUtils.cacheRules.private)
.expect(200);
localUtils.API.checkResponse(res.body.config, 'config');
// full version
res.body.config.version.should.match(/\d+\.\d+\.\d+/);
});
describe('mailgunIsConfigured', function () {
it('is a boolean when it is configured', async function () {
// set any non-default keys so we can be sure they're exposed
configUtils.set('bulkEmail', {
mailgun: 'exists'
it('Can retrieve config and all expected properties', async function () {
await agent
.get('/config/')
.expectStatus(200)
.matchBodySnapshot({
config: {
database: stringMatching(/sqlite3|mysql|mysql2/),
environment: stringMatching(/^testing/),
version: stringMatching(/\d+\.\d+\.\d+/)
}
})
.matchHeaderSnapshot({
'content-version': anyContentVersion,
'content-length': anyContentLength, // Length can differ slightly based on the database, environment and version values
etag: anyEtag
});
const res = await request
.get(localUtils.API.getApiQuery('config/'))
.set('Origin', config.get('url'))
.expect('Content-Type', /json/)
.expect('Cache-Control', testUtils.cacheRules.private)
.expect(200);
should.equal(typeof res.body.config.mailgunIsConfigured, 'boolean');
});
it('is a boolean when it is not configured', async function () {
// set any non-default keys so we can be sure they're exposed
configUtils.set('bulkEmail', {});
const res = await request
.get(localUtils.API.getApiQuery('config/'))
.set('Origin', config.get('url'))
.expect('Content-Type', /json/)
.expect('Cache-Control', testUtils.cacheRules.private)
.expect(200);
should.equal(typeof res.body.config.mailgunIsConfigured, 'boolean');
});
});
});

View File

@ -0,0 +1,71 @@
const assert = require('assert/strict');
const configUtils = require('../../../../utils/configUtils');
const getConfigProperties = require('../../../../../core/server/services/public-config/config');
// List of allowed keys to be returned by the public-config service
// This is kind of a duplicate of the keys in the config.js output serializer in the api-framework
// However the list of keys returned by the public-config service can differ based on flags and config set, so we want to keep this explicit
const allowedKeys = [
'version',
'environment',
'database',
'mail',
'useGravatar',
'labs',
'clientExtensions',
'enableDeveloperExperiments',
'stripeDirect',
'mailgunIsConfigured',
'emailAnalytics',
'hostSettings',
'tenor',
'pintura',
'signupForm'
];
describe('Public-config Service', function () {
describe('Config Properties', function () {
afterEach(async function () {
await configUtils.restore();
});
it('should return the correct default config properties', function () {
const configProperties = getConfigProperties();
assert.deepEqual(Object.keys(configProperties), allowedKeys);
});
it('should return null for tenor apikey when unset', function () {
let configProperties = getConfigProperties();
assert.equal(configProperties.tenor.googleApiKey, null);
});
it('should return tenor apikey when set', function () {
configUtils.set('tenor:googleApiKey', 'TENOR_KEY');
let configProperties = getConfigProperties();
assert.equal(configProperties.tenor.googleApiKey, 'TENOR_KEY');
});
it('should return true for mailgunIsConfigured when mailgun is configured', function () {
configUtils.set('bulkEmail', {
mailgun: 'exists'
});
let configProperties = getConfigProperties();
assert.equal(configProperties.mailgunIsConfigured, true);
});
it('should return false for mailgunIsConfigured when mailgun is not configured', function () {
configUtils.set('bulkEmail', {});
let configProperties = getConfigProperties();
assert.equal(configProperties.mailgunIsConfigured, false);
});
});
});