embark/packages/stack/pipeline/test/api.spec.js

255 lines
9.4 KiB
JavaScript

/* global describe, beforeEach, afterEach, test */
import assert from 'assert';
import sinon from 'sinon';
import { fakeEmbark } from 'embark-testing';
import API from '../src/api';
import path from 'path';
// Due to our `DAPP_PATH` dependency in `embark-utils` `dappPath()`, we need to
// ensure that this environment variable is defined.
const DAPP_PATH = 'something';
process.env.DAPP_PATH = DAPP_PATH;
describe('stack/pipeline/api', () => {
const { embark } = fakeEmbark();
let pipelineApi;
beforeEach(() => {
pipelineApi = new API(embark);
});
afterEach(() => {
embark.teardown();
sinon.restore();
});
describe('constructor', () => {
test('it should assign the correct properties', () => {
assert.strictEqual(pipelineApi.plugins, embark.plugins);
assert.strictEqual(pipelineApi.fs, embark.fs);
});
});
describe('methods', () => {
describe('apiGuardBadFile', () => {
let pathToCheck;
const pathToFile = "/path/to/file";
const error = { message: 'Path is invalid' };
beforeEach(() => {
pathToCheck = path.join(DAPP_PATH, pathToFile);
});
test('it should throw when file doesn\'t exist and is expected to exist', () => {
const options = { ensureExists: true };
const existsSync = sinon.fake.returns(false);
sinon.replace(pipelineApi.fs, 'existsSync', existsSync);
assert.throws(() => pipelineApi.apiGuardBadFile(pathToCheck, options), error);
});
test('it should not throw when file exists and is expected to exist', () => {
const options = { ensureExists: true };
const existsSync = sinon.fake.returns(true);
sinon.replace(pipelineApi.fs, 'existsSync', existsSync);
assert.doesNotThrow(() => pipelineApi.apiGuardBadFile(pathToCheck, options));
});
test('it should throw when file is not in the dappPath', () => {
assert.throws(() => pipelineApi.apiGuardBadFile(pathToFile), error);
});
test('it should not throw when file is in the dappPath', () => {
assert.doesNotThrow(() => pipelineApi.apiGuardBadFile(pathToCheck));
});
});
describe('registerAPIs', () => {
describe('GET /embark-api/file', () => {
let req, readFileSync;
const method = "GET";
const endpoint = "/embark-api/file";
const filepath = path.join(DAPP_PATH, "/path/to/file");
beforeEach(() => {
req = { path: filepath };
readFileSync = sinon.stub().returns("content");
pipelineApi.fs = { readFileSync };
pipelineApi.registerAPIs();
});
test(`it should register ${method} ${endpoint}`, () => {
pipelineApi.plugins.assert.apiCallRegistered(method, endpoint);
});
test('it should throw error when guarding bad files', async () => {
const error = "testing error";
pipelineApi.apiGuardBadFile = sinon.stub().throws(new Error(error));
const resp = await pipelineApi.plugins.mock.apiCall(method, endpoint, req);
assert(resp.send.calledWith({ error }));
});
test('it should return a file', async () => {
pipelineApi.apiGuardBadFile = sinon.stub().returns();
const resp = await pipelineApi.plugins.mock.apiCall(method, endpoint, req);
assert(readFileSync.calledWith(filepath, 'utf8'));
assert(resp.send.calledWith({ name: "file", content: "content", path: filepath }));
});
});
describe('POST /embark-api/folders', () => {
let req, mkdirpSync;
const method = "POST";
const endpoint = "/embark-api/folders";
const filepath = path.join(DAPP_PATH, "/path/to/folder");
beforeEach(() => {
req = { path: filepath };
mkdirpSync = sinon.stub();
pipelineApi.fs = { mkdirpSync };
pipelineApi.registerAPIs();
});
test(`it should register ${method} ${endpoint}`, () => {
pipelineApi.plugins.assert.apiCallRegistered(method, endpoint);
});
test('it should throw error when guarding bad files', async () => {
const error = "testing error";
pipelineApi.apiGuardBadFile = sinon.stub().throws(new Error(error));
const resp = await pipelineApi.plugins.mock.apiCall(method, endpoint, req);
assert(resp.send.calledWith({ error }));
});
test('it should create a folder', async () => {
pipelineApi.apiGuardBadFile = sinon.stub().returns();
const resp = await pipelineApi.plugins.mock.apiCall(method, endpoint, req);
assert(mkdirpSync.calledWith(filepath));
assert(resp.send.calledWith({ name: "folder", path: filepath }));
});
});
describe('POST /embark-api/files', () => {
let req, writeFileSync;
const method = "POST";
const endpoint = "/embark-api/files";
const filepath = path.join(DAPP_PATH, "/path/to/file");
beforeEach(() => {
req = { path: filepath, content: "content" };
writeFileSync = sinon.stub();
pipelineApi.fs = { writeFileSync };
pipelineApi.registerAPIs();
});
test(`it should register ${method} ${endpoint}`, () => {
pipelineApi.plugins.assert.apiCallRegistered(method, endpoint);
});
test('it should throw error when guarding bad files', async () => {
const error = "testing error";
pipelineApi.apiGuardBadFile = sinon.stub().throws(new Error(error));
const resp = await pipelineApi.plugins.mock.apiCall(method, endpoint, req);
assert(resp.send.calledWith({ error }));
});
test('it should write a file to the filesystem', async () => {
pipelineApi.apiGuardBadFile = sinon.stub().returns();
const resp = await pipelineApi.plugins.mock.apiCall(method, endpoint, req);
assert(writeFileSync.calledWith(req.path, req.content, { encoding: 'utf8' }));
assert(resp.send.calledWith({ name: "file", ...req }));
});
});
describe('DELETE /embark-api/file', () => {
let req, removeSync;
const method = "DELETE";
const endpoint = "/embark-api/file";
const filepath = path.join(DAPP_PATH, "/path/to/file");
beforeEach(() => {
req = { path: filepath, content: "content" };
removeSync = sinon.stub();
pipelineApi.fs = { removeSync };
pipelineApi.registerAPIs();
});
test(`it should register ${method} ${endpoint}`, () => {
pipelineApi.plugins.assert.apiCallRegistered(method, endpoint);
});
test('it should throw error when guarding bad files', async () => {
const error = "testing error";
pipelineApi.apiGuardBadFile = sinon.stub().throws(new Error(error));
const resp = await pipelineApi.plugins.mock.apiCall(method, endpoint, req);
assert(resp.send.calledWith({ error }));
});
test('it should delete a file from the filesystem', async () => {
pipelineApi.apiGuardBadFile = sinon.stub().returns();
const resp = await pipelineApi.plugins.mock.apiCall(method, endpoint, req);
assert(removeSync.calledWith(req.path));
assert(resp.send.called);
});
});
describe('GET /embark-api/files', () => {
let req, readdirSync, statSync;
const method = "GET";
const endpoint = "/embark-api/files";
const file = "file";
const fileHidden = ".file";
const folder = "folder";
const child = "child";
beforeEach(() => {
req = {};
readdirSync = sinon.stub();
readdirSync.withArgs(DAPP_PATH).returns([
file,
fileHidden,
folder
]);
readdirSync.withArgs(path.join(DAPP_PATH, folder)).returns([child]);
statSync = sinon.stub();
statSync.returns({ isDirectory: () => false });
statSync.withArgs(path.join(DAPP_PATH, folder)).returns({ isDirectory: () => true });
pipelineApi.fs = { readdirSync, statSync };
pipelineApi.registerAPIs();
});
test(`it should register ${method} ${endpoint}`, () => {
pipelineApi.plugins.assert.apiCallRegistered(method, endpoint);
});
test('it should return a tree of file objects for the dapp', async () => {
const resp = await pipelineApi.plugins.mock.apiCall(method, endpoint, req);
const expectedValue = [
{
isRoot: true,
name: 'folder',
dirname: 'something',
path: path.join(DAPP_PATH, folder),
isHidden: false,
children: [
{
name: 'child',
isRoot: false,
path: path.join(DAPP_PATH, folder, child),
dirname: path.join(DAPP_PATH, folder),
isHidden: false
}
]
},
{
name: '.file',
isRoot: true,
path: path.join(DAPP_PATH, fileHidden),
dirname: 'something',
isHidden: true
},
{
name: 'file',
isRoot: true,
path: path.join(DAPP_PATH, file),
dirname: 'something',
isHidden: false
}
];
assert(resp.send.calledWith(expectedValue));
});
});
});
});
});