chore: add proxy backend (#3126)
* feat(backends): add proxy backend * feat: add proxy server initial commit * fix: move from joi to @hapi/joi * test: add joi validation tests * feat: proxy server initial implementations * test: add tests, fix build * chore: update yarn.lock * build: fix develop command * fix(back-proxy): fix bugs * test(backend-proxy): add cypress tests * chore: cleanup * chore: support node 10 * chore: code cleanup * chore: run cypress on ubuntu 16.04 * test(e2e): fix proxy backend cypress tests * chore: don't start proxy server on yarn develop
This commit is contained in:
committed by
Shawn Erquhart
parent
cf57da223d
commit
7e8084be87
30
cypress/integration/editorial_workflow_spec_proxy_backend.js
Normal file
30
cypress/integration/editorial_workflow_spec_proxy_backend.js
Normal file
@ -0,0 +1,30 @@
|
||||
import fixture from './common/editorial_workflow';
|
||||
import * as specUtils from './common/spec_utils';
|
||||
import { entry1, entry2, entry3 } from './common/entries';
|
||||
|
||||
const backend = 'proxy';
|
||||
|
||||
describe('Proxy Backend Editorial Workflow', () => {
|
||||
let taskResult = { data: {} };
|
||||
|
||||
before(() => {
|
||||
specUtils.before(taskResult, { publish_mode: 'editorial_workflow' }, backend);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
specUtils.after(taskResult, backend);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
specUtils.beforeEach(taskResult, backend);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
specUtils.afterEach(taskResult, backend);
|
||||
});
|
||||
|
||||
fixture({
|
||||
entries: [entry1, entry2, entry3],
|
||||
getUser: () => taskResult.data.user,
|
||||
});
|
||||
});
|
27
cypress/integration/media_library_spec_proxy_backend.js
Normal file
27
cypress/integration/media_library_spec_proxy_backend.js
Normal file
@ -0,0 +1,27 @@
|
||||
import fixture from './common/media_library';
|
||||
import * as specUtils from './common/spec_utils';
|
||||
import { entry1 } from './common/entries';
|
||||
|
||||
const backend = 'proxy';
|
||||
|
||||
describe('Proxy Backend Media Library - REST API', () => {
|
||||
let taskResult = { data: {} };
|
||||
|
||||
before(() => {
|
||||
specUtils.before(taskResult, { publish_mode: 'editorial_workflow' }, backend);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
specUtils.after(taskResult, backend);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
specUtils.beforeEach(taskResult, backend);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
specUtils.afterEach(taskResult, backend);
|
||||
});
|
||||
|
||||
fixture({ entries: [entry1], getUser: () => taskResult.data.user });
|
||||
});
|
30
cypress/integration/simple_workflow_spec_proxy_backend.js
Normal file
30
cypress/integration/simple_workflow_spec_proxy_backend.js
Normal file
@ -0,0 +1,30 @@
|
||||
import fixture from './common/simple_workflow';
|
||||
import * as specUtils from './common/spec_utils';
|
||||
import { entry1, entry2, entry3 } from './common/entries';
|
||||
|
||||
const backend = 'proxy';
|
||||
|
||||
describe('Proxy Backend Simple Workflow', () => {
|
||||
let taskResult = { data: {} };
|
||||
|
||||
before(() => {
|
||||
specUtils.before(taskResult, { publish_mode: 'simple' }, backend);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
specUtils.after(taskResult, backend);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
specUtils.beforeEach(taskResult, backend);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
specUtils.afterEach(taskResult, backend);
|
||||
});
|
||||
|
||||
fixture({
|
||||
entries: [entry1, entry2, entry3],
|
||||
getUser: () => taskResult.data.user,
|
||||
});
|
||||
});
|
@ -27,6 +27,7 @@ const {
|
||||
setupBitBucketTest,
|
||||
teardownBitBucketTest,
|
||||
} = require('./bitbucket');
|
||||
const { setupProxy, teardownProxy, setupProxyTest, teardownProxyTest } = require('./proxy');
|
||||
|
||||
const { copyBackendFiles } = require('../utils/config');
|
||||
|
||||
@ -51,6 +52,9 @@ module.exports = async (on, config) => {
|
||||
case 'bitbucket':
|
||||
result = await setupBitBucket(options);
|
||||
break;
|
||||
case 'proxy':
|
||||
result = await setupProxy(options);
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -72,6 +76,9 @@ module.exports = async (on, config) => {
|
||||
case 'bitbucket':
|
||||
await teardownBitBucket(taskData);
|
||||
break;
|
||||
case 'proxy':
|
||||
await teardownProxy(taskData);
|
||||
break;
|
||||
}
|
||||
|
||||
console.log('Restoring defaults');
|
||||
@ -96,6 +103,9 @@ module.exports = async (on, config) => {
|
||||
case 'bitbucket':
|
||||
await setupBitBucketTest(taskData);
|
||||
break;
|
||||
case 'proxy':
|
||||
await setupProxyTest(taskData);
|
||||
break;
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -118,6 +128,9 @@ module.exports = async (on, config) => {
|
||||
case 'bitbucket':
|
||||
await teardownBitBucketTest(taskData);
|
||||
break;
|
||||
case 'proxy':
|
||||
await teardownProxyTest(taskData);
|
||||
break;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
96
cypress/plugins/proxy.js
Normal file
96
cypress/plugins/proxy.js
Normal file
@ -0,0 +1,96 @@
|
||||
const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
const { spawn } = require('child_process');
|
||||
const { updateConfig } = require('../utils/config');
|
||||
const { merge } = require('lodash');
|
||||
const { getGitClient } = require('./common');
|
||||
|
||||
const initRepo = async dir => {
|
||||
await fs.remove(dir);
|
||||
await fs.mkdirp(dir);
|
||||
const git = getGitClient(dir);
|
||||
await git.init();
|
||||
await git.addConfig('user.email', 'cms-cypress-test@netlify.com');
|
||||
await git.addConfig('user.name', 'cms-cypress-test');
|
||||
|
||||
const readme = 'README.md';
|
||||
await fs.writeFile(path.join(dir, readme), '');
|
||||
await git.add(readme);
|
||||
await git.commit('initial commit', readme, { '--no-verify': true, '--no-gpg-sign': true });
|
||||
};
|
||||
|
||||
const startServer = async repoDir => {
|
||||
const tsNode = path.join(__dirname, '..', '..', 'node_modules', '.bin', 'ts-node');
|
||||
const serverDir = path.join(__dirname, '..', '..', 'packages', 'netlify-cms-proxy-server');
|
||||
const distIndex = path.join(serverDir, 'dist', 'index.js');
|
||||
const tsIndex = path.join(serverDir, 'src', 'index.ts');
|
||||
|
||||
const env = { ...process.env, GIT_REPO_DIRECTORY: path.resolve(repoDir), PORT: 8082 };
|
||||
if (await fs.pathExists(distIndex)) {
|
||||
serverProcess = spawn('node', [distIndex], { env, cwd: serverDir });
|
||||
} else {
|
||||
serverProcess = spawn(tsNode, ['--files', tsIndex], { env, cwd: serverDir });
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
serverProcess.stdout.on('data', data => {
|
||||
const message = data.toString().trim();
|
||||
console.log(`server:stdout: ${message}`);
|
||||
if (message.startsWith('Netlify CMS Proxy Server listening on port')) {
|
||||
resolve(serverProcess);
|
||||
}
|
||||
});
|
||||
|
||||
serverProcess.stderr.on('data', data => {
|
||||
console.error(`server:stderr: ${data.toString().trim()}`);
|
||||
reject(data.toString());
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
let serverProcess;
|
||||
|
||||
async function setupProxy(options) {
|
||||
const postfix = Math.random()
|
||||
.toString(32)
|
||||
.substring(2);
|
||||
|
||||
const testRepoName = `proxy-test-repo-${Date.now()}-${postfix}`;
|
||||
const tempDir = path.join('.temp', testRepoName);
|
||||
|
||||
await updateConfig(config => {
|
||||
merge(config, options);
|
||||
});
|
||||
|
||||
return { tempDir };
|
||||
}
|
||||
|
||||
async function teardownProxy(taskData) {
|
||||
if (serverProcess) {
|
||||
serverProcess.kill();
|
||||
}
|
||||
await fs.remove(taskData.tempDir);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
async function setupProxyTest(taskData) {
|
||||
await initRepo(taskData.tempDir);
|
||||
serverProcess = await startServer(taskData.tempDir);
|
||||
return null;
|
||||
}
|
||||
|
||||
async function teardownProxyTest(taskData) {
|
||||
if (serverProcess) {
|
||||
serverProcess.kill();
|
||||
}
|
||||
await fs.remove(taskData.tempDir);
|
||||
return null;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
setupProxy,
|
||||
teardownProxy,
|
||||
setupProxyTest,
|
||||
teardownProxyTest,
|
||||
};
|
@ -133,19 +133,21 @@ function deleteEntryInEditor() {
|
||||
|
||||
function assertOnCollectionsPage() {
|
||||
cy.url().should('contain', '/#/collections/posts');
|
||||
cy.contains('h2', 'Collections');
|
||||
}
|
||||
|
||||
function assertEntryDeleted(entry) {
|
||||
if (Array.isArray(entry)) {
|
||||
const titles = entry.map(e => e.title);
|
||||
cy.get('a h2').each(el => {
|
||||
expect(titles).not.to.include(el.text());
|
||||
});
|
||||
} else {
|
||||
cy.get('a h2').each(el => {
|
||||
expect(entry.title).not.to.equal(el.text());
|
||||
});
|
||||
const hasEntries = Cypress.$('a h2').length > 0;
|
||||
if (hasEntries) {
|
||||
if (Array.isArray(entry)) {
|
||||
const titles = entry.map(e => e.title);
|
||||
cy.get('a h2').each(el => {
|
||||
expect(titles).not.to.include(el.text());
|
||||
});
|
||||
} else {
|
||||
cy.get('a h2').each(el => {
|
||||
expect(entry.title).not.to.equal(el.text());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user