Skip to content
Open
Changes from all commits
Commits
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
239 changes: 238 additions & 1 deletion src/createServer.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,248 @@
'use strict';

// const express = require('express');
const express = require('express');
const cors = require('cors');

let users = [];
let expenses = [];

function createServer() {
users = [];
expenses = [];

const app = express();

app.use(express.json());
app.use(cors());

app.get('/users', (req, res) => {
res.json(users);
});

app.post('/users', (req, res) => {
const { name } = req.body;

if (!name) {
res.sendStatus(400);

return;
}

const user = { id: users.length + 1, name };

users.push(user);

res.statusCode = 201;

res.send(user);
});

app.get('/users/:id', (req, res) => {
const { id } = req.params;

const user = users.find((userId) => userId.id === Number(id));

if (!user) {
res.sendStatus(404);

return;
}

res.statusCode = 200;

res.send(user);
});

app.delete('/users/:id', (req, res) => {
const { id } = req.params;

const userForDelete = users.find((user) => user.id === Number(id));

if (!userForDelete) {
res.sendStatus(404);

return;
}

const newUsers = users.filter((userId) => userId.id !== Number(id));

users = newUsers;

res.sendStatus(204);
});

app.patch('/users/:id', (req, res) => {
const { id } = req.params;
const { name } = req.body;

const userForUpdate = users.find((user) => user.id === Number(id));

if (!userForUpdate) {
res.sendStatus(404);

return;
}

if (!name) {
res.sendStatus(400);

return;
}

userForUpdate.name = name;

res.statusCode = 200;

res.send(userForUpdate);
});

app.get('/expenses', (req, res) => {
let result = expenses;

if (req.query.userId) {
const userId = Number(req.query.userId);

result = result.filter((expense) => expense.userId === userId);
}

if (req.query.categories) {
result = result.filter(
(expense) => expense.category === req.query.categories,
);
Comment on lines +108 to +111

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GET /expenses filters by the query parameter categories here, but the API spec uses category (singular). Use req.query.category so the filtering matches the documentation and tests.

Comment on lines +108 to +111

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The API spec and tests expect a single query parameter named category. Here the handler checks req.query.categories and filters by req.query.categories. Change this to use req.query.category so filtering by category works as expected and matches the documentation/tests.

Comment on lines +108 to +111

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In GET /expenses you check req.query.categories and compare expense.category to req.query.categories. The docs/tests expect a single category query parameter. Use req.query.category so filtering matches the API contract.

}

if (req.query.from) {
const fromDate = new Date(req.query.from);

result = result.filter(
(expense) => new Date(expense.spentAt) >= fromDate,
);
}

if (req.query.to) {
const toDate = new Date(req.query.to);

result = result.filter((expense) => new Date(expense.spentAt) <= toDate);
}

return res.send(result);
});

app.post('/expenses', (req, res) => {
const { userId, spentAt, title, amount, category, note } = req.body;

if (userId == null || title == null || amount == null || category == null) {
res.sendStatus(400);

return;
}

const userExist = users.find((user) => user.id === Number(userId));

if (!userExist) {
res.sendStatus(400);
Comment on lines +142 to +143

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In POST /expenses, when the referenced user is not found you return res.sendStatus(400). Per the requirements, missing entities must return 404. Change this branch to return 404 to match the spec/tests.


return;
Comment on lines +142 to +145

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the referenced user does not exist you return HTTP 400 here. Per the task requirements tests expect HTTP 404 for missing entities — change this to res.sendStatus(404) so missing related resources return 404.

Comment on lines +142 to +145

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the referenced user doesn't exist the handler responds with status 400. Per the task requirements (and tests) missing entities should produce a 404. Replace res.sendStatus(400) with res.sendStatus(404) for this branch.

}

const expense = {
id: expenses.length + 1,
userId: Number(userId),
spentAt: spentAt || new Date().toISOString(),
title: title,
amount: amount,
category: category,
note: note,
};

expenses.push(expense);

res.statusCode = 201;

res.send(expense);
});

app.get('/expenses/:id', (req, res) => {
const { id } = req.params;

const expenseById = expenses.find((expense) => expense.id === Number(id));

if (!expenseById) {
res.sendStatus(404);

return;
}

res.statusCode = 200;

res.send(expenseById);
});

app.delete('/expenses/:id', (req, res) => {
const { id } = req.params;

const expenseForDelete = expenses.find(
(expense) => expense.id === Number(id),
);

if (!expenseForDelete) {
res.sendStatus(404);

return;
}

const newListOfExpenses = expenses.filter(
(expense) => expense.id !== Number(id),
);

expenses = newListOfExpenses;

res.sendStatus(204);
});

app.patch('/expenses/:id', (req, res) => {
const { id } = req.params;
const { spentAt, title, amount, category, note } = req.body;

const expenseForUpdate = expenses.find(
(expense) => expense.id === Number(id),
);

if (!expenseForUpdate) {
res.sendStatus(404);

return;
}

if (spentAt !== undefined) {
expenseForUpdate.spentAt = spentAt;
}

if (title !== undefined) {
expenseForUpdate.title = title;
}

if (amount !== undefined) {
expenseForUpdate.amount = amount;
}

if (category !== undefined) {
expenseForUpdate.category = category;
}

if (note !== undefined) {
expenseForUpdate.note = note;
}

res.statusCode = 200;

res.send(expenseForUpdate);
});
// Use express to create a server
// Add a routes to the server
// Return the server (express app)

return app;
}

module.exports = {
Expand Down
Loading