Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BO-901 - Create version and refactor command arguments validation #11

Merged
merged 12 commits into from
Mar 1, 2017
2 changes: 2 additions & 0 deletions bin/barracks-create-package-version.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const CreatePackageVersionCommand = require('../commands/CreatePackageVersionCommand');
new CreatePackageVersionCommand().render();
1 change: 1 addition & 0 deletions bin/barracks.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const barracks = program
if (config.experimental) {
barracks
.command('create-package', 'Create a new package')
.command('create-package-version', 'Create a package version')
.command('create-filter', 'Create a filter')
.command('filters', 'List filters')
.command('create-token', 'Create an API token')
Expand Down
37 changes: 37 additions & 0 deletions clients/Barracks.js
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,43 @@ class Barracks {
});
}

createVersion(token, version) {
return new Promise((resolve, reject) => {
this.client.sendEndpointRequest('createVersion', {
headers: {
'x-auth-token': token
},
formData: {
version: {
value: JSON.stringify({
id: version.id,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

id mongo VS version id?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not the mongo id, all good

name: version.name,
description: version.description,
metadata: version.metadata
}),
options: {
contentType: 'application/json'
}
},
file: {
value: fs.createReadStream(version.file),
options: {
filename: path.basename(version.file),
contentType: 'application/octet-stream'
}
}
},
pathVariables: {
componentRef: version.component
}
}).then(response => {
resolve(response.body);
}).catch(errResponse => {
reject(errResponse.message);
});
});
}

checkUpdate(apiKey, device) {
return new Promise((resolve, reject) => {
logger.debug('checking update:', device);
Expand Down
110 changes: 110 additions & 0 deletions clients/Barracks.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1346,6 +1346,116 @@ describe('Barracks', () => {
});
});

describe('#createVersion()', () => {


const filename = 'file.txt';
const filePath = 'path/to/file.txt';
const version = {
id: '2.0',
name: 'version 2',
component: 'ref.package',
file: filePath,
description: 'description',
metadata: JSON.stringify({ data: 'value' })
};

let spyCreateReadStream;
const proxyCreateReadStream = (path) => {
spyCreateReadStream(path);
return filename;
};

let spyBasename;
const proxyBasename = (path) => {
spyBasename(path);
return filename;
};

const ProxifiedBarracks = proxyquire('./Barracks', {
fs: { createReadStream: (path) => {
return proxyCreateReadStream(path);
}},
path: { basename: (path) => {
return proxyBasename(path);
}}
});

const options = {
headers: {
'x-auth-token': token
},
formData: {
version: {
value: JSON.stringify({
id: version.id,
name: version.name,
description: version.description,
metadata: version.metadata
}),
options: {
contentType: 'application/json'
}
},
file: {
value: filename,
options: {
filename: filename,
contentType: 'application/octet-stream'
}
}
},
pathVariables: {
componentRef: version.component
}
};

it('should return an error message when request fails', done => {
// Given
const proxyBarracks = new ProxifiedBarracks();
const error = { message: 'request failed' };
spyCreateReadStream = sinon.spy();
spyBasename = sinon.spy();
proxyBarracks.client.sendEndpointRequest = sinon.stub().returns(Promise.reject(error));

// When / Then
proxyBarracks.createVersion(token, version).then(result => {
done('should have failed');
}).catch(err => {
expect(err).to.be.equals(error.message);
expect(proxyBarracks.client.sendEndpointRequest).to.have.been.calledOnce;
expect(proxyBarracks.client.sendEndpointRequest).to.have.been.calledWithExactly(
'createVersion',
options
);
done();
});
});

it('should return the serveur response body when request is successful', done => {
// Given
const proxyBarracks = new ProxifiedBarracks();
const response = { body: 'youpi created' };
spyCreateReadStream = sinon.spy();
spyBasename = sinon.spy();

proxyBarracks.client.sendEndpointRequest = sinon.stub().returns(Promise.resolve(response));

// When / Then
proxyBarracks.createVersion(token, version).then(result => {
expect(result).to.be.equals(response.body);
expect(proxyBarracks.client.sendEndpointRequest).to.have.been.calledOnce;
expect(proxyBarracks.client.sendEndpointRequest).to.have.been.calledWithExactly(
'createVersion',
options
);
done();
}).catch(err => {
done(err);
});
});
});

describe('#checkUpdate()', () => {

it('should reject an error if client fail', done => {
Expand Down
89 changes: 89 additions & 0 deletions commands/BarracksCommand.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -607,4 +607,93 @@ describe('BarracksCommand', () => {
});
});
});

describe('#render()', () => {

let mockedBarracksCommand;
let spyRender;
let spyJsonRender;

const mockedRender = (data) => {
spyRender(data);
};
const mockedJsonRender = (data) => {
spyJsonRender(data);
};
const program = {
option: () => { return program; },
parse: () => { return program; }
};
const MockedBarracksCommand = proxyquire('./BarracksCommand', {
'../renderers/prettyRenderer': (data) => {
mockedRender(data);
},
'../renderers/jsonRenderer': (data) => {
mockedJsonRender(data);
},
commander: program
});

before(() => {
mockedBarracksCommand = new MockedBarracksCommand();
});

it('should print error if arguments are missing', () => {
// Given
const originalConsoleError = console.error;
console.error = sinon.spy();
mockedBarracksCommand.validateCommand = sinon.stub().returns(false);

// When
mockedBarracksCommand.render();

// Then
expect(mockedBarracksCommand.validateCommand).to.have.been.calledOnce;
expect(mockedBarracksCommand.validateCommand).to.have.been.calledWithExactly(program);
expect(console.error).to.have.been.calledOnce;
expect(console.error).to.have.been.calledWithExactly(
'Mandatory arguments are missing or invalid. Use --help for more information.'
);
console.error = originalConsoleError;
});

it('should call renderer if execution successful', () => {
// Given
const executeResponse = { the: 'response' };
spyRender = sinon.spy();
mockedBarracksCommand.validateCommand = sinon.stub().returns(true);
mockedBarracksCommand.execute = sinon.stub().returns(executeResponse);

// When
mockedBarracksCommand.render();

// Then
expect(mockedBarracksCommand.validateCommand).to.have.been.calledOnce;
expect(mockedBarracksCommand.validateCommand).to.have.been.calledWithExactly(program);
expect(mockedBarracksCommand.execute).to.have.been.calledOnce;
expect(mockedBarracksCommand.execute).to.have.been.calledWithExactly(program);
expect(spyRender).to.have.been.calledOnce;
expect(spyRender).to.have.been.calledWithExactly(executeResponse);
});

it('should call json renderer if execution successful and json flag', () => {
// Given
const executeResponse = { the: 'response' };
program.json = true;
spyJsonRender = sinon.spy();
mockedBarracksCommand.validateCommand = sinon.stub().returns(true);
mockedBarracksCommand.execute = sinon.stub().returns(executeResponse);

// When
mockedBarracksCommand.render();

// Then
expect(mockedBarracksCommand.validateCommand).to.have.been.calledOnce;
expect(mockedBarracksCommand.validateCommand).to.have.been.calledWithExactly(program);
expect(mockedBarracksCommand.execute).to.have.been.calledOnce;
expect(mockedBarracksCommand.execute).to.have.been.calledWithExactly(program);
expect(spyJsonRender).to.have.been.calledOnce;
expect(spyJsonRender).to.have.been.calledWithExactly(executeResponse);
});
});
});
11 changes: 2 additions & 9 deletions commands/CreateFilterCommand.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
const Validator = require('../utils/Validator');
const BarracksCommand = require('./BarracksCommand');

function isValidJson(json) {
try {
return !!JSON.parse(json);
} catch (e) {
return false;
}
}

class CreateFilterCommand extends BarracksCommand {

configureCommand(program) {
Expand All @@ -20,7 +13,7 @@ class CreateFilterCommand extends BarracksCommand {
return !!(
program.name && program.name !== true && typeof program.name !== 'function' &&
program.query && program.query !== true &&
isValidJson(program.query)
Validator.isJsonString(program.query)
);
}

Expand Down
41 changes: 34 additions & 7 deletions commands/CreateFilterCommand.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,29 @@ const chai = require('chai');
const expect = chai.expect;
const sinon = require('sinon');
const sinonChai = require('sinon-chai');
const chaiAsPromised = require("chai-as-promised");
const CreateFilterCommand = require('./CreateFilterCommand');
const chaiAsPromised = require('chai-as-promised');
const proxyquire = require('proxyquire').noCallThru();

chai.use(chaiAsPromised);
chai.use(sinonChai);

describe('CreateFilterCommand', () => {

let createFilterCommand;
let proxyIsJsonString;
let proxyFileExists;

const CreateFilterCommand = proxyquire('./CreateFilterCommand', {
'../utils/Validator': {
isJsonString: (str) => {
return proxyIsJsonString(str);
},
fileExists: (path) => {
return proxyFileExists(path);
}
}
});

const token = 'i8uhkj.token.65ryft';
const programWithValidOptions = {
name: 'FilterName',
Expand Down Expand Up @@ -52,28 +66,35 @@ describe('CreateFilterCommand', () => {
createFilterCommand = new CreateFilterCommand();
createFilterCommand.barracks = {};
createFilterCommand.userConfiguration = {};
proxyIsJsonString = undefined;
roxyFileExists = undefined;
});

describe('#validateCommand(program)', () => {

it('should return true when all the options are valid and present', () => {
// Given
const program = Object.assign({}, programWithValidOptions);
const spyIsJsonString = sinon.spy();
proxyIsJsonString = (str) => {
spyIsJsonString(str);
return true;
}

// When
const result = createFilterCommand.validateCommand(program);

// Then
expect(result).to.be.true;
expect(spyIsJsonString).to.have.been.calledOnce;
expect(spyIsJsonString).to.have.been.calledWithExactly(programWithValidOptions.query);
});

it('should return false when name is missing', () => {
// Given
const program = Object.assign({}, programWithValidOptions, { name: undefined });

// When
const result = createFilterCommand.validateCommand(program);

// Then
expect(result).to.be.false;
});
Expand All @@ -92,23 +113,29 @@ describe('CreateFilterCommand', () => {
it('should return false when query is missing', () => {
// Given
const program = Object.assign({}, programWithValidOptions, { query: undefined });

// When
const result = createFilterCommand.validateCommand(program);

// Then
expect(result).to.be.false;
});

it('should return false when query is not a valid JSON', () => {
// Given
const program = Object.assign({}, programWithValidOptions, { query: 'Not { a } json' });
const query = 'Not { a } json';
const program = Object.assign({}, programWithValidOptions, { query });
const spyIsJsonString = sinon.spy();
proxyIsJsonString = (str) => {
spyIsJsonString(str);
return false;
}

// When
const result = createFilterCommand.validateCommand(program);

// Then
expect(result).to.be.false;
expect(spyIsJsonString).to.have.been.calledOnce;
expect(spyIsJsonString).to.have.been.calledWithExactly(query);
});

});
Expand Down
Loading