Skip to content

Commit 3039e4b

Browse files
authored
Merge pull request #13 from gurbraj/modify-referendum-proposal
first commit modify referendum proposal
2 parents 7336874 + 052f4a7 commit 3039e4b

File tree

4 files changed

+141
-18
lines changed

4 files changed

+141
-18
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export default class ModifyReferendumProposal {
2+
constructor(referendumId, organizationId, proposal) {
3+
this.referendumId = referendumId; // mandatory
4+
this.organizationId = organizationId; // mandatory
5+
this.proposal = proposal; // mandatory
6+
}
7+
};

api/src/domain/Referendum.js

+55-18
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import CreateReferendum from '../commands/CreateReferendum';
2+
import ModifyReferendumProposal from '../commands/ModifyReferendumProposal';
23
import DeleteReferendum from '../commands/DeleteReferendum';
34
import AuthenticateVoter from "../commands/AuthenticateVoter"
45
import OpenPolls from "../commands/OpenPolls"
56
import ClosePolls from "../commands/ClosePolls"
67
import CastVote from "../commands/CastVote"
78
import ReferendumCreated from '../events/ReferendumCreated';
9+
import ReferendumProposalModified from '../events/ReferendumProposalModified';
810
import ReferendumDeleted from '../events/ReferendumDeleted';
911
import PollsOpened from '../events/PollsOpened';
1012
import PollsClosed from '../events/PollsClosed';
@@ -26,6 +28,9 @@ export default class Referendum {
2628
if (evt instanceof ReferendumCreated) {
2729
this._onReferendumCreated(evt);
2830
}
31+
if (evt instanceof ReferendumProposalModified) {
32+
this._onReferendumProposalModified(evt);
33+
}
2934
if (evt instanceof PollsOpened) {
3035
this._onPollsOpened();
3136
}
@@ -45,6 +50,10 @@ export default class Referendum {
4550
this._options = evt.options
4651
}
4752

53+
_onReferendumProposalModified(evt) {
54+
this._proposal = evt.proposal;
55+
}
56+
4857
_onPollsOpened() {
4958
this._status = "polls_open";
5059
}
@@ -65,6 +74,9 @@ export default class Referendum {
6574
if (command instanceof CreateReferendum) {
6675
return this._CreateReferendum(command);
6776
}
77+
if (command instanceof ModifyReferendumProposal) {
78+
return this._ModifyReferendumProposal(command);
79+
}
6880
if (command instanceof DeleteReferendum) {
6981
return this._DeleteReferendum(command);
7082
}
@@ -96,25 +108,50 @@ export default class Referendum {
96108
}
97109
if(!command.proposal) {
98110
validationErrors.push({"field": "proposal", "msg": "Referendum proposal is a required field."});
99-
}
111+
}
100112
if(!command.name) {
101113
validationErrors.push({"field": "name", "msg": "Referendum name is a required field."});
102-
}
114+
}
103115
if(!command.options) {
104116
validationErrors.push({"field": "options", "msg": "Referendum options are required."});
105117
}
106118
if(command.options&&command.options.length < 2) {
107119
validationErrors.push({"field": "options", "msg": "At least two options are required."});
108-
}
120+
}
109121
if(validationErrors.length > 0) {
110122
throw new errors.ValidationFailed(validationErrors);
111-
}
123+
}
112124
command.options.push("None of the above");
113125
var result = [];
114126
result.push(new ReferendumCreated(command.referendumId, command.organizationId, command.name, command.proposal, command.options));
115127
return result;
116128
}
117129

130+
_ModifyReferendumProposal(command) {
131+
var validationErrors = [];
132+
133+
if (!this._id) {
134+
validationErrors.push({"field": "", "msg": "Referendum does not exist." });
135+
}
136+
if (!command.referendumId) {
137+
validationErrors.push({"field": "referendum", "msg": "ReferendumId is a required field"});
138+
}
139+
if (!command.organizationId) {
140+
validationErrors.push({"field": "organization", "msg": "organizationId is a required field"});
141+
}
142+
if (!command.proposal) {
143+
validationErrors.push({"field": "proposal", "msg": "proposal is a required field"});
144+
}
145+
146+
if (validationErrors.length > 0) {
147+
throw new errors.ValidationFailed(validationErrors);
148+
}
149+
150+
var result = [];
151+
result.push( new ReferendumProposalModified(command.referendumId, command.organizationId, command.proposal) );
152+
return result;
153+
}
154+
118155
_DeleteReferendum(command) {
119156
var validationErrors = [];
120157
if(!this._id) {
@@ -131,7 +168,7 @@ export default class Referendum {
131168
}
132169
if(validationErrors.length > 0) {
133170
throw new errors.ValidationFailed(validationErrors);
134-
}
171+
}
135172
var result = [];
136173
result.push(new ReferendumDeleted(command.referendumId));
137174
return result;
@@ -141,19 +178,19 @@ export default class Referendum {
141178
var validationErrors = [];
142179
if(!this._id) {
143180
validationErrors.push({"field": "", "msg": "Referendum does not exist."})
144-
}
181+
}
145182
if(!command.referendumId) {
146183
validationErrors.push({"field": "referendumId", "msg": "Referendum id is a required field."});
147184
}
148185
if(this._status === "polls_open") {
149-
validationErrors.push({"field": "", "msg": "Polls are already open."})
186+
validationErrors.push({"field": "", "msg": "Polls are already open."})
150187
}
151188
if(this._status === "polls_closed") {
152-
validationErrors.push({"field": "", "msg": "Polls have already been closed."})
189+
validationErrors.push({"field": "", "msg": "Polls have already been closed."})
153190
}
154191
if(validationErrors.length > 0) {
155192
throw new errors.ValidationFailed(validationErrors);
156-
}
193+
}
157194
var result = [];
158195
result.push(new PollsOpened(command.referendumId));
159196
return result;
@@ -163,16 +200,16 @@ export default class Referendum {
163200
var validationErrors = [];
164201
if(!this._id) {
165202
validationErrors.push({"field": "", "msg": "Referendum does not exist."})
166-
}
203+
}
167204
if(!command.referendumId) {
168205
validationErrors.push({"field": "referendumId", "msg": "Referendum id is a required field."});
169206
}
170207
if(!(this._status === "polls_open")) {
171-
validationErrors.push({"field": "referendumId", "msg": "Polls are not open."})
208+
validationErrors.push({"field": "referendumId", "msg": "Polls are not open."})
172209
}
173210
if(validationErrors.length > 0) {
174211
throw new errors.ValidationFailed(validationErrors);
175-
}
212+
}
176213
var result = [];
177214
result.push(new PollsClosed(command.referendumId));
178215
return result;
@@ -187,8 +224,8 @@ export default class Referendum {
187224
validationErrors.push({"field": "organizationId", "msg": "Organization does not exist."});
188225
}
189226
if(this._status != "polls_open") {
190-
validationErrors.push({"field": "", "msg": "Polls are not open."})
191-
}
227+
validationErrors.push({"field": "", "msg": "Polls are not open."})
228+
}
192229
if(!command.voterId) {
193230
validationErrors.push({"field": "voterId", "msg": "Voter id is a required field."});
194231
}
@@ -197,11 +234,11 @@ export default class Referendum {
197234
validationErrors.push({"field": "voterId", "msg": "Voter is not on voter list"});
198235
}
199236
if(this._authenticatedVoters.indexOf(command.voterId) != -1) {
200-
validationErrors.push({"field": "voterId", "msg": "Voter has already voted"});
237+
validationErrors.push({"field": "voterId", "msg": "Voter has already voted"});
201238
}
202239
if(validationErrors.length > 0) {
203240
throw new errors.ValidationFailed(validationErrors);
204-
}
241+
}
205242
var result = [];
206243
result.push(new VoterAuthenticated(command.referendumId, command.organizationId, command.voterId));
207244
return result;
@@ -213,8 +250,8 @@ export default class Referendum {
213250
validationErrors.push({"field": "referendumId", "msg": "Referendum id is a required field."});
214251
}
215252
if(this._status != "polls_open") {
216-
validationErrors.push({"field": "", "msg": "Polls are not open."})
217-
}
253+
validationErrors.push({"field": "", "msg": "Polls are not open."})
254+
}
218255
if(!command.vote) {
219256
validationErrors.push({"field": "vote", "msg": "Vote is a required field."});
220257
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export default class ReferendumProposalModified {
2+
constructor(referendumId, organizationId, proposal) {
3+
this.referendumId = referendumId; // mandatory
4+
this.organizationId = organizationId; // mandatory
5+
this.proposal = proposal; // mandatory
6+
}
7+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/* eslint-env mocha */
2+
import Referendum from '../src/domain/Referendum';
3+
import ModifyReferendumProposal from '../src/commands/ModifyReferendumProposal';
4+
import ReferendumProposalModified from '../src/events/ReferendumProposalModified';
5+
import CreateReferendum from '../src/commands/CreateReferendum';
6+
import assert from 'assert';
7+
8+
describe('Modifying referendums', function() {
9+
describe('Given a referendum that does not exist, when the command ModifyReferendumProposal is called', function() {
10+
it('should throw a error', function() {
11+
assert.throws(() => {
12+
//making a empty referendum (that is not persisted into db) to borrow the execute method.
13+
var referendum = new Referendum();
14+
referendum.execute(new ModifyReferendumProposal("134", "organization-1", "Changed proposal goes here "))
15+
16+
},
17+
function(err) {
18+
if (err.name == "ValidationFailed" && err.message.find(m => m.msg === "Referendum does not exist.") ) {
19+
return true;
20+
}
21+
},
22+
);
23+
});
24+
});
25+
describe('Given an existing referendum, when ModifyReferendumProposal is called', function() {
26+
var referendum = new Referendum();
27+
var options = ["Remain a member of European Union", "Leave the European Union"];
28+
referendum.hydrate(
29+
referendum.execute(
30+
new CreateReferendum("134", "organization-1", "Referendum Name",
31+
"Should the United Klingon remain a member of the European Union?",
32+
options
33+
)
34+
)[0]
35+
);
36+
//above is setup for hydrating a existing referendum, now execute ModifyReferendumProposal
37+
describe("when modified proposal is valid", function() {
38+
var result = referendum.execute(
39+
new ModifyReferendumProposal("134", "organization-1", "modified proposal goes here")
40+
);
41+
it('should publish a ReferendumProposalModified event', function() {
42+
assert.ok(result[0] instanceof ReferendumProposalModified);
43+
assert.ok(result.length == 1);
44+
})
45+
it('it should have the referendum id', function() {
46+
assert.equal(result[0].referendumId, "134");
47+
});
48+
it('it should have the organization id', function() {
49+
assert.equal(result[0].organizationId, "organization-1");
50+
});
51+
it('it should have the modified proposal', function() {
52+
assert.equal(result[0].proposal, "modified proposal goes here");
53+
});
54+
})
55+
describe("when modified proposal is not valid", function() {
56+
it("throws an error", function() {
57+
assert.throws(
58+
() => {
59+
var result = referendum.execute(
60+
new ModifyReferendumProposal("134", "organization-1", "")
61+
);
62+
},
63+
function(err) {
64+
if (err.name == "ValidationFailed" && err.message.find(m => m.field && m.msg === "proposal is a required field") ) {
65+
return true
66+
}
67+
}
68+
);
69+
});
70+
});
71+
});
72+
});

0 commit comments

Comments
 (0)