Skip to content

Commit 7013e5e

Browse files
Fix the tests and upgrade the code for Vercel
1 parent 08755ee commit 7013e5e

14 files changed

Lines changed: 977 additions & 1026 deletions

docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ services:
77
- ./:/app
88
working_dir: /app
99
environment:
10-
- DATABASE_URL=postgresql://postgres:toor@db:5432/plus
10+
- DATABASE_URL=postgresql://postgres:KXiT2gMAp3CYiiqL@db.kxeqrvcoztnvjgtgjnig.supabase.co:5432/postgres
1111
- SLACK_VERIFICATION_TOKEN=xxxxxxxxxxxxxxxxxxxxxxx1
1212
- SLACK_BOT_USER_OAUTH_ACCESS_TOKEN=
1313
- YARN_PRODUCTION=true

index.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@
99

1010
'use strict';
1111

12-
const app = require( './src/app' ),
13-
slack = require( './src/slack' );
14-
15-
const fs = require( 'fs' ),
16-
mime = require( 'mime' ),
17-
express = require( 'express' ),
18-
bodyParser = require( 'body-parser' ),
19-
slackClient = require( '@slack/client' );
12+
import app from './src/app.js';
13+
import slack from './src/slack.js';
14+
import express from 'express';
15+
import fs from 'fs';
16+
import mime from 'mime';
17+
import bodyParser from 'body-parser';
18+
import slackClient from '@slack/client';
19+
import { fileURLToPath } from 'url';
2020

2121
/* eslint-disable no-process-env, no-magic-numbers */
2222
const PORT = process.env.PORT || 80; // Let Heroku set the port.
@@ -64,8 +64,8 @@ const bootstrap = ( options = {}) => {
6464
}; // Bootstrap.
6565

6666
// If module was called directly, bootstrap now.
67-
if ( require.main === module ) {
67+
if (process.argv[1] === fileURLToPath(import.meta.url)) {
6868
bootstrap();
6969
}
7070

71-
module.exports = bootstrap;
71+
export default bootstrap;

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"name": "working-plusplus",
3+
"type": "module",
34
"version": "0.0.5",
45
"description": "PHP México PlusPlus bot",
56
"main": "index.js",
@@ -32,6 +33,7 @@
3233
"eslint-config-tdmalone": "^0.1.3",
3334
"eslint-plugin-dollar-sign": "^1.0.1",
3435
"eslint-plugin-jest": "^29.12.1",
36+
"esmock": "^2.7.3",
3537
"jest": "^30.2.0",
3638
"jest-chain": "^1.1.6",
3739
"jest-extended": "^7.0.0",

src/app.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010

1111
'use strict';
1212

13-
const events = require( './events' ),
14-
helpers = require( './helpers' ),
15-
leaderboard = require( './leaderboard' );
13+
import events from './events.js';
14+
import helpers from './helpers.js';
15+
import leaderboard from './leaderboard.js';
1616

1717
// eslint-disable-next-line no-process-env
1818
const SLACK_VERIFICATION_TOKEN = process.env.SLACK_VERIFICATION_TOKEN;
@@ -77,7 +77,7 @@ const validateToken = ( suppliedToken, serverToken ) => {
7777
* @param {express.res} response An Express response. See https://expressjs.com/en/4x/api.html#res.
7878
* @return {void}
7979
*/
80-
const handleGet = async( request, response ) => {
80+
export const handleGet = async( request, response ) => {
8181
logRequest( request );
8282

8383
switch ( request.path.replace( /\/$/, '' ) ) {
@@ -115,7 +115,7 @@ const handleGet = async( request, response ) => {
115115
* @return {bool|Promise} Either `false` if the event cannot be handled, or a Promise as returned
116116
* by `events.handleEvent()`.
117117
*/
118-
const handlePost = ( request, response ) => {
118+
export const handlePost = ( request, response ) => {
119119
logRequest( request );
120120

121121
// Respond to challenge sent by Slack during event subscription set up.
@@ -150,7 +150,7 @@ const handlePost = ( request, response ) => {
150150

151151
}; // HandlePost.
152152

153-
module.exports = {
153+
export default {
154154
logRequest,
155155
validateToken,
156156
handleGet,

src/events.js

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@
77

88
'use strict';
99

10-
const slack = require( './slack' ),
11-
points = require( './points' ),
12-
helpers = require( './helpers' ),
13-
messages = require( './messages' ),
14-
operations = require( './operations' ),
15-
leaderboard = require( './leaderboard' );
10+
import slack from './slack.js';
11+
import points from './points.js';
12+
import helpers from './helpers.js';
13+
import messages from './messages.js';
14+
import operationsPkg from './operations.js';
15+
const { operations } = operationsPkg;
16+
import leaderboard from './leaderboard.js';
1617

17-
const camelCase = require( 'lodash.camelcase' );
18+
import camelCase from 'lodash.camelcase';
1819

1920
/**
2021
* Handles an attempt by a user to 'self plus' themselves, which includes both logging the attempt
@@ -25,7 +26,7 @@ const camelCase = require( 'lodash.camelcase' );
2526
* private channels - aka groups) that the message was sent from.
2627
* @return {Promise} A Promise to send a Slack message back to the requesting channel.
2728
*/
28-
const handleSelfPlus = ( user, channel ) => {
29+
export const handleSelfPlus = ( user, channel ) => {
2930
console.log( user + ' tried to alter their own score.' );
3031
const message = messages.getRandomMessage( operations.operations.SELF, user );
3132
return slack.sendMessage( message, channel );
@@ -42,7 +43,7 @@ const handleSelfPlus = ( user, channel ) => {
4243
* @return {Promise} A Promise to send a Slack message back to the requesting channel after the
4344
* points have been updated.
4445
*/
45-
const handlePlusMinus = async( item, operation, channel ) => {
46+
export const handlePlusMinus = async( item, operation, channel ) => {
4647
const score = await points.updateScore( item, operation ),
4748
operationName = operations.getOperationName( operation ),
4849
message = messages.getRandomMessage( operationName, item, score );
@@ -70,7 +71,7 @@ const handlePlusPlusMinusMinus = async( item, channel ) => {
7071
* https://api.slack.com/events/app_mention for details.
7172
* @returns {Promise} A Promise to send the Slack message.
7273
*/
73-
const sayThankyou = ( event ) => {
74+
export const sayThankyou = ( event ) => {
7475

7576
const thankyouMessages = [
7677
'¡Ni lo menciones!',
@@ -98,7 +99,7 @@ const sayThankyou = ( event ) => {
9899
* https://api.slack.com/events/app_mention for details.
99100
* @returns {Promise} A Promise to send the Slack message.
100101
*/
101-
const sendHelp = ( event ) => {
102+
export const sendHelp = ( event ) => {
102103

103104
const botUserID = helpers.extractUserID( event.text );
104105

@@ -118,7 +119,7 @@ const sendHelp = ( event ) => {
118119

119120
}; // SendHelp.
120121

121-
const handlers = {
122+
export const handlers = {
122123

123124
/**
124125
* Handles standard incoming 'message' events sent from Slack.
@@ -206,7 +207,7 @@ const handlers = {
206207
* @return {bool|Promise} Either `false` if the event cannot be handled, or a Promise as returned
207208
* by the event's handler function.
208209
*/
209-
const handleEvent = ( event, request ) => {
210+
export const handleEvent = ( event, request ) => {
210211

211212
// If the event has no type, something has gone wrong.
212213
if ( 'undefined' === typeof event.type ) {
@@ -241,7 +242,7 @@ const handleEvent = ( event, request ) => {
241242

242243
}; // HandleEvent.
243244

244-
module.exports = {
245+
export default {
245246
handleSelfPlus,
246247
handlePlusMinus,
247248
sayThankyou,

src/helpers.js

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66

77
'use strict';
88

9-
const slack = require( './slack' );
9+
import slack from './slack.js';
1010

11-
const fs = require( 'fs' ),
12-
crypto = require( 'crypto' ),
13-
handlebars = require( 'handlebars' );
11+
import fs from 'fs';
12+
import crypto from 'crypto';
13+
import handlebars from 'handlebars';
1414

1515
const templates = {};
1616

@@ -33,7 +33,7 @@ const ONE_DAY = 60 * 60 * 24, // eslint-disable-line no-magic-numbers
3333
* @param {array} commands The commands to look for.
3434
* @return {string|Boolean} Either the first command found, or false if no commands were found.
3535
*/
36-
const extractCommand = ( message, commands ) => {
36+
export const extractCommand = ( message, commands ) => {
3737

3838
let firstLocation = Number.MAX_SAFE_INTEGER,
3939
firstCommand;
@@ -60,7 +60,7 @@ const extractCommand = ( message, commands ) => {
6060
* 'operation' being done on it - expressed as a valid mathematical operation
6161
* (i.e. + or -).
6262
*/
63-
const extractPlusMinusEventData = ( text ) => {
63+
export const extractPlusMinusEventData = ( text ) => {
6464
const data = text.match( /@([A-Za-z0-9]+?)>?\s*(-{2}\+{2}|\+{2}-{2}|\+{2}|-{2}|{1})/ );
6565

6666
if ( ! data ) {
@@ -97,7 +97,7 @@ const extractPlusMinusEventData = ( text ) => {
9797
* could not be found.
9898
* @see ::isUser
9999
*/
100-
const extractUserID = ( text ) => {
100+
export const extractUserID = ( text ) => {
101101
const match = text.match( /U[A-Z0-9]{8}/ );
102102
return match ? match[0] : '';
103103
};
@@ -108,7 +108,7 @@ const extractUserID = ( text ) => {
108108
* @param {string} ts A timestamp to hash into the token.
109109
* @returns {string} A token, that can be re-checked later using the same timestamp.
110110
*/
111-
const getTimeBasedToken = ( ts ) => {
111+
export const getTimeBasedToken = ( ts ) => {
112112

113113
if ( ! ts ) {
114114
throw Error( 'Timestamp not provided when getting time-based token.' );
@@ -125,7 +125,7 @@ const getTimeBasedToken = ( ts ) => {
125125
*
126126
* @returns {integer} The current Unix timestamp.
127127
*/
128-
const getTimestamp = () => {
128+
export const getTimestamp = () => {
129129
return Math.floor( Date.now() / MILLISECONDS_TO_SECONDS );
130130
};
131131

@@ -135,7 +135,7 @@ const getTimestamp = () => {
135135
* @param {integer} number The number in question.
136136
* @returns {Boolean} Whether or not the number is a plural.
137137
*/
138-
const isPlural = ( number ) => {
138+
export const isPlural = ( number ) => {
139139
return 1 !== Math.abs( number );
140140
};
141141

@@ -147,7 +147,7 @@ const isPlural = ( number ) => {
147147
* @param {integer} ts The timestamp the token was supplied with.
148148
* @returns {boolean} Whether or not the token is valid.
149149
*/
150-
const isTimeBasedTokenStillValid = ( token, ts ) => {
150+
export const isTimeBasedTokenStillValid = ( token, ts ) => {
151151
const now = getTimestamp();
152152

153153
// Don't support tokens too far from the past.
@@ -176,7 +176,7 @@ const isTimeBasedTokenStillValid = ( token, ts ) => {
176176
* @returns {Boolean} Whether or not the string is a Slack user ID.
177177
* @see ::extractUserID()
178178
*/
179-
const isUser = ( item ) => {
179+
export const isUser = ( item ) => {
180180
return item.match( /U[A-Z0-9]{8}/ ) ? true : false;
181181
};
182182

@@ -188,7 +188,7 @@ const isUser = ( item ) => {
188188
* @return {string} The item linked with Slack mrkdwn
189189
* @see https://api.slack.com/docs/message-formatting#linking_to_channels_and_users
190190
*/
191-
const maybeLinkItem = ( item ) => {
191+
export const maybeLinkItem = ( item ) => {
192192
return isUser( item ) ? '<@' + item + '>' : item;
193193
};
194194

@@ -200,7 +200,7 @@ const maybeLinkItem = ( item ) => {
200200
* @return {int} item
201201
* The id.
202202
*/
203-
const returnAsId = ( item ) => {
203+
export const returnAsId = ( item ) => {
204204
return item;
205205
};
206206

@@ -222,7 +222,7 @@ const returnAsId = ( item ) => {
222222
* @returns {string} HTML ready to be rendered in the browser.
223223
* @see https://handlebarsjs.com/
224224
*/
225-
const render = async( templatePath, context = {}, request = {}) => {
225+
export const render = async( templatePath, context = {}, request = {}) => {
226226

227227
// Retrieve the header and footer HTML, if we don't already have it in memory.
228228
if ( ! templates.header ) templates.header = fs.readFileSync( 'src/html/header.html', 'utf8' );
@@ -249,7 +249,7 @@ const render = async( templatePath, context = {}, request = {}) => {
249249

250250
}; // Render.
251251

252-
module.exports = {
252+
export default {
253253
extractCommand,
254254
extractPlusMinusEventData,
255255
extractUserID,

src/leaderboard.js

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66

77
'use strict';
88

9-
const slack = require( './slack' ),
10-
points = require( './points' ),
11-
helpers = require( './helpers' );
9+
import slack from './slack.js';
10+
import points from './points.js';
11+
import helpers from './helpers.js';
1212

13-
const querystring = require( 'querystring' );
13+
import querystring from 'querystring';
1414

1515
/**
1616
* Gets the URL for the full leaderboard, including a token to ensure that it is only viewed by
@@ -19,7 +19,7 @@ const querystring = require( 'querystring' );
1919
* @param {object} request The Express request object that resulted in this handler being run.
2020
* @returns {string} The leaderboard URL, which will be picked up in ../index.js when called.
2121
*/
22-
const getLeaderboardUrl = ( request ) => {
22+
export const getLeaderboardUrl = ( request ) => {
2323

2424
const hostname = request.headers.host,
2525
ts = helpers.getTimestamp();
@@ -54,7 +54,7 @@ const getLeaderboardUrl = ( request ) => {
5454
* format is 'slack') or objects containing 'rank', 'item' and 'score' values (if
5555
* format is 'object').
5656
*/
57-
const rankItems = async( topScores, itemType = 'users', format = 'slack' ) => {
57+
export const rankItems = async( topScores, itemType = 'users', format = 'slack' ) => {
5858

5959
let lastScore, lastRank, output;
6060
const items = [];
@@ -145,7 +145,7 @@ const rankItems = async( topScores, itemType = 'users', format = 'slack' ) => {
145145
* @param {object} request The Express request object that resulted in this handler being run.
146146
* @returns {Promise} A Promise to send the Slack message.
147147
*/
148-
const getForSlack = async( event, request ) => {
148+
export const getForSlack = async( event, request ) => {
149149

150150
const limit = 5;
151151

@@ -190,7 +190,7 @@ const getForSlack = async( event, request ) => {
190190
* @param {object} request The Express request object that resulted in this handler being run.
191191
* @returns {string} HTML for the browser.
192192
*/
193-
const getForWeb = async( request ) => {
193+
export const getForWeb = async( request ) => {
194194

195195
const scores = await points.retrieveTopScores(),
196196
users = await rankItems( scores, 'users', 'object' ),
@@ -211,7 +211,7 @@ const getForWeb = async( request ) => {
211211
* @returns {Promise<{things: *, users: *}>}
212212
* Data with top users.
213213
*/
214-
const getForAPI = async() => {
214+
export const getForAPI = async() => {
215215

216216
const scores = await points.retrieveTopScores(),
217217
users = await rankItems( scores, 'users', 'object' );
@@ -232,11 +232,11 @@ const getForAPI = async() => {
232232
* @param {*} request See the documentation for getForSlack.
233233
* @returns {*} See the documentation for getForSlack.
234234
*/
235-
const handler = async( event, request ) => {
235+
export const handler = async( event, request ) => {
236236
return getForSlack( event, request );
237237
};
238238

239-
module.exports = {
239+
export default {
240240
getLeaderboardUrl,
241241
rankItems,
242242
getForSlack,

0 commit comments

Comments
 (0)