Skip to content

Commit 43ffaa4

Browse files
authored
Merge pull request CoderDojo#173 from CoderDojo/staging
Staging sync
2 parents cbafa69 + ee0a230 commit 43ffaa4

17 files changed

+222
-539
lines changed

Dockerfile

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
FROM mhart/alpine-node:0.10.48
22
MAINTAINER butlerx <[email protected]>
3+
ENV NODE_ENV=production
34
ARG DEP_VERSION=latest
4-
RUN apk add --update git build-base python postgresql-client
5-
RUN mkdir -p /usr/src/app
5+
RUN apk add --update git build-base python postgresql-client &&\
6+
mkdir -p /usr/src/app
67
WORKDIR /usr/src/app
7-
ADD . /usr/src/app
8+
COPY . /usr/src/app
89
RUN npm install && \
9-
npm install cp-translations@$DEP_VERSION && \
10+
npm install cp-translations@"$DEP_VERSION" && \
1011
apk del build-base python && \
1112
rm -rf /tmp/* /root/.npm /root/.node-gyp
1213
EXPOSE 10306
13-
CMD ["npm", "start"]
14+
CMD ["npm", "start"]

dev.Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
FROM mhart/alpine-node:0.10.48
22
MAINTAINER butlerx <[email protected]>
3+
ENV NODE_ENV=development
34
RUN apk add --update git build-base python postgresql-client && \
45
mkdir -p /usr/src/app /usr/src/cp-translations
56
COPY docker-entrypoint.sh /usr/src

lib/cd-events.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,12 @@ module.exports = function () {
5959

6060
// CRUD
6161
seneca.add({role: plugin, entity: 'invite', cmd: 'list'}, require('./entity/invite/list'));
62+
seneca.add({role: plugin, entity: 'event', cmd: 'save'}, require('./entity/event/save'));
63+
seneca.add({role: plugin, entity: 'next-events', cmd: 'list'}, require('./entity/next-events/list'));
6264

6365
// Controllers
6466
seneca.add({role: plugin, ctrl: 'applications', cmd: 'list'}, require('./controllers/application/list'));
67+
seneca.add({role: plugin, ctrl: 'events', cmd: 'updateAddress'}, require('./controllers/event/update-address'));
6568

6669
// PERMS
6770
seneca.add({role: plugin, cmd: 'is_ticketing_admin'}, isTicketingAdmin.bind(seneca));
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
var async = require('async');
2+
/**
3+
* updateAddress function - Called to update all upcoming event address upon dojo address change
4+
* By default asynchronous
5+
* @param {String} dojoId Identifier of the parent entity
6+
* @param {Object} location Object containing the information of the address
7+
* @return {Void}
8+
*/
9+
module.exports = function (args, done) {
10+
var seneca = this;
11+
var plugin = args.role;
12+
var dojoId = args.dojoId;
13+
var location = args.location;
14+
// Retrieve all events in the future
15+
function getUpcomingEvents (wfCb) {
16+
seneca.act({role: plugin, entity: 'next-events', cmd: 'list', query: {dojoId: dojoId, useDojoAddress: true}},
17+
function (err, events) {
18+
if (events && events.length > 0) {
19+
wfCb(null, events);
20+
} else {
21+
done();
22+
}
23+
});
24+
}
25+
function updateEvents (events, wfCb) {
26+
async.eachSeries(events, updateAddress, wfCb);
27+
}
28+
// Save the new address
29+
function updateAddress (event, sCb) {
30+
var payload = {
31+
id: event.id,
32+
country: location.country,
33+
city: location.city,
34+
address: location.address,
35+
position: location.position
36+
};
37+
seneca.act({role: plugin, entity: 'event', cmd: 'save', event: payload}, sCb);
38+
}
39+
async.waterfall([
40+
getUpcomingEvents,
41+
updateEvents
42+
], done);
43+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
'use strict';
2+
3+
var lab = exports.lab = require('lab').script();
4+
var chai = require('chai');
5+
var expect = chai.expect;
6+
chai.use(require('sinon-chai'));
7+
var sinon = require('sinon');
8+
var _ = require('lodash');
9+
var fn = require(__dirname + '/update-address.js');
10+
11+
lab.experiment('Event - Update address', { timeout: 5000 }, function () {
12+
var sandbox;
13+
var senecaStub;
14+
var updateAddress;
15+
16+
lab.beforeEach(function (done) {
17+
sandbox = sinon.sandbox.create();
18+
senecaStub = {
19+
act: sandbox.stub(),
20+
make: sandbox.stub()
21+
};
22+
updateAddress = fn.bind(senecaStub);
23+
done();
24+
});
25+
26+
lab.afterEach(function (done) {
27+
sandbox.restore();
28+
done();
29+
});
30+
31+
lab.test('should get next events and update addresses of those events', function (done) {
32+
// ARRANGE
33+
var dojoId = 1;
34+
var mockLocation = {
35+
address: 'aha',
36+
city: { placeName: 'place' },
37+
country: {
38+
alpha2: 'FR',
39+
countryName: 'France'
40+
},
41+
position: { lat: 1, lng: 1 } };
42+
var mockEvents = [{ id: 1, name: 'event1' }];
43+
var eventMock = _.assign({},
44+
mockLocation,
45+
{ id: mockEvents[0].id });
46+
// PREPARE
47+
senecaStub.act
48+
.withArgs(sinon.match({ role: 'cd-events', entity: 'next-events', cmd: 'list' }))
49+
.callsFake(function (args, cb) {
50+
expect(args.query).to.be.eql({
51+
dojoId: dojoId,
52+
useDojoAddress: true
53+
});
54+
cb(null, mockEvents);
55+
});
56+
senecaStub.act
57+
.withArgs(sinon.match({ role: 'cd-events', entity: 'event', cmd: 'save' }))
58+
.callsFake(function (args, cb) {
59+
expect(args.event).to.be.eql(eventMock);
60+
cb(null, eventMock);
61+
});
62+
// ACT
63+
updateAddress({ role: 'cd-events', dojoId: 1, location: mockLocation }, function (err, ret) {
64+
expect(err).to.be.eql(undefined);
65+
expect(ret).to.be.eql(undefined);
66+
done();
67+
});
68+
});
69+
70+
lab.test('should not save if there is no events', function (done) {
71+
// ARRANGE
72+
var dojoId = 1;
73+
var mockLocation = {
74+
address: 'aha',
75+
city: { placeName: 'place' },
76+
country: {
77+
alpha2: 'FR',
78+
countryName: 'France'
79+
},
80+
position: { lat: 1, lng:1 }
81+
};
82+
var mockEvents = [];
83+
// PREPARE
84+
senecaStub.act
85+
.withArgs(sinon.match({ role: 'cd-events', entity: 'next-events', cmd: 'list' }))
86+
.callsFake(function (args, cb) {
87+
expect(args.query).to.be.eql({
88+
dojoId: dojoId,
89+
useDojoAddress: true
90+
});
91+
cb(null, mockEvents);
92+
});
93+
// ACT
94+
updateAddress({role: 'cd-events', dojoId: 1, location: mockLocation}, function (err, ret) {
95+
expect(err).to.be.eql(undefined);
96+
expect(ret).to.be.eql(undefined);
97+
expect(senecaStub.act
98+
.withArgs(sinon.match({ role: 'cd-events', entity: 'event', cmd: 'save' }))
99+
).to.not.have.been.called;
100+
done();
101+
});
102+
});
103+
});

lib/entity/event/save.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = function (args, done) {
2+
var seneca = this;
3+
var event = args.event;
4+
seneca.make$('cd/events').save$(event, done);
5+
};

lib/entity/next-events/list.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module.exports = function (args, done) {
2+
var seneca = this;
3+
var query = args.query;
4+
if (query) {
5+
seneca.make$('v/next_events').list$(query, done);
6+
} else {
7+
done(null, []);
8+
}
9+
}

lib/save-event.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ function saveEvent (args, callback) {
5151
public: eventInfo.public,
5252
status: eventInfo.status,
5353
type: eventInfo.type,
54+
useDojoAddress: eventInfo.useDojoAddress || false, // Backward compat : set it as false
5455
recurringType: eventInfo.recurringType,
5556
ticketApproval: eventInfo.ticketApproval,
5657
notifyOnApplicant: eventInfo.notifyOnApplicant
@@ -73,6 +74,7 @@ function saveEvent (args, callback) {
7374
});
7475

7576
if (pastDateFound && !eventInfo.id) return done(new Error('Past events cannot be created'));
77+
if (pastDateFound && eventInfo.id) return done(new Error('Past events cannot be edited'));
7678

7779
newEvent.dates = eventInfo.dates;
7880

package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"scripts": {
77
"lint": "semistandard *.js config/config.js",
88
"testdata": "node test/lib/service.js",
9-
"test": "bash -c 'source ./config/development.env; npm run lint && lab --ignore __core-js_shared__ --flat --threshold 48 -r html -o ./coverage/coverage.html -r lcov -o ./coverage/lcov.info -r json -o ./coverage/coverage.json -r console -o stdout'",
9+
"test": "sh -c 'source ./config/development.env; npm run lint && lab lib/controllers -P spec --ignore __core-js_shared__ '",
10+
"coverage": "sh -c 'source ./config/development.env; lab --threshold 68 -r html -o ./coverage/coverage.html -r lcov -o ./coverage/lcov.info -r json -o ./coverage/coverage.json -r console -o stdout'",
1011
"start": "node service.js",
1112
"dev": "nodemon service.js"
1213
},
@@ -23,12 +24,13 @@
2324
"url": "https://github.com/CoderDojo/community-platform/issues"
2425
},
2526
"devDependencies": {
26-
"chai": "2.2.0",
27+
"chai": "^4.0",
2728
"lab": "5.15.2",
2829
"nodemon": "1.11.0",
2930
"pre-commit": "1.1.2",
3031
"semistandard": "7.0.3",
31-
"sinon": "1.16.1"
32+
"sinon": "^2.3",
33+
"sinon-chai": "^2.14.0"
3234
},
3335
"dependencies": {
3436
"async": "0.9.2",
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
DO $$
2+
BEGIN
3+
BEGIN
4+
ALTER TABLE cd_events ADD COLUMN use_dojo_address boolean;
5+
EXCEPTION
6+
WHEN duplicate_column THEN RAISE NOTICE 'column useDojoAddress already exists in cd_events.';
7+
END;
8+
END;
9+
$$

0 commit comments

Comments
 (0)