Commit c0997450 authored by Benjamin Bouvier's avatar Benjamin Bouvier
Browse files

Add validation helpers and use them for categories;

parent 4c874fdf
import { assert, translate as $t } from '../helpers';
import { checkExactFields, checkAllowedFields } from '../../shared/validators';
const API_VERSION = 'v1';
......@@ -152,16 +153,6 @@ export function deleteAlert(alertId) {
});
}
export function deleteCategory(categoryId, replaceByCategoryId) {
return buildFetchPromise(`api/${API_VERSION}/categories/${categoryId}`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ replaceByCategoryId })
});
}
export function updateOperation(id, newOp) {
return buildFetchPromise(`api/${API_VERSION}/operations/${id}`, {
method: 'PUT',
......@@ -318,6 +309,12 @@ export function createAccess(bank, login, password, customFields, customLabel) {
}
export function addCategory(category) {
let error = checkExactFields(category, ['title', 'color']);
if (error) {
alert(`Developer error when adding a category: ${error}`);
return;
}
return buildFetchPromise(`api/${API_VERSION}/categories/`, {
method: 'POST',
headers: {
......@@ -328,6 +325,12 @@ export function addCategory(category) {
}
export function updateCategory(id, category) {
let error = checkAllowedFields(category, ['title', 'color']);
if (error) {
alert(`Developer error when updating a category: ${error}`);
return;
}
return buildFetchPromise(`api/${API_VERSION}/categories/${id}`, {
method: 'PUT',
headers: {
......@@ -337,6 +340,16 @@ export function updateCategory(id, category) {
});
}
export function deleteCategory(categoryId, replaceByCategoryId) {
return buildFetchPromise(`api/${API_VERSION}/categories/${categoryId}`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ replaceByCategoryId })
});
}
export function fetchBudgets(year, month) {
return buildFetchPromise(`api/${API_VERSION}/budgets/${year}/${month}`);
}
......
......@@ -3,68 +3,54 @@ import Categories from '../../models/categories';
import Transactions from '../../models/transactions';
import { makeLogger, KError, asyncErr } from '../../helpers';
import { checkExactFields, checkAllowedFields } from '../../shared/validators';
let log = makeLogger('controllers/categories');
export async function create(req, res) {
export async function preloadCategory(req, res, next, id) {
try {
let { id: userId } = req.user;
let cat = req.body;
// Missing parameters
if (typeof cat.title === 'undefined') {
throw new KError('Missing category title', 400);
}
if (typeof cat.color === 'undefined') {
throw new KError('Missing category color', 400);
}
let category;
category = await Categories.find(userId, id);
if (typeof cat.parentId !== 'undefined') {
let parent = await Categories.find(userId, cat.parentId);
if (!parent) {
throw new KError(`Category ${cat.parentId} not found`, 404);
}
if (!category) {
throw new KError('Category not found', 404);
}
let created = await Categories.create(userId, cat);
res.status(200).json(created);
req.preloaded = { category };
return next();
} catch (err) {
return asyncErr(res, err, 'when creating category');
return asyncErr(res, err, 'when preloading a category');
}
}
export async function preloadCategory(req, res, next, id) {
export async function create(req, res) {
try {
let { id: userId } = req.user;
let category;
category = await Categories.find(userId, id);
if (!category) {
throw new KError('Category not found', 404);
let error = checkExactFields(req.body, ['title', 'color']);
if (error) {
throw new KError(`when creating a category: ${error}`, 400);
}
req.preloaded = { category };
return next();
let created = await Categories.create(userId, req.body);
res.status(200).json(created);
} catch (err) {
return asyncErr(res, err, 'when preloading a category');
return asyncErr(res, err, 'when creating category');
}
}
export async function update(req, res) {
try {
let { id: userId } = req.user;
let params = req.body;
// Missing parameters
if (typeof params.title === 'undefined') {
throw new KError('Missing title parameter', 400);
}
if (typeof params.color === 'undefined') {
throw new KError('Missing color parameter', 400);
let error = checkAllowedFields(req.body, ['title', 'color']);
if (error) {
throw new KError(`when updating a category: ${error}`, 400);
}
let category = req.preloaded.category;
let newCat = await Categories.update(userId, category.id, params);
let newCat = await Categories.update(userId, category.id, req.body);
res.status(200).json(newCat);
} catch (err) {
return asyncErr(res, err, 'when updating a category');
......@@ -75,13 +61,14 @@ export async function destroy(req, res) {
try {
let { id: userId } = req.user;
let replaceBy = req.body.replaceByCategoryId;
if (typeof replaceBy === 'undefined') {
throw new KError('Missing parameter replaceBy', 400);
let error = checkExactFields(req.body, ['replaceByCategoryId']);
if (error) {
throw new KError('Missing parameter replaceByCategoryId', 400);
}
let former = req.preloaded.category;
let replaceBy = req.body.replaceByCategoryId;
if (replaceBy !== null) {
log.debug(`Replacing category ${former.id} by ${replaceBy}...`);
let categoryToReplaceBy = await Categories.find(userId, replaceBy);
......
// Checks that the given object fields match all the names specified in
// allowedFieldNames. Returns an error if there's one, or nothing otherwise.
export function checkHasAllFields(object, allowedFieldNames) {
for (let name of allowedFieldNames) {
if (!object.hasOwnProperty(name)) {
return `missing field ${name}`;
}
}
}
// Checks that the given object fields belong to the list of allowedFieldNames.
// Returns an error if there's one, or nothing otherwise.
export function checkAllowedFields(object, allowedFieldNames) {
for (let key of Object.keys(object)) {
if (!allowedFieldNames.includes(key)) {
return `unexpected property on object: ${key}`;
}
}
}
// Checks that the fields in object exactly match those provided by
// allowedFieldNames. Returns an error if there's one, or nothing otherwise.
export function checkExactFields(object, allowedFieldNames) {
return (
checkHasAllFields(object, allowedFieldNames) ||
checkAllowedFields(object, allowedFieldNames)
);
}
export function checkAlert(alert) {
if (alert.type === 'report') {
if (
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment