Skip to content

Commit

Permalink
feat(API): add PUT /profile endpoint
Browse files Browse the repository at this point in the history
- create tests for endpoint
- add more tests to previous endpoints
- add endpoint controllers

[Delivers #159805808]
  • Loading branch information
olusoladavid committed Aug 15, 2018
1 parent c36fb80 commit b62289f
Show file tree
Hide file tree
Showing 12 changed files with 584 additions and 102 deletions.
112 changes: 112 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
},
"scripts": {
"dev": "nodemon server/index.js --exec babel-node",
"test": "cross-env NODE_ENV=test nyc mocha --timeout 5000 --exit",
"test": "cross-env NODE_ENV=test nyc mocha --timeout 10000 --exit",
"build": "babel server -d dist",
"lint": "eslint server",
"coverage": "nyc report --reporter=text-lcov | coveralls",
Expand Down Expand Up @@ -36,7 +36,8 @@
"mocha": "^5.2.0",
"nodemon": "^1.18.2",
"nyc": "^12.0.2",
"prettier-eslint": "^8.8.2"
"prettier-eslint": "^8.8.2",
"sinon": "^6.1.5"
},
"dependencies": {
"babel-cli": "^6.26.0",
Expand Down
28 changes: 18 additions & 10 deletions server/controllers/entryController.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,24 @@ class entryController {
*/
static async getAllEntries(req, res, next) {
try {
// get query params
let { limit, page } = req.query;
const { filter } = req.query;

// validate queries
limit = validate.isNumber(limit) ? limit : 20;
page = validate.isNumber(page) ? page : 0;
limit = limit ? parseInt(limit, 10) : 20;
page = page ? parseInt(page, 10) : 0;
const favs = filter && filter === 'favs' ? 't' : 'all';

// get entries
const userEntries = await query(queries.getAllEntries,
[req.authorizedUser.email, limit, page * limit]);
res.status(200).json({ entries: userEntries.rows, meta: { limit, page } });
[req.authorizedUser.email, favs]);
const start = limit * page;
const stop = limit * (page + 1);
const selectedEntries = userEntries.rows.slice(start, stop);
res.status(200).json({
entries: selectedEntries,
meta: { limit, page, count: userEntries.rows.length },
});
} catch (error) {
next(error);
}
Expand Down Expand Up @@ -92,18 +100,18 @@ class entryController {
const isFavorite = validate.booleanOrNull(req.body.is_favorite);

// check if entry exists and is already older than a day
const entryDate = await query(queries.getEntryCreationDate,
const entry = await query(queries.getOneEntry,
[req.authorizedUser.email, req.params.id]);
if (!entryDate.rowCount) res.status(404).json({ error: { message: 'Entry not found' } });
if (!entry.rowCount) res.status(404).json({ error: { message: 'Entry not found' } });

// older than a day?
if (!validate.isWithinLast24hours(entryDate.rows[0].created_on)) {
if (!validate.isWithinLast24hours(entry.rows[0].created_on)) {
res.status(403).json({ error: { message: 'Cannot update entry after 24 hours' } });
} else {
// add entry to database
const entry = await query(queries.updateOneEntry,
const updatedEntry = await query(queries.updateOneEntry,
[title, content, isFavorite, req.authorizedUser.email, req.params.id]);
res.status(200).json(entry.rows[0]);
res.status(200).json(updatedEntry.rows[0]);
}
} catch (error) {
next(error);
Expand Down
25 changes: 22 additions & 3 deletions server/controllers/userController.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,23 +85,42 @@ class userController {

/**
* @description Fetches user profile
*
* Returns user profile information
* @static
* @param {*} req - Request object
* @param {*} res - Response object
* @returns {data} email, entriesCount
* @memberof userController
*/
static async getProfile(req, res, next) {
try {
const entriesCounter = await query(queries.getEntriesCount, [req.authorizedUser.email]);
const allEntries = await query(queries.getAllEntries, [req.authorizedUser.email, 'all']);
const favEntries = await query(queries.getAllEntries, [req.authorizedUser.email, 't']);
const user = await query(queries.getOneUser, [req.authorizedUser.email]);
res.status(200).json({
email: req.authorizedUser.email,
entriesCount: entriesCounter.rows[0].count,
entries_count: allEntries.rows.length,
fav_count: favEntries.rows.length,
created_on: user.rows[0].created_on,
push_sub: Boolean(user.rows[0].push_sub),
email_reminder: Boolean(user.rows[0].reminderisset),
});
} catch (error) {
next(error);
}
}

static async updateProfile(req, res, next) {
try {
const { push_sub: pushSub, email_reminder: reminderIsSet } = req.body;
const pushSubString = JSON.stringify(pushSub);
await query(queries.updateProfile, [req.authorizedUser.email,
pushSubString, reminderIsSet]);
res.sendStatus(204);
} catch (error) {
next(error);
}
}
}

export default userController;
15 changes: 7 additions & 8 deletions server/db/createTables.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { queryClient } from './index';
import { query } from './index';

const usersTableQuery = `CREATE TABLE IF NOT EXISTS users
(
Expand All @@ -21,13 +21,12 @@ const entriesTableQuery = `CREATE TABLE IF NOT EXISTS entries (
is_favorite BOOLEAN DEFAULT false NOT NULL
);`;

const createTables = () => queryClient((err, client, done) => {
if (err) {
console.log(err.stack);
} else {
done();
client.query(`${usersTableQuery} ${entriesTableQuery}`);
const createTables = async () => {
try {
await query(`${usersTableQuery} ${entriesTableQuery}`);
} catch (error) {
console.error(error.stack);
}
});
};

export default createTables;
24 changes: 0 additions & 24 deletions server/db/entries.js

This file was deleted.

5 changes: 4 additions & 1 deletion server/db/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ const pool = new Pool(dbConfig);

const query = (text, params, callback) => pool.query(text, params, callback);

// if you need a client for db transactions
/*
const queryClient = callback => pool.connect((err, client, done) => {
callback(err, client, done);
});
*/

export { query, queryClient };
export { pool, query }; // eslint-disable-line import/prefer-default-export
22 changes: 9 additions & 13 deletions server/db/queries.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,18 @@ queries.getOneUser = 'SELECT * FROM users WHERE email=$1';

queries.insertOneUser = 'INSERT INTO users(email, password) VALUES($1, $2) RETURNING *';

queries.getEntriesCount = `SELECT COUNT(*) FROM entries INNER JOIN users
ON entries.user_id = users.id WHERE users.email=$1`;
queries.getAllEntries = `SELECT entries.id, entries.title, entries.content, entries.created_on,
entries.updated_on, entries.is_favorite FROM entries INNER JOIN users ON entries.user_id=users.id
WHERE (users.email=$1) AND ($2='all' OR entries.is_favorite='t')`;

queries.getAllEntries = `SELECT entries.id, entries.title, entries.content, entries.created_on, entries.updated_on,
entries.is_favorite FROM entries INNER JOIN users ON entries.user_id=users.id WHERE users.email=$1
LIMIT $2 OFFSET $3`;

queries.getOneEntry = `SELECT entries.id, entries.title, entries.content, entries.created_on, entries.is_favorite
FROM entries INNER JOIN users ON entries.user_id = users.id
queries.getOneEntry = `SELECT entries.id, entries.title, entries.content,
entries.created_on, entries.is_favorite FROM entries INNER JOIN users ON entries.user_id = users.id
WHERE users.email=$1 AND entries.id=$2`;

queries.insertOneEntry = `INSERT INTO entries (user_id, title, content, is_favorite)
VALUES ((SELECT id from users WHERE email=$1), $2, $3, $4)
RETURNING id, title, content, is_favorite, created_on`;

queries.getEntryCreationDate = `SELECT entries.created_on FROM entries
INNER JOIN users
ON entries.user_id = users.id
WHERE users.email=$1 AND entries.id=$2`;

queries.updateOneEntry = `UPDATE entries SET title = COALESCE($1, title),
content = COALESCE($2, content),is_favorite = COALESCE($3, is_favorite)
FROM users WHERE entries.user_id=users.id AND users.email=$4
Expand All @@ -32,3 +24,7 @@ entries.content, entries.is_favorite, entries.created_on`;

queries.deleteOneEntry = `DELETE FROM entries USING users
WHERE entries.user_id=users.id AND users.email=$1 AND entries.id=$2`;

queries.updateProfile = `UPDATE users SET push_sub = COALESCE($2, push_sub),
reminderisset = COALESCE($3, reminderisset) WHERE email=$1
RETURNING push_sub, reminderisset`;
Loading

0 comments on commit b62289f

Please sign in to comment.