Skip to content

Commit

Permalink
duplicate vote prevention
Browse files Browse the repository at this point in the history
  • Loading branch information
teropa committed Sep 10, 2015
1 parent 80b1cd6 commit 3371786
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 15 deletions.
27 changes: 21 additions & 6 deletions src/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,29 @@ export function next(state) {
}
}

export function vote(voteState, entry) {
function removePreviousVote(voteState, voter) {
const previousVote = voteState.getIn(['votes', voter]);
if (previousVote) {
return voteState.updateIn(['tally', previousVote], t => t - 1)
.removeIn(['votes', voter]);
} else {
return voteState;
}
}

function addVote(voteState, entry, voter) {
if (voteState.get('pair').includes(entry)) {
return voteState.updateIn(
['tally', entry],
0,
tally => tally + 1
);
return voteState.updateIn(['tally', entry], 0, t => t + 1)
.setIn(['votes', voter], entry);
} else {
return voteState;
}
}

export function vote(voteState, entry, voter) {
return addVote(
removePreviousVote(voteState, voter),
entry,
voter
);
}
2 changes: 1 addition & 1 deletion src/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default function reducer(state = INITIAL_STATE, action) {
return next(state);
case 'VOTE':
return state.update('vote',
voteState => vote(voteState, action.entry));
voteState => vote(voteState, action.entry, action.clientId));
}
return state;
}
41 changes: 38 additions & 3 deletions test/core_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,16 @@ describe('application logic', () => {
vote(Map({
round: 1,
pair: List.of('Trainspotting', '28 Days Later')
}), 'Trainspotting')
}), 'Trainspotting', 'voter1')
).to.equal(
Map({
round: 1,
pair: List.of('Trainspotting', '28 Days Later'),
tally: Map({
'Trainspotting': 1
}),
votes: Map({
voter1: 'Trainspotting'
})
})
);
Expand All @@ -140,15 +143,47 @@ describe('application logic', () => {
tally: Map({
'Trainspotting': 3,
'28 Days Later': 2
})
}), 'Trainspotting')
}),
votes: Map()
}), 'Trainspotting', 'voter1')
).to.equal(
Map({
round: 1,
pair: List.of('Trainspotting', '28 Days Later'),
tally: Map({
'Trainspotting': 4,
'28 Days Later': 2
}),
votes: Map({
voter1: 'Trainspotting'
})
})
);
});

it('nullifies previous vote for the same voter', () => {
expect(
vote(Map({
round: 1,
pair: List.of('Trainspotting', '28 Days Later'),
tally: Map({
'Trainspotting': 3,
'28 Days Later': 2
}),
votes: Map({
voter1: '28 Days Later'
})
}), 'Trainspotting', 'voter1')
).to.equal(
Map({
round: 1,
pair: List.of('Trainspotting', '28 Days Later'),
tally: Map({
'Trainspotting': 4,
'28 Days Later': 1
}),
votes: Map({
voter1: 'Trainspotting'
})
})
);
Expand Down
13 changes: 8 additions & 5 deletions test/reducer_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,17 @@ describe('reducer', () => {
},
entries: []
});
const action = {type: 'VOTE', entry: 'Trainspotting'};
const action = {type: 'VOTE', entry: 'Trainspotting', clientId: 'voter1'};
const nextState = reducer(initialState, action);

expect(nextState).to.equal(fromJS({
vote: {
round: 1,
pair: ['Trainspotting', '28 Days Later'],
tally: {Trainspotting: 1}
tally: {Trainspotting: 1},
votes: {
voter1: 'Trainspotting'
}
},
entries: []
}));
Expand All @@ -64,9 +67,9 @@ describe('reducer', () => {
const actions = [
{type: 'SET_ENTRIES', entries: ['Trainspotting', '28 Days Later']},
{type: 'NEXT'},
{type: 'VOTE', entry: 'Trainspotting'},
{type: 'VOTE', entry: '28 Days Later'},
{type: 'VOTE', entry: 'Trainspotting'},
{type: 'VOTE', entry: 'Trainspotting', clientId: 'voter1'},
{type: 'VOTE', entry: '28 Days Later', clientId: 'voter2'},
{type: 'VOTE', entry: 'Trainspotting', clientId: 'voter3'},
{type: 'NEXT'}
];
const finalState = actions.reduce(reducer, Map());
Expand Down

1 comment on commit 3371786

@mark-stephenson-
Copy link

Choose a reason for hiding this comment

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

I'm missing something here, but I cant see what. Can you point me in the right direction please?
If I copy and paste your test for the same assertion I get the same error.

  1. application logic
    vote
    ignores the vote if for an invalid entry:

    AssertionError: expected 'Map { "round": 1, "pair": List [ "Trainspotting", "28 Days Later" ], "tally": Map { "Sunshine": 1 }, "votes": Map { undefined: "Sunshine" } }' to equal 'Map { "round": 1, "pair": List [ "Trainspotting", "28 Days Later" ] }'

    • expected - actual

    -Map { "round": 1, "pair": List [ "Trainspotting", "28 Days Later" ], "tally": Map { "Sunshine": 1 }, "votes": Map { undefined: "Sunshine" } }
    +Map { "round": 1, "pair": List [ "Trainspotting", "28 Days Later" ] }

Please sign in to comment.