Skip to content

Commit

Permalink
Allow specifying whether person of colour by DM
Browse files Browse the repository at this point in the history
Progress toward #6
  • Loading branch information
backspace committed Feb 9, 2015
1 parent 72e1563 commit c980165
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 10 deletions.
34 changes: 27 additions & 7 deletions src/direct-message-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Also should maybe just return a reply which the bot actually sends?

var GenderUpdateParser = require('./gender-update-parser');
var RaceUpdateParser = require('./race-update-parser');

class DirectMessageHandler {
constructor(userRepository) {
Expand Down Expand Up @@ -66,21 +67,40 @@ class DirectMessageHandler {
}

handleInformationUpdate(channel, message) {
var parser = new GenderUpdateParser(message.text);
var isMan = parser.parseIsMan();

var reply;
var genderParser = new GenderUpdateParser(message.text);
var isMan = new GenderUpdateParser(message.text).parseIsMan();
var isPersonOfColour = new RaceUpdateParser(message.text).parseIsPersonOfColour();

if (isMan !== undefined) {
this.userRepository.storeAttribute(message.user, 'isMan', isMan);
this.handleGenderUpdate(channel, message.user, isMan);
} else if (isPersonOfColour !== undefined) {
this.handleRaceUpdate(channel, message.user, isPersonOfColour);
} else {
channel.send(`I’m sorry, I’m not that advanced and I didn’t understand your message. ${DirectMessageHandler.HELP_MESSAGE}`);
}
}

handleGenderUpdate(channel, userID, isMan) {
var reply;
this.userRepository.storeAttribute(userID, 'isMan', isMan);

if (isMan === true) {
reply = 'Okay, we have noted that you are a man. If I got it wrong, try saying “I am *not* a man!”';
} else if (isMan === false) {
reply = 'Okay, we have noted that you are not a man. If I got it wrong, try saying “I am a man”.';
} else {
reply = `I’m sorry, I’m not that advanced and I didn’t understand your message. ${DirectMessageHandler.HELP_MESSAGE}`;
}

channel.send(reply);
}

handleRaceUpdate(channel, userID, isPersonOfColour) {
var reply;
this.userRepository.storeAttribute(userID, 'isPersonOfColour', isPersonOfColour);

if (isPersonOfColour === true) {
reply = 'We have noted that you are a person of colour. If I got it wrong, try saying “I am not a person of colour”';
} else if (isPersonOfColour === false) {
reply = 'We have noted that you are not a person of colour. If I got it wrong, try saying “I am a person of colour”';
}

channel.send(reply);
Expand Down
35 changes: 35 additions & 0 deletions src/race-update-parser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
class RaceUpdateParser {
constructor(message) {
this.message = message.toLowerCase();
}

parseIsPersonOfColour() {
if (this.matchesPersonOfColourPatterns()) {
return true;
} else if (this.matchesNotPersonOfColourPatterns()) {
return false;
} else {
return undefined;
}
}

matchesPersonOfColourPatterns() {
if ((this.message.match(/person of colou?r/) && !this.message.match(/not/)) ||
(this.message.match(/white/) && this.message.match(/not/))) {
return true;
} else {
return false;
}
}

matchesNotPersonOfColourPatterns() {
if ((this.message.match(/person of colou?r/) && this.message.match(/not/)) ||
(this.message.match(/white/) && !this.message.match(/not/))) {
return true;
} else {
return false;
}
}
}

module.exports = RaceUpdateParser;
42 changes: 42 additions & 0 deletions test/direct-message-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,48 @@ test('DirectMessageHandler updates whether or not the user is a man', function(t
t.end();
});

test('DirectMessageHandler updates whether the user is a person of colour', function(t) {
// TODO reduce setup boilerplate
// but this is all too acceptance-like and redundant and should just test
// that the parsers are called and their results are used
var handler = new DirectMessageHandler(fakeUserRepository);

var chris = {id: 'C', name: 'Chris', isPersonOfColour: true, message: 'i am a person of colour'};
var chrisDM = {send: sinon.stub()};

var david = {id: 'D', name: 'David', isPersonOfColour: false, message: 'I am white'};
var davidDM = {send: sinon.stub()};

var unknown = {id: 'U', name: 'Unknown', isMan: 'what is this'};
var unknownDM = {send: sinon.stub()};

var personIDToChannel = {};
personIDToChannel[chris.id] = chrisDM;
personIDToChannel[david.id] = davidDM;
personIDToChannel[unknown.id] = unknownDM;

var storeAttributeStub = sinon.stub(fakeUserRepository, 'storeAttribute');

[chris, david, unknown].forEach(function(person) {
handler.handle(personIDToChannel[person.id], {
text: `${person.message}`,
user: person.id
});
});

t.ok(chrisDM.send.calledWithMatch(/you are a person of colour/), 'replies affirming that Chris is a person of colour');
t.ok(storeAttributeStub.calledWith(chris.id, 'isPersonOfColour', true), 'stores that Chris is a person of colour');

t.ok(davidDM.send.calledWithMatch(/you are not a person of colour/), 'replies affirming that David is not a person of colour');
t.ok(storeAttributeStub.calledWith(david.id, 'isPersonOfColour', false), 'stores that David is not a person of colour');

t.ok(unknownDM.send.calledWithMatch(/I’m sorry, I’m not that advanced and I didn’t understand your message./), 'replies that it didn’t understand the message');
t.ok(storeAttributeStub.neverCalledWith(unknown.id), 'does not store anything about Unknown');

storeAttributeStub.restore();
t.end();
});

test('DirectMessageHandler handles an information request', function(t) {
var handler = new DirectMessageHandler(fakeUserRepository);

Expand Down
25 changes: 25 additions & 0 deletions test/race-update-parser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/env iojs --es_staging --use-strict

var test = require('tape');

var RaceUpdateParser = require('../src/race-update-parser');

test('RaceUpdateParser parses whether or not someone is a person of colour', function(t) {
var inputToResponse = {
'i am a Person of Colour': true,
'person of color': true,
'i am not a person of color': false,
'i am white': false,
'i am not white': true,
'anything': undefined
};

Object.keys(inputToResponse).forEach(function(input) {
var parser = new RaceUpdateParser(input);
var response = parser.parseIsPersonOfColour();

t.equal(response, inputToResponse[input], `${input} should represent isPersonOfColour ${inputToResponse[input]} but response was ${response}`);
});

t.end();
});
22 changes: 19 additions & 3 deletions test/statsbot.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,9 +258,7 @@ test('StatsBot asks the top two unknowns in a reporting period who have not decl
});
});

test('StatsBot records a user\'s gender', function(t) {
t.plan(4);

test('StatsBot records a user\'s gender and race', function(t) {
var adapter = new SlackAdapter(fakeClient);
var bot = new StatsBot(adapter, fakeUserRepository);

Expand Down Expand Up @@ -289,6 +287,14 @@ test('StatsBot records a user\'s gender', function(t) {
t.ok(prakashDM.send.calledWithMatch(/Okay, we have noted that you are a man./), 'replies affirming that Prakash is a man');
t.ok(storeAttributeStub.calledWith('P', 'isMan', true), 'stores that Prakash is a man');

bot.handleDirectMessage(prakashDM, {
text: 'i am a person of colour',
user: prakash.id
});

t.ok(prakashDM.send.calledWithMatch(/you are a person of colour/), 'replies affirming that Prakash is a person of colour');
t.ok(storeAttributeStub.calledWith('P', 'isPersonOfColour', true), 'stores that Prakash is a person of colour');

bot.handleDirectMessage(lauraDM, {
text: 'false',
user: laura.id
Expand All @@ -297,9 +303,19 @@ test('StatsBot records a user\'s gender', function(t) {
t.ok(lauraDM.send.calledWithMatch(/Okay, we have noted that you are not a man./), 'replies affirming that Laura is not a man');
t.ok(storeAttributeStub.calledWith('L', 'isMan', false), 'stores that Laura is not a man');

bot.handleDirectMessage(lauraDM, {
text: 'i am white',
user: laura.id
});

t.ok(lauraDM.send.calledWithMatch(/you are not a person of colour/), 'replies affirming that Laura is not a person of colour');
t.ok(storeAttributeStub.calledWith('L', 'isPersonOfColour', false), 'stores that Laura is not a person of colour');

userStub.restore();
channelByIDStub.restore();
storeAttributeStub.restore();

t.end();
});

test('StatsBot responds with a user\'s information when they ask', function(t) {
Expand Down

0 comments on commit c980165

Please sign in to comment.