Skip to content

Commit

Permalink
Merge pull request #61 from barracksiot/BO-1486
Browse files Browse the repository at this point in the history
Bo 1486 : Add retained in messaging
  • Loading branch information
bargenson committed Aug 11, 2017
2 parents 9da6eb4 + 94d0668 commit b5f3c28
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 26 deletions.
8 changes: 6 additions & 2 deletions src/clients/MessageClient.js
Expand Up @@ -9,7 +9,7 @@ const endpoints = {
},
sendMessageToAll: {
method: 'POST',
path: '/api/messaging/messages'
path: '/api/messaging/messages?:query'
}
};

Expand All @@ -21,6 +21,7 @@ class MessageClient {
}

sendMessage(token, message) {
/*jshint maxcomplexity:5 */
return new Promise((resolve, reject) => {
this.httpClient.sendEndpointRequest(
endpoints.sendMessage,
Expand All @@ -29,7 +30,7 @@ class MessageClient {
'x-auth-token': token
},
pathVariables: {
query: 'unitId=' + encodeURI(message.unitId || '') + '&filter=' + encodeURI(message.filter || '')
query: 'unitId=' + encodeURI(message.unitId || '') + '&filter=' + encodeURI(message.filter || '') + '&retained=' + encodeURI(message.retained || 'false')
},
body: message.message
}
Expand All @@ -51,6 +52,9 @@ class MessageClient {
headers: {
'x-auth-token': token
},
pathVariables: {
query: 'retained=' + encodeURI(message.retained || 'false')
},
body: message.message
}
).then(response => {
Expand Down
17 changes: 11 additions & 6 deletions src/commands/hook/CreateHookCommand.js
Expand Up @@ -19,28 +19,34 @@ function getEventType(program) {
if (program.enrollment) {
return 'ENROLLMENT';
}
if(program.deviceDataChange) {
return 'DEVICE_DATA_CHANGE';
}
}

function getGoogleClientSecret(program) {
return ObjectReader.readObjectFromFile(program.googleClientSecret);
}

function hasValidEventType(program) {
return (!program.ping && program.enrollment || program.ping && !program.enrollment);
return (!program.ping && program.enrollment && !program.deviceDataChange ||
program.ping && !program.enrollment && !program.deviceDataChange ||
!program.ping && !program.enrollment && program.deviceDataChange);
}

function hasValidHookTypeAndArguments(program) {
return (program.web && !program.googleAnalytics && !program.bigquery && program.url && program.url !== true ||
!program.web && program.googleAnalytics && !program.bigquery && program.gaTrackingId && program.gaTrackingId !== true ||
!program.web && !program.googleAnalytics && program.bigquery && program.googleClientSecret && Validator.fileExists(program.googleClientSecret))
!program.web && !program.googleAnalytics && program.bigquery && program.googleClientSecret && Validator.fileExists(program.googleClientSecret));
}

class CreateHookCommand extends BarracksCommand {

configureCommand(program) {
return program
.option('--ping', 'To create a hook triggered by the ping of a device.')
.option('--enrollment', 'To create a hook for the first ping of a device')
.option('--enrollment', 'To create a hook for the first ping of a device.')
.option('--deviceDataChange', 'To create a hook triggered when a device pings with new custom client data.')
.option('--web', 'To create a web hook')
.option('--googleAnalytics', 'To create a Google Analytics hook')
.option('--bigquery', 'To create a BigQuery hook')
Expand All @@ -51,9 +57,8 @@ class CreateHookCommand extends BarracksCommand {
}

validateCommand(program) {
return !!(
hasValidEventType(program) &&
(hasValidHookTypeAndArguments(program)) &&
return !!(hasValidEventType(program) &&
hasValidHookTypeAndArguments(program) &&
program.name && program.name !== true
);
}
Expand Down
12 changes: 8 additions & 4 deletions src/commands/message/SendMessageCommand.js
Expand Up @@ -6,29 +6,33 @@ class SendMessageCommand extends BarracksCommand {
return program.option('--unitId [value]', 'The device to which the message will be sent')
.option('--all', 'Indicates the message must be sent to all devices')
.option('--filter [value]', 'Allows to send messages to devices belonging to a specific filter')
.option('--message [value]', 'The content of the message');
.option('--message [value]', 'The content of the message')
.option('--retained [value]', 'Indicates whether the message should be retained');
}

validateCommand(program) {
return !!(
((program.unitId && program.unitId !== true && !program.all) ||
(!program.unitId && !program.filter && program.all) ||
(!program.unitId && !program.all && program.filter && program.filter !== true)) &&
program.message && program.message !== true
(program.message && program.message !== true) &&
((program.retained && (program.retained === 'true' || program.retained === 'false')) || !program.retained)
);
}

execute(program) {
return this.getAuthenticationToken().then(token => {
if (program.all) {
return this.barracks.sendMessageToAll(token, {
message: program.message
message: program.message,
retained: program.retained
});
} else {
return this.barracks.sendMessage(token, {
unitId: program.unitId,
filter: program.filter,
message: program.message
message: program.message,
retained: program.retained
});
}
});
Expand Down
61 changes: 52 additions & 9 deletions tests/clients/MessageClient.spec.js
Expand Up @@ -25,16 +25,28 @@ describe('MessageClient', () => {
const unitId = 'aShortUnitId';
const filter = 'superfilter';
const messageContent = 'messageInABottle';
const retained = 'true';
const message = {
unitId,
filter,
message: messageContent
};
message: messageContent,
retained
}

const messageNoFilter = {
unitId,
message: messageContent
message: messageContent,
retained
};

const messageNoUnitId = {
filter,
message: messageContent,
retained
};

const messageNoRetained = {
unitId,
filter,
message: messageContent
};
Expand All @@ -57,7 +69,7 @@ describe('MessageClient', () => {
},
{
headers: { 'x-auth-token': token },
pathVariables: { query: 'unitId=' + message.unitId + '&filter=' + message.filter },
pathVariables: { query: 'unitId=' + message.unitId + '&filter=' + message.filter + '&retained=' + message.retained},
body: message.message
}
);
Expand All @@ -83,14 +95,15 @@ describe('MessageClient', () => {
},
{
headers: { 'x-auth-token': token },
pathVariables: { query: 'unitId=' + messageNoFilter.unitId + '&filter='},
pathVariables: { query: 'unitId=' + messageNoFilter.unitId + '&filter=' + '&retained=' + message.retained},
body: messageNoFilter.message
}
);
done();
});
});


it('should return the message sent when request succeeds', done => {
// Given
const response = { body: message.message };
Expand All @@ -107,7 +120,7 @@ describe('MessageClient', () => {
},
{
headers: { 'x-auth-token': token },
pathVariables: { query: 'unitId=' + messageNoFilter.unitId + '&filter=' + message.filter},
pathVariables: { query: 'unitId=' + message.unitId + '&filter=' + message.filter + '&retained=' + message.retained},
body: message.message
}
);
Expand All @@ -133,7 +146,7 @@ describe('MessageClient', () => {
},
{
headers: { 'x-auth-token': token },
pathVariables: { query: 'unitId=' + '&filter=' + messageNoUnitId.filter},
pathVariables: { query: 'unitId=' + '&filter=' + messageNoUnitId.filter + '&retained=' + message.retained},
body: messageNoUnitId.message
}
);
Expand All @@ -142,6 +155,34 @@ describe('MessageClient', () => {
done(err);
});
});

it('should return the message sent when request succeeds and should use false instead of undefined when no retained provided', done => {
// Given
const response = { body: messageNoRetained.message };
messageClient.httpClient.sendEndpointRequest = sinon.stub().returns(Promise.resolve(response));

// When / Then
messageClient.sendMessage(token, messageNoRetained).then(result => {
expect(result).to.be.equals(messageNoRetained.message);
expect(messageClient.httpClient.sendEndpointRequest).to.have.been.calledOnce;
expect(messageClient.httpClient.sendEndpointRequest).to.have.been.calledWithExactly(
{
method: 'POST',
path: '/api/messaging/messages?:query'
},
{
headers: { 'x-auth-token': token },
pathVariables: { query: 'unitId=' + messageNoRetained.unitId + '&filter=' + messageNoRetained.filter + '&retained=false'},
body: messageNoRetained.message
}
);
done();
}).catch(err => {
done(err);
});
});


});

describe('#sendMessageToAll()', () => {
Expand All @@ -165,10 +206,11 @@ describe('MessageClient', () => {
expect(messageClient.httpClient.sendEndpointRequest).to.have.been.calledWithExactly(
{
method: 'POST',
path: '/api/messaging/messages'
path: '/api/messaging/messages?:query'
},
{
headers: { 'x-auth-token': token },
pathVariables: { query: 'retained=' + (message.retained || 'false')},
body: message.message
}
);
Expand All @@ -188,10 +230,11 @@ describe('MessageClient', () => {
expect(messageClient.httpClient.sendEndpointRequest).to.have.been.calledWithExactly(
{
method: 'POST',
path: '/api/messaging/messages'
path: '/api/messaging/messages?:query'
},
{
headers: { 'x-auth-token': token },
pathVariables: { query: 'retained=' + (message.retained || 'false')},
body: message.message
}
);
Expand Down
63 changes: 62 additions & 1 deletion tests/commands/hook/CreateHookCommand.spec.js
Expand Up @@ -118,6 +118,15 @@ describe('CreateHookCommand', () => {
expect(result).to.be.true;
});

it('should return true when event type is enrollment', () => {
// Given
const program = Object.assign({}, programWithValidOptions, { ping: false, deviceDataChange:true });
// When
const result = createHookCommand.validateCommand(program);
// Then
expect(result).to.be.true;
});

it('should return false when event type is missing', () => {
// Given
const program = Object.assign({}, programWithValidOptions, { ping: undefined });
Expand All @@ -127,7 +136,7 @@ describe('CreateHookCommand', () => {
expect(result).to.be.false;
});

it('should return false when multiple event types', () => {
it('should return false when ping and enrollment', () => {
// Given
const program = Object.assign({}, programWithValidOptions, { ping: true, enrollment:true });
// When
Expand All @@ -136,6 +145,24 @@ describe('CreateHookCommand', () => {
expect(result).to.be.false;
});

it('should return false when ping and deviceDataChange', () => {
// Given
const program = Object.assign({}, programWithValidOptions, { ping: true, deviceDataChange:true });
// When
const result = createHookCommand.validateCommand(program);
// Then
expect(result).to.be.false;
});

it('should return false when enrollment and deviceDataChange', () => {
// Given
const program = Object.assign({}, programWithValidOptions, { ping:false, enrollment: true, deviceDataChange:true });
// When
const result = createHookCommand.validateCommand(program);
// Then
expect(result).to.be.false;
});

it('should return false when web and GA', () => {
// Given
const program = Object.assign({}, programWithValidOptions, { web:true, googleAnalytics: true });
Expand Down Expand Up @@ -293,6 +320,40 @@ describe('CreateHookCommand', () => {
});
});

it('should return the created hook when the request was successful and event type is deviceDataChange', done => {
// Given
const spyReadObjectFromStdin = sinon.spy();
proxyReadObjectFromStdin = () => {
spyReadObjectFromStdin();
return undefined;
};

const program = Object.assign({}, programWithValidOptions, { ping: false, deviceDataChange:true });
createHookCommand.getAuthenticationToken = sinon.stub().returns(Promise.resolve(token));
createHookCommand.barracks = {
createHook: sinon.stub().returns(Promise.resolve(createdHook))
};

// When / Then
createHookCommand.execute(program).then(result => {
expect(result).to.be.equals(createdHook);
expect(createHookCommand.getAuthenticationToken).to.have.been.calledOnce;
expect(createHookCommand.getAuthenticationToken).to.have.been.calledWithExactly();
expect(createHookCommand.barracks.createHook).to.have.been.calledOnce;
expect(createHookCommand.barracks.createHook).to.have.been.calledWithExactly(token, {
eventType: 'DEVICE_DATA_CHANGE',
type: 'web',
name: program.name,
url: program.url,
gaTrackingId: undefined,
googleClientSecret: undefined
});
done();
}).catch(err => {
done(err);
});
});

it('should return the created hook when the request was successful and hook type is google analytics', done => {
// Given
const spyReadObjectFromFile = sinon.spy();
Expand Down

0 comments on commit b5f3c28

Please sign in to comment.