Skip to content
This repository was archived by the owner on Mar 25, 2020. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
316cfe3
add prefix to list test
lucacioria Feb 4, 2017
63e32e4
complete create test to test for pledge to be in list too
lucacioria Feb 4, 2017
f26057b
adding return to all res.send to avoid UnhandledPromiseRejectionWarning
lucacioria Feb 4, 2017
60cf66b
completed test -> expired: notifies both at the right time, stays in …
lucacioria Feb 4, 2017
e3ba4af
added test for expired: does not notify for completed pledges, also c…
lucacioria Feb 4, 2017
7c84ac2
completed test -> expired: does not notify for deleted pledges
lucacioria Feb 4, 2017
ba35f7c
completed test -> delete: notifies both immediately, disappears form …
lucacioria Feb 4, 2017
d5081de
tests for completed pledges
lucacioria Feb 4, 2017
9787034
refactor
lucacioria Feb 4, 2017
8cffbcc
add restart command to package json using nodemon
lucacioria Feb 5, 2017
c1ee030
add slack keys to config files
lucacioria Feb 5, 2017
a87df4a
write migration to schema v4 and add functions for teams
lucacioria Feb 5, 2017
55e740d
change slack functions to work with bots instead of incoming webhooks
lucacioria Feb 5, 2017
8820d6d
adapted routes to work with bot and added oauth2
lucacioria Feb 5, 2017
131b51c
added route add-to-slack which shows the add to slack button in a bro…
lucacioria Feb 5, 2017
7a6ace9
yarn lock for all previous changes
lucacioria Feb 5, 2017
f2d4c97
added pledge and pledge-test icons for slack app
lucacioria Feb 5, 2017
c166249
remove migrations as impossible to migrate to slack app, and not much…
lucacioria Feb 5, 2017
04b3c9f
make tests pass, fixing tests and a few bugs :)
lucacioria Feb 5, 2017
c54b21b
add https
lucacioria Feb 5, 2017
1064bf0
avoid inserting duplicate teams
lucacioria Feb 5, 2017
0742eaa
added logic to send notification as bot instead as @slackbot
lucacioria Feb 5, 2017
5b60c1e
added ORDER BY
lucacioria Feb 5, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added assets/pledge-test.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/pledge.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 3 additions & 2 deletions config-ci.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
{
"db": "db-test",
"domain": "pledge.our.buildo.io",
"domain": "ci.pledge.com.fake",
"interval": 1,
"slack": {
"incomingWebhookURL": "https://hooks.slack.com/services/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"
"clientId": "123456789.123456789",
"clientSecret": "abcdef123456789"
}
}

5 changes: 3 additions & 2 deletions config-prod.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
{
"db": "/var/lib/pledge/db",
"domain": "pledge.our.buildo.io",
"domain": "https://pledge.our.buildo.io",
"interval": 1,
"slack": {
"incomingWebhookURL": "https://hooks.slack.com/services/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"
"clientId": "2194261799.137771655351",
"clientSecret": "37ca4f24926ff3b36f39f6f2f77faaff"
}
}

3 changes: 2 additions & 1 deletion config.json.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"domain": "my.deploy.url",
"interval": 1,
"slack": {
"incomingWebhookURL": "https://url/of/incoming/webhook"
"clientId": "123456789.123456789",
"clientSecret": "abcdef123456789"
}
}

3 changes: 3 additions & 0 deletions nodemon.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"ignore": ["tests/*"]
}
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"build": "npm run clean && babel src --out-dir lib && cp config.json lib || true",
"watch": "npm run clean && cp config.json lib && babel src --out-dir lib --watch",
"start": "DEBUG=pledge,http,express:* node lib/index.js",
"restart": "DEBUG=pledge,http,express:* nodemon --config nodemon.json lib/index.js",
"test": "jest"
},
"repository": {
Expand All @@ -27,6 +28,7 @@
},
"homepage": "https://github.com/buildo/pledge#readme",
"dependencies": {
"@slack/client": "^3.8.1",
"babel-core": "^6.4.5",
"babel-polyfill": "^6.4.5",
"babel-runtime": "^6.9.2",
Expand All @@ -39,6 +41,7 @@
"mockdate": "^2.0.1",
"request": "^2.75.0",
"request-promise": "^2.0.1",
"simple-oauth2": "^1.0.3",
"sqlite": "^2.0.2",
"supertest": "^2.0.1"
},
Expand All @@ -54,6 +57,7 @@
"babel-preset-stage-0": "^6.5.0",
"eslint": "^2.4.0",
"eslint-config-buildo": "github:buildo/eslint-config-buildo",
"jest": "^18.1.0"
"jest": "^18.1.0",
"nodemon": "^1.11.0"
}
}
122 changes: 57 additions & 65 deletions src/db.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import db from 'sqlite';
import config from '../config.json';
import { formatDate } from './utils';

const schemaVersion = 3;

const createTables = async () => {
await db.run(`
CREATE TABLE pledges (
id INTEGER PRIMARY KEY AUTOINCREMENT,
teamId TEXT NOT NULL,
requester TEXT NOT NULL,
performer TEXT NOT NULL,
performerId TEXT NOT NULL,
content TEXT NOT NULL,
deadline INTEGER NOT NULL,
completed BOOLEAN NOT NULL DEFAULT 0,
Expand All @@ -18,95 +18,90 @@ const createTables = async () => {
);
`);
await db.run(`
CREATE TABLE schemaVersions (
version INTEGER NOT NULL,
migrationDate INTEGER NOT NULL
CREATE TABLE teams (
teamName TEXT NOT NULL,
teamId TEXT NOT NULL,
botUserId TEXT NOT NULL,
botAccessToken TEXT NOT NULL,
createdAt INTEGER NOT NULL
);
`);
await db.run('INSERT INTO schemaVersions values (?, ?)', schemaVersion, Date.now());
};

const migrateIfNeeded = async () => {
const hasSchemaVersionsTable = !!(await db.get(`
SELECT 1 FROM sqlite_master WHERE name ='schemaVersions' and type='table';
`));
const currentVersion = hasSchemaVersionsTable ?
(await db.get('SELECT max(version) as v FROM schemaVersions')).v : 1;
console.log(`starting pledge, current DB version is ${currentVersion}`); // eslint-disable-line no-console
if (currentVersion < 2) {
// version 1 did not have a schemaVersions table, let's create it
await db.run(`
CREATE TABLE if not exists schemaVersions (
version INTEGER NOT NULL,
migrationDate INTEGER NOT NULL
);`
);
// add first version line with migrationDate = now
await db.run(`
INSERT INTO schemaVersions values (2, ?)
`, Date.now()
);
// perform migration v1 => v2
await db.run(`
ALTER TABLE pledges
ADD COLUMN expiredNotificationSent BOOLEAN NOT NULL DEFAULT 0`
);
console.log('migrated DB to version 2'); // eslint-disable-line no-console
}
export const getTeam = (teamId) => {
return db.get(`
SELECT teamId, teamName, botUserId, botAccessToken, createdAt
FROM teams
WHERE teamId = ?
`, teamId
);
};

if (currentVersion < 3) {
// add version line with migrationDate = now
await db.run(`
INSERT INTO schemaVersions values (3, ?)
`, Date.now()
);
// perform migration v2 => v3
await db.run(`
ALTER TABLE pledges
ADD COLUMN completed BOOLEAN NOT NULL DEFAULT 0`
);
console.log('migrated DB to version 3'); // eslint-disable-line no-console
}
export const deleteTeam = (teamId) => {
return db.run(`
DELETE FROM teams
WHERE teamId = ?
`, teamId
);
};

export const insertTeam = (teamId, teamName, botUserId, botAccessToken) => {
return db.run(`
INSERT INTO teams (teamId, teamName, botUserId, botAccessToken, createdAt)
VALUES (?, ?, ?, ?, ?)
`, teamId, teamName, botUserId, botAccessToken, Date.now()
);
};

export const getList = async requester => {
export const getList = async (requester, teamId) => {
const requests = (await db.all(`
SELECT id, requester, performer, content, deadline
SELECT id, teamId, requester, performer, content, deadline
FROM pledges
WHERE requester = ? AND completed = 0
`, requester)).map(x => ({ ...x, deadline: formatDate(new Date(x.deadline)) }));
WHERE requester = ? AND teamId = ? AND completed = 0
ORDER BY deadline ASC
`, requester, teamId)).map(x => ({ ...x, deadline: formatDate(new Date(x.deadline)) }));

const pledges = (await db.all(`
SELECT id, requester, performer, content, deadline
SELECT id, teamId, requester, performer, content, deadline
FROM pledges
WHERE performer = ? AND completed = 0
`, requester)).map(x => ({ ...x, deadline: formatDate(new Date(x.deadline)) }));
WHERE performer = ? AND teamId = ? AND completed = 0
ORDER BY deadline ASC
`, requester, teamId)).map(x => ({ ...x, deadline: formatDate(new Date(x.deadline)) }));

return { requests, pledges };
};

export const getPledge = (pledgeId) => {
return db.get(`
SELECT id, requester, performer, content, deadline
SELECT id, teamId, requester, performer, performerId, content, deadline
FROM pledges
WHERE id = ?
`, pledgeId
);
};

export const insertPledge = ({ requester, performer, content, deadline }) => {
export const insertPledge = ({ teamId, requester, performer, performerId, content, deadline }) => {
return db.run(`
INSERT INTO pledges (requester, performer, content, deadline, created_at)
VALUES (?, ?, ?, ?, ?)
`, requester, performer, content, deadline, Date.now()
INSERT INTO pledges (teamId, requester, performer, performerId, content, deadline, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?)
`, teamId, requester, performer, performerId, content, deadline, Date.now()
);
};

export const getTeamByBotAccessToken = (botAccessToken) => {
return db.get(`
SELECT teamId, teamName, botUserId, botAccessToken, createdAt
FROM teams
WHERE botAccessToken = ?
`, botAccessToken
);
};

export const findAllPledgesExpiredToNotify = () => {
return db.all(`
SELECT id, requester, performer, content, deadline
SELECT id, teamId, requester, performer, performerId, content, deadline
FROM pledges
WHERE deadline < ? AND expiredNotificationSent = 0
WHERE deadline < ? AND expiredNotificationSent = 0 AND completed = 0
`, Date.now()
);
};
Expand Down Expand Up @@ -146,11 +141,8 @@ export const init = async (dbFilename = config.db) => {
const hasPledgesTable = !!(await db.get(`
SELECT 1 FROM sqlite_master WHERE name ='pledges' and type='table';
`));
if (hasPledgesTable) {
await migrateIfNeeded();
} else {
console.log('creating tables'); // eslint-disable-line no-console
createTables();
if (!hasPledgesTable) {
await createTables();
}
};

Expand Down
Loading