Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 00b7df8

Browse files
committed
inject fs data for testing
1 parent d6596ca commit 00b7df8

File tree

4 files changed

+165
-81
lines changed

4 files changed

+165
-81
lines changed

handler.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
'use strict'
22

33
const reload = require('./reloader')
4-
4+
const fs = require('fs'
5+
)
56
function roomName(message) {
67
return message.room() ? message.room().topic() : 'self'
78
}
@@ -31,14 +32,22 @@ function destination(message) {
3132
return message.room() ? message.room() : message.from()
3233
}
3334

35+
function isValidRoom(config, currentRoomName) {
36+
return config.whitelisted.indexOf(currentRoomName) != -1 ||
37+
currentRoomName.toLowerCase().indexOf(config.prefix.toLowerCase()) != -1
38+
}
39+
3440
function handler(config, data, message) {
3541
if(mine(content(message), config.prefix) &&
36-
config.whitelisted.indexOf(roomName(message)) != -1) {
42+
isValidRoom(config, roomName(message))) {
3743
const processor = reload(config.processor)
3844
if(!(data.tickets instanceof Object)) {
3945
data.tickets = processor.load(config.store)
4046
}
41-
const reply = processor.process(data.tickets, {
47+
if(!data.fs) {
48+
data.fs = fs
49+
}
50+
const reply = processor.process(data, {
4251
content: cleanContent(config.prefix, message),
4352
prefix: config.prefix,
4453
roomName: roomName(message),

support.js

Lines changed: 54 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
const fs = require('fs')
44
const path = require('path')
5+
const assert = require('assert')
56

67
function TicketError(message) {
78
this.name = 'TicketError';
@@ -25,80 +26,83 @@ const Sample = {
2526

2627
const actions = [
2728
{
28-
action: (_tickets, _message) => 'DEFAULT ACTION',
29+
action: (_data, _message) => 'DEFAULT ACTION',
2930
regexp: /^$/i,
3031
reply: (message, _output) => `Yes ${message.userName}?`,
3132
},
3233
{
33-
action: (_tickets, _message) => help(),
34+
action: (_data, _message) => help(),
3435
regexp: /help/i,
3536
reply: (message, output) => `\n${output}`,
3637
},
3738
{
38-
action: (tickets, _message, id) => closeTicket(tickets, id),
39+
action: (data, _message, id) => closeTicket(data.tickets, id),
3940
regexp: /close #?([0-9]*)/i,
4041
reply: (message, output) => `ticket #${output.id} is closed`,
4142
},
4243
{
43-
action: (tickets, message, content) =>
44-
openTicket(tickets, message, content),
44+
action: (data, message, content) =>
45+
openTicket(data.tickets, message, content),
4546
regexp: /please (.*)/i,
4647
reply: (message, output) => `will ${output.content} (ticket #${output.id})`,
4748
},
4849
{
49-
action: (tickets, _message, id) => findTicket(tickets, id),
50+
action: (data, _message, id) => findTicket(data.tickets, id),
5051
regexp: /show #?([0-9]*)/i,
5152
reply: (message, output) => showTicket(output),
5253
},
5354
{
5455
/* eslint-disable max-params */
55-
action: (tickets, _m, id, comment) => [findTicket(tickets, id), comment],
56+
action: (data, _m, id, comment) => [findTicket(data.tickets, id), comment],
5657
regexp: /ticket #?([0-9]*) (.*)$/i,
5758
reply: (message, output) => addComment(output[0], output[1]),
5859
},
5960
{
60-
action: (tickets, message, id) => assign(tickets, id, message.userName),
61+
action: (data, message, id) => assign(data.tickets, id, message.userName),
6162
regexp: /take #?([0-9]*)/i,
6263
reply: (message, output) => `ticket #${output.id} is assigned to ${output.assignee}`,
6364
},
6465
{
6566
/* eslint-disable max-params */
66-
action: (tickets, _message, id, assignee) => assign(tickets, id, assignee),
67+
action: (data, _message, id, assignee) =>
68+
assign(data.tickets, id, assignee),
6769
regexp: /assign #?([0-9]*) to (\w*)/i,
6870
reply: (message, output) => `ticket #${output.id} is assigned to ${output.assignee}`,
6971
},
7072
{
71-
action: (tickets, _message) => tickets,
73+
action: (data, _message) => data.tickets,
7274
regexp: /debug/i,
7375
reply: (message, output) => JSON.stringify(output, null, 4),
7476
},
7577
{
76-
action: (tickets, _message, username) => [tickets, username.toLowerCase()],
78+
action: (data, _message, username) => [
79+
data.tickets, username.toLowerCase()
80+
],
7781
regexp: /todo ?(\w*)/i,
7882
reply: (message, output) => showTickets(output[0], ['open'], output[1]),
7983
},
8084
{
81-
action: (tickets, _message) => tickets,
85+
action: (data, _message) => data.tickets,
8286
regexp: /mine/i,
8387
reply: (message, output) => showTickets(output, ['open'], message.userName),
8488
},
8589
{
86-
action: (tickets, _message) => tickets,
90+
action: (data, _message) => data.tickets,
8791
regexp: /history/i,
8892
reply: (message, output) => showTickets(output, ['open', 'closed']),
8993
},
9094
{
91-
action: (tickets, _message) => forget(tickets),
95+
action: (data, _message) => forget(data.tickets),
9296
regexp: /forget it/i,
9397
reply: (message, output) => `deleted ${output} tickets`,
9498
},
9599
{
96-
action: (tickets, _message, type) => gimme(type),
100+
action: (data, _message, type) => gimme(data.fs, type),
97101
regexp: /gimme\s*a*n*\s*(\w*)/i,
98102
reply: (message, output) => `${message.userName} ${output[0].toLowerCase()}${output.substr(1)}`,
99103
},
100104
{
101-
action: (tickets, _message, type) => listType(type),
105+
action: (data, _message, type) => listType(data.fs, type),
102106
regexp: /what\s*(\w*) (you)? (got)?\??/i,
103107
reply: (message, output) => `${output.join('\n')}`,
104108
},
@@ -204,11 +208,6 @@ function help() {
204208
return actions.map((action) => `${action.regexp.toString()}`).join('\n')
205209
}
206210

207-
function getRandomInt(min, max) {
208-
const range = max - min + 1 + min
209-
return Math.floor(Math.random() * range);
210-
}
211-
212211
function addComment(ticket, comment) {
213212
if(!(ticket.comments instanceof Array)) {
214213
ticket.comments = []
@@ -218,20 +217,22 @@ function addComment(ticket, comment) {
218217
}
219218
var sources = {}
220219

221-
function gimme(type) {
222-
const saying = listType(type)[getRandomInt(0, sources[type].length)]
223-
return saying
220+
function gimme(injectedFs, type) {
221+
const typeList = listType(injectedFs, type)
222+
const randomIndex = Math.floor(Math.random() * sources[type].length)
223+
const result = typeList[randomIndex]
224+
return result
224225
}
225226

226-
function listType(type) {
227+
function listType(injectedFs, type) {
227228
const typePath = path.basename(`${type}.txt`)
228229
/* eslint-disable no-sync */
229-
if(!fs.existsSync(typePath)) {
230+
if(!injectedFs.existsSync(typePath)) {
230231
throw new TicketError(`I don't know how to give you ${type}!`)
231232
}
232233
if(!sources[type]) {
233234
/* eslint-disable no-sync */
234-
const content = fs.readFileSync(typePath)
235+
const content = injectedFs.readFileSync(typePath)
235236
sources[type] = content.toString().split('\n')
236237
}
237238
return sources[type]
@@ -254,7 +255,9 @@ function searchRegexp(action) {
254255
return false
255256
}
256257

257-
function process(tickets, message) {
258+
function process(data, message) {
259+
assert(isValidTickets(data.tickets),
260+
`Expecting valid tickets data key, got: ${JSON.stringify(data.tickets)}`)
258261
const findParams = {
259262
content: message.content,
260263
result: null
@@ -264,7 +267,7 @@ function process(tickets, message) {
264267
var reply;
265268
if(action) {
266269
try {
267-
var output = action.action(tickets, message, ...findParams.result)
270+
var output = action.action(data, message, ...findParams.result)
268271
reply = `${action.reply.bind(output)(message, output)}`
269272
} catch(e) {
270273
if(e instanceof TicketError) {
@@ -284,7 +287,23 @@ function createTickets() {
284287
}
285288
}
286289

290+
function isValidTickets(tickets) {
291+
if(!tickets) {
292+
return false
293+
}
294+
if(!(tickets instanceof Object)) {
295+
return false
296+
}
297+
if(!Number.isInteger(tickets.lastId)) {
298+
return false
299+
}
300+
return true
301+
}
302+
287303
function store(storePath, tickets) {
304+
if(!isValidTickets(tickets)) {
305+
throw new TicketError(`refusing to write invalid data: ${JSON.stringify(tickets)}`)
306+
}
288307
/* eslint-disable no-sync */
289308
fs.writeFileSync(storePath, JSON.stringify(tickets, null, 4))
290309
}
@@ -295,7 +314,11 @@ function load(storePath) {
295314
/* eslint-disable no-sync */
296315
const datastore = fs.readFileSync(storePath).toString()
297316
try {
298-
return JSON.parse(datastore)
317+
const tickets = JSON.parse(datastore)
318+
if(!isValidTickets(tickets)) {
319+
throw new TicketError(`does not contain valid data: ${storePath}`)
320+
}
321+
return tickets
299322
} catch(e) {
300323
if(e instanceof SyntaxError) {
301324
throw new TicketError(`invalid content of file: ${storePath}`)
@@ -310,6 +333,7 @@ function load(storePath) {
310333
module.exports = {
311334
TicketError,
312335
createTickets,
336+
isValidTickets,
313337
load,
314338
openTicket,
315339
process,

test/handler_test.js

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,19 @@ const config = {
3232
],
3333
}
3434

35+
var sayValue = null
36+
function say(msg) {
37+
sayValue = msg
38+
}
3539

3640
describe('handler', function() {
41+
beforeEach(function () {
42+
sayValue = null
43+
})
44+
3745
it('handles multiple class and storage', function() {
38-
const data = {}
39-
var sayValue = null
40-
function say(msg) {
41-
sayValue = msg
42-
}
46+
const data = {tickets: {lastId: 0}}
47+
4348
const message = createWeChatyMessage(
4449
'Ricky',
4550
'test room',
@@ -57,4 +62,25 @@ describe('handler', function() {
5762
assert.equal(data.tickets.lastId, 2)
5863
assert.instanceOf(data.tickets['2'], Object)
5964
})
65+
66+
it('non-whitelisted room is ignored', function() {
67+
const message = createWeChatyMessage(
68+
'Ricky',
69+
'no valid test room',
70+
'cando please add ticket',
71+
() => {
72+
throw new Error('should not be called')
73+
})
74+
handler(config, {tickets: {lastId: 0}}, message)
75+
})
76+
77+
it('room with prefix in name is accepted', function() {
78+
const message = createWeChatyMessage(
79+
'Ricky',
80+
'CANDO testing',
81+
'cando please add ticket',
82+
say)
83+
handler(config, {tickets: {lastId: 0}}, message)
84+
assert.equal(sayValue, '#cando: will add ticket (ticket #1)')
85+
})
6086
})

0 commit comments

Comments
 (0)