Skip to content
This repository was archived by the owner on Dec 10, 2022. It is now read-only.

Commit efe2224

Browse files
committed
Merge branch 'dev'
* dev: (60 commits) Test cleanups incl. proper naming Clean up the custom test runner Complete app.js tests Minor simplification of eslint config WIP: Reorganise app.js to make it easier to maintain and easier to test Clean up and complete all currently remaining tests WIP: A bunch of Slack message tests Minor tweaks Improve test runner to handle user IDs + only make a DB connection if required devDeps: Add jest-chain for cleaner tests Minor: make tests more maintainable by just checking that assertions exist Make eslint output a little cleaner More Travis tweakin Try upgrading Travis Slack integration for .com endpoint Further Travis postgres tweaks It usually helps to use the correct filename Docs & CI: mention min. Postgres version & upgrade in Travis Restructure some tests, adding e2e tests + implementing some Slack test TODOs Construct test runner for end-to-end tests Complete Postgres tests ...
2 parents 776e2eb + 8c9f3ae commit efe2224

22 files changed

+1783
-407
lines changed

.eslintrc.js

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,68 @@
1+
/**
2+
* Custom ESLint configuration.
3+
*
4+
* @see https://eslint.org/docs/user-guide/configuring
5+
* @see https://eslint.org/docs/rules/
6+
*/
17

28
'use strict';
39

410
module.exports = {
511

612
env: {
713
browser: false,
8-
node: true
14+
node: true
915
},
1016

11-
extends: [ 'tdmalone' ],
17+
extends: [
18+
'tdmalone' // @see https://github.com/tdmalone/eslint-config-tdmalone/blob/master/index.js
19+
],
1220

1321
parserOptions: {
14-
ecmaVersion: 8
22+
ecmaVersion: 9 // Aka ES2018. @see https://node.green/#ES2018
1523
},
1624

1725
rules: {
18-
'max-statements': [ 'error', { max: 75 } ],
19-
'no-magic-numbers': [ 'error', {
20-
ignore: [
21-
-1,
22-
0,
23-
1
24-
],
25-
ignoreArrayIndexes: true,
26-
enforceConst: true
27-
} ],
28-
'no-multi-str': [ 'off' ]
29-
}
30-
31-
};
26+
27+
'array-bracket-newline': [ 'error', 'consistent' ],
28+
'array-element-newline': [ 'error', 'consistent' ],
29+
30+
'object-curly-newline': [
31+
'error',
32+
{
33+
minProperties: 3,
34+
multiline: true,
35+
consistent: true
36+
}
37+
],
38+
39+
'key-spacing': [
40+
'warn',
41+
{
42+
beforeColon: false,
43+
afterColon: true,
44+
mode: 'strict'
45+
}
46+
],
47+
48+
'max-statements': [ 'error', { max: 20 } ],
49+
50+
'no-magic-numbers': [
51+
'error',
52+
{
53+
ignore: [
54+
-1,
55+
0,
56+
1
57+
],
58+
ignoreArrayIndexes: true,
59+
enforceConst: true
60+
}
61+
],
62+
63+
'no-multi-str': [ 'off' ],
64+
'no-var': [ 'error' ],
65+
'prefer-const': [ 'error' ]
66+
67+
} // Rules.
68+
}; // Module.exports.

.travis-postgres10.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Installs PostgreSQL 10 on Travis CI, as the default build images don't support it yet.
4+
#
5+
# @see https://github.com/travis-ci/travis-ci/issues/8537#issuecomment-354020356
6+
7+
set -euxo pipefail
8+
9+
echo "Installing Postgres 10..."
10+
sudo service postgresql stop
11+
sudo apt-get remove --quiet 'postgresql-*'
12+
sudo apt-get update --quiet
13+
sudo apt-get install --quiet postgresql-10 postgresql-client-10
14+
sudo cp /etc/postgresql/{9.6,10}/main/pg_hba.conf
15+
16+
echo "Restarting Postgres 10..."
17+
sudo service postgresql restart
18+
19+
echo "Adding Travis role..."
20+
sudo psql --command="CREATE ROLE travis SUPERUSER LOGIN CREATEDB;" --username="postgres"

.travis.yml

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,42 @@
1+
2+
# Travis CI configuration for Working PlusPlus++
3+
#
4+
# @see https://docs.travis-ci.com/user/languages/javascript-with-nodejs/
5+
# @see https://docs.travis-ci.com/user/database-setup/#postgresql
6+
# @author Tim Malone <[email protected]>
7+
18
language: node_js
29
node_js: 10.8.0
310

11+
services:
12+
- postgresql
13+
14+
# Support upgrading to PostgreSQL 10, as the default build images don't support it yet.
15+
# (We run the install script in before_install below)
16+
# @see https://github.com/travis-ci/travis-ci/issues/8537#issuecomment-354020356
17+
sudo: required
18+
addons:
19+
postgresql: 9.6
20+
421
cache:
522
yarn: true
623
directories:
724
- node_modules
825

9-
# Upgrade Yarn to the version specified in package.json.
1026
before_install:
27+
28+
# Upgrade Yarn to the version specified in package.json.
1129
- curl --location https://yarnpkg.com/install.sh | bash -s -- --version "$( node -e "console.log(require('./package.json').engines.yarn)" )"
1230
- export PATH="$HOME/.yarn/bin:$PATH"
1331

14-
install: yarn
32+
# Upgrade to PostgreSQL 10.
33+
- ./.travis-postgres10.sh
34+
35+
install:
36+
- yarn --frozen-lockfile
37+
38+
before_script:
39+
- psql --command="CREATE DATABASE plusplus_tests;" --username="postgres"
1540

1641
script:
1742
- yarn lint
@@ -24,4 +49,4 @@ notifications:
2449
slack:
2550
on_start: always
2651
rooms:
27-
- secure: UbCK1YGnopRxELn0sxl1Ra7/c4GjAHYb77FRS3mzgOdIzg+C3VyAilIL1SpAS3ue7IGyG+DeTtVa1azC4Xwo9abpk5/wJQxYBFlBoYV2VO9JWgz74L4i/rW00cbFZDozCv1Df3mwq9OUe6S5eXDY4KSR36hod48aZ/PRwHL8uj/VyYku5JA1BI3nyIQx7N7Tn26jzQkC2M74aO4tN3FSwrYyV0805In43+rUKGnb65glJ+nxrW6A6lBsTH9MiIt2xk9FFBuF9ZQUjG0Fu4asOGROqJp4w5b1p7Hf2PVWB773oFQuNIi4H2jEiHO/QUAtmn8i5lCuzLpB1PuGmcQGIpw4GdZE5R0gZ7au0sgqmiNM20v+5L355M0+bK+BfyEKLz+rBIl0mmmWd1rXipErlhsmQRsp1bvMk7pjoeQGgJ4Qrt9NZYqkmBR/629fGsf68maSNR+AFbYzXeOcSq/6VK445QMdw8XygYiQVswS7Kyu3/s2VeaDJOPUORpJ2jehGsj5a1B0jTpPMYXGVMwYRfA5CqT8BqM0BvwvzHtyz/sGHodMr3UIodBWBIyDigP7Pk8gYN0hTsg6rVZ7SkjWgOKxcuwOnRwA36T9KfVfyEcDfbcyROl3fSTn5wNABBrUxaFU12paTlIQlZ4Gveh9W80xN5y9fHXWJb+B80bHbnA=
52+
- secure: efl6ZdfE6OTOK5L2z5m993uultsT5WanZ5sn8EmHPa0ENd2+SKXIIigQ1EqbLm1zExWLMKA3Pq5pbHwndsnWywGkZDXWy2eHoSHk7IEVLLvAceyLUr5h2pBL8wztqWGZDMBo1tHGYddQsyBlCs52AQM04i+XBX4tYiUhub7AAbMQ9cqBIz09fRZ9JBNxM6HzMvj+PmeezXzFxvzgvmVQawGQUvJPaZuf9qcwJN1ZWw0FNkIwg3Aafe809mnQnzYIwmiC9kF+ZJ14BX4qqW7uzbo7Zsf647a8LSm9OI3fWzGdNnScWXv+hkWyfHAj8cz4yI2y5l+F3Muhwylp2wHGzjARJTLQq3HTFWaAnZtpyd82FB8v82qKPaPpKTeLcVkdib/E9XjYsdFdsC33jr5vc0j/oM/bLi9pA0faWwN4kq6Q9k3Ei2u+WnP4G7Fzb1WR7zZoLmT9k4BVOJFLYF++OirE9GPaKTvRMnOaR/RO/rQkOx2FlrtzfoG//NBULycMbEMmrv4/GJ64SHQ7YtnedaEb1NwXi/qTwdDtjXkmAeNRoNayHvLLZKG3GKsUze3VIrieN8qMCTRdXRttQd3hacPYNtoCqcB7ogIMN/Jg7v1g2l2szs/v2waNMJW18Hoj3PD8dDSrH/VXlDjaqCNFxo5/sBeHC6eJtW6EkCgzCY4=

CONTRIBUTING.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Contributing to Working PlusPlus++
2+
3+
Contributions are welcome! [Create an issue](https://github.com/tdmalone/working-plusplus/issues/new) if there's something you'd like to see or [send a pull request](https://github.com/tdmalone/working-plusplus/compare) if you can implement it yourself.
4+
5+
## Installing Locally
6+
7+
To develop locally against a real, working instance, follow most of the *Installation* instructions in the [README](README.md), except **instead of step 5** (deploying to Heroku), clone this repo locally and then install dependencies:
8+
9+
$ git clone https://github.com/tdmalone/working-plusplus
10+
$ cd working-plusplus
11+
$ yarn
12+
13+
You'll need [Node.js](https://nodejs.org/) already installed on your system. In addition, if you don't have [Yarn](https://yarnpkg.com/en/) and don't want it, you can use `npm install` instead of `yarn` above (but you might not get _exactly_ the same dependency versions).
14+
15+
You'll also need a local installation of PostgreSQL (or a server you can utilise) and a clean database you can use. [Here's an easy-to-use Postgres app for Macs](https://postgresapp.com/). Working PlusPlus++ requires at least PostgreSQL 9.5, but 10+ is recommended.
16+
17+
Make the following environment variables accessible to the app:
18+
19+
- **`SLACK_BOT_USER_OAUTH_ACCESS_TOKEN`**: from step 4 of the [installation instructions](README.md)
20+
- **`SLACK_VERIFICATION_TOKEN`**: from step 4 of the [installation instructions](README.md)
21+
- **`DATABASE_URL`**: in the format `postgres://user@localhost:5432/databasename`
22+
23+
Then, run the app:
24+
25+
$ node index.js
26+
27+
Or if you have the [Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli) installed:
28+
29+
$ heroku local
30+
31+
ℹ️ _For more help on using `heroku local`, see the [Heroku Local Dev Center article](https://devcenter.heroku.com/articles/heroku-local)._
32+
33+
If you make changes to the app, press Ctrl+C to exit, and then run it again.
34+
35+
Finally, you'll need to be able to have Slack contact your development instance directly. If you don't have the ability to forward a port through to your machine, I recommend [ngrok](https://ngrok.com/). Download and extract, then in the directory you've extracted it in run:
36+
37+
./ngrok http 80 # Or port 5000 if you're running with heroku local.
38+
39+
ngrok will provide you with the public URL your app is accessible on. This is the URL you'll then need to use in **step 6** of the [installation instructions](README.md).
40+
41+
Other than the modifications to steps 5 and 6, make sure you've followed all the rest of the installation instructions. You should then be set up and ready with a local development instance that you can interact with directly on Slack! If you run into any problems, feel free to [create an issue](https://github.com/tdmalone/working-plusplus/issues/new).
42+
43+
## Linting and Running Tests
44+
45+
This app has an extensive test suite, just because. Before submitting pull requests, please check that your changes pass linting and tests by running `yarn lint` and `yarn test`. These will also be run for you by Travis CI, but it's often quicker to debug and resolve the issues locally.
46+
47+
⚠️ _You will need access to a PostgreSQL server to run the integration and end-to-end tests. If you don't, just run the unit tests (see below) and let Travis CI run the full test suite for you._
48+
49+
ℹ️ _If you don't have Yarn, you can replace any mention of `yarn` in this section with `npm run`._
50+
51+
You can run just a subset of tests:
52+
- Unit tests with `yarn unit-tests`
53+
- Integration tests with `yarn integration-tests`
54+
- End-to-end tests with `yarn e2e-tests`
55+
56+
It is normal to see _some_ errors while running the integration and end-to-end tests, but keep an eye on the exit code of the process to determine if it is successful (run `echo $?` immediately after running `yarn test` - you're looking for an exit code of `0` for a pass).
57+
58+
You can modify the default testing behaviour by adjusting the relevant `scripts` in [`package.json`](package.json) or in some cases by passing additional [Jest configuration parameters](https://jestjs.io/docs/en/configuration.html) at the end of the test commands above.
59+
60+
If you come across annoying *stylistic* linting rules, feel free to [change them](https://eslint.org/docs/rules/) in [`.eslintrc.js`](.eslintrc.js) as part of your pull request, providing they don't cause an adverse effect on existing code.
61+
62+
Many linting issues can be automatically fixed by running `yarn fix`.

README.md

Lines changed: 4 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -76,45 +76,9 @@ Further instructions, such as hosting elsewhere, upgrading, etc. are coming soon
7676

7777
## Contributing
7878

79-
Contributions are welcome! [Create an issue](https://github.com/tdmalone/working-plusplus/issues/new) if there's something you'd like to see or [send a pull request](https://github.com/tdmalone/working-plusplus/compare) if you can implement it yourself.
79+
Your contributions are welcome! [Create an issue](https://github.com/tdmalone/working-plusplus/issues/new) if there's something you'd like to see or [send a pull request](https://github.com/tdmalone/working-plusplus/compare) if you can implement it yourself.
8080

81-
To develop locally, follow most of the *Installation* instructions above, except **instead of step 5** (deploying to Heroku), clone this repo locally and then install dependencies:
82-
83-
$ git clone https://github.com/tdmalone/working-plusplus
84-
$ cd working-plusplus
85-
$ yarn
86-
87-
You'll need [Node.js](https://nodejs.org/) already installed on your system. In addition, if you don't have [Yarn](https://yarnpkg.com/en/) and don't want it, you can use `npm install` instead of `yarn` above (but you might not get _exactly_ the same dependency versions).
88-
89-
After installing, to run the app:
90-
91-
$ node index.js
92-
93-
Or if you have the [Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli) installed:
94-
95-
$ heroku local
96-
97-
_For more help on running `heroku local`, see the [Heroku Local Dev Center article](https://devcenter.heroku.com/articles/heroku-local)._
98-
99-
If you make changes to the app, press Ctrl+C to exit, and then run it again.
100-
101-
Finally, you'll need to be able to have Slack contact your development instance directly. If you don't have the ability to forward a port through to your machine, I recommend [ngrok](https://ngrok.com/). Download and extract, then in the directory you've extracted it in run:
102-
103-
./ngrok http 80 # Or port 5000 if you're running with heroku local.
104-
105-
ngrok will provide you with the public URL your app is accessible on. This is the URL you'll then need to use in **step 6** of the installation instructions above.
106-
107-
Other than the modifications to steps 5 and 6, make sure you've followed all the rest of the installation instructions. You should then be set up and ready with a local development instance that you can interact with directly on Slack! If you run into any problems, feel free to [create an issue](https://github.com/tdmalone/working-plusplus/issues/new).
108-
109-
### Linting and Running Tests
110-
111-
Before submitting pull requests, please check that your changes pass linting and tests by running `yarn lint` and `yarn test`. These will also be run for you by Travis CI, but it's often quicker to debug and resolve the issues locally.
112-
113-
You can run just the unit tests with `yarn unit-tests`, and just the integration tests with `yarn integration-tests`. It is normal to see errors while running the integration tests - some of the tests specifically check for these errors - but keep an eye on the exit code of the process to determine if it is successful (run `echo $?` immediately after running `yarn test` - you're looking for an exit code of `0` for a pass.)
114-
115-
You can modify the default testing behaviour by adjusting the relevant `scripts` in [`package.json`](package.json) or in some cases by passing additional [Jest configuration parameters](https://jestjs.io/docs/en/configuration.html) on the command line.
116-
117-
If you come across annoying *stylistic* linting rules, feel free to [change them](https://eslint.org/docs/rules/) in [`.eslintrc.js`](.eslintrc.js) as part of your pull request, providing they don't cause an adverse effect on existing code. Many linting issues can be automatically fixed by running `yarn fix`.
81+
For full details on contributing, including getting a local environment set up, see [CONTRIBUTING.md](CONTRIBUTING.md).
11882

11983
## TODO
12084

@@ -133,6 +97,8 @@ Although it works, it's very basic. Potential enhancements include:
13397
* Option to deduct karma automatically for swearing (with customisable word list?)
13498
* Record and make accessible how many karma points someone has _given_
13599
* Enhance messages to support interpolation of variables such as score and name of user or thing **(in progress, see [#1](https://github.com/tdmalone/working-plusplus/pull/1))**
100+
* Set up a Dockerfile to make local development easier (i.e. to not require Node, Yarn or Postgres)
101+
* Improve error handling
136102

137103
## License
138104

app.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
},
1919
"YARN_PRODUCTION": {
2020
"description": "This configures Heroku to only install production dependencies. See https://devcenter.heroku.com/articles/nodejs-support#package-installation for more details.",
21-
"value": true
21+
"value": "true"
2222
}
2323
},
2424
"addons": [

index.js

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,45 @@
1010
'use strict';
1111

1212
const express = require( 'express' ),
13+
slack = require( '@slack/client' ),
1314
bodyParser = require( 'body-parser' ),
1415
app = require( './src/app' );
1516

16-
// Let Heroku set the port.
17-
const PORT = process.env.PORT || 80; // eslint-disable-line no-process-env, no-magic-numbers
17+
/* eslint-disable no-process-env, no-magic-numbers */
18+
const PORT = process.env.PORT || 80; // Let Heroku set the port.
19+
const SLACK_OAUTH_ACCESS_TOKEN = process.env.SLACK_BOT_USER_OAUTH_ACCESS_TOKEN;
20+
/* eslint-enable no-process-env, no-magic-numbers */
1821

19-
const server = express();
22+
/**
23+
* Starts the server and bootstraps the app.
24+
*
25+
* @param {object} options Optional. Allows passing in replacements for the default Express server
26+
* module (`express` property) and Slack Web API client module (`slack`
27+
* property).
28+
* @returns {http.Server} A Node.js http.Server object as returned by Express' listen method. See
29+
* https://expressjs.com/en/4x/api.html#app.listen and
30+
* https://nodejs.org/api/http.html#http_class_http_server for details.
31+
*/
32+
const bootstrap = ( options = {}) => {
33+
34+
// Allow alternative implementations of both Express and Slack to be passed in.
35+
const server = options.express || express();
36+
app.setSlackClient( options.slack || new slack.WebClient( SLACK_OAUTH_ACCESS_TOKEN ) );
37+
38+
server.use( bodyParser.json() );
39+
server.enable( 'trust proxy' );
40+
server.get( '/', app.handleGet );
41+
server.post( '/', app.handlePost );
42+
43+
return server.listen( PORT, () => {
44+
console.log( 'Listening on port ' + PORT + '.' );
45+
});
46+
47+
};
2048

21-
server.use( bodyParser.json() );
22-
server.enable( 'trust proxy' );
23-
server.get( '/', app.handleGet );
24-
server.post( '/', app.handlePost );
49+
// If module was called directly, bootstrap now.
50+
if ( require.main === module ) {
51+
bootstrap();
52+
}
2553

26-
server.listen( PORT, () => {
27-
console.log( 'Listening on port ' + PORT + '.' );
28-
});
54+
module.exports = bootstrap;

jest.config.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* Configuration for Jest.
3+
*
4+
* @see https://jestjs.io/docs/en/configuration.html
5+
*/
6+
7+
'use strict';
8+
9+
const config = {
10+
collectCoverage: true,
11+
setupTestFrameworkScriptFile: 'jest-chain',
12+
testEnvironment: 'node',
13+
14+
testMatch: [
15+
'**/tests/**/*.js'
16+
],
17+
18+
testPathIgnorePatterns: [
19+
'/mocks/',
20+
'/node_modules/',
21+
'/_config.js',
22+
'/_runner.js',
23+
'/.eslintrc.js'
24+
],
25+
26+
verbose: true
27+
};
28+
29+
/* eslint-disable no-process-env */
30+
31+
if ( process.env.SKIP_INTEGRATION_TESTS ) {
32+
config.testPathIgnorePatterns.push( 'integration-tests' );
33+
}
34+
35+
if ( process.env.SKIP_E2E_TESTS ) {
36+
config.testPathIgnorePatterns.push( 'e2e-tests' );
37+
}
38+
39+
process.env.PORT = 5000;
40+
process.env.SLACK_VERIFICATION_TOKEN = 'abcdef123';
41+
process.env.DATABASE_URL = 'postgres://postgres@localhost:5432/plusplus_tests';
42+
process.env.DATABASE_USE_SSL = false;
43+
44+
/* eslint-enable no-process-env */
45+
46+
module.exports = config;

0 commit comments

Comments
 (0)