-
Notifications
You must be signed in to change notification settings - Fork 663
add task solution #507
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
add task solution #507
Changes from all commits
67d06ff
e2fecea
d2f753c
328786b
34d078c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| name: Test | ||
|
|
||
| on: | ||
| pull_request: | ||
| branches: [master] | ||
|
|
||
| jobs: | ||
| build: | ||
| runs-on: ubuntu-latest | ||
| strategy: | ||
| matrix: | ||
| node-version: [20.x] | ||
| services: | ||
| postgres: | ||
| image: postgres:latest | ||
| env: | ||
| POSTGRES_USER: postgres | ||
| POSTGRES_PASSWORD: password | ||
| POSTGRES_DB: students | ||
| POSTGRES_PORT: 5432 | ||
| POSTGRES_HOST: localhost | ||
| ports: | ||
| - 5432:5432 | ||
| options: >- | ||
| --health-cmd pg_isready | ||
| --health-interval 10s | ||
| --health-timeout 5s | ||
| --health-retries 5 | ||
| steps: | ||
| - uses: actions/checkout@v2 | ||
| - name: Set up Node.js | ||
| uses: actions/setup-node@v1 | ||
| with: | ||
| node-version: '20' | ||
| - name: Install dependencies | ||
| run: npm install | ||
| - name: Run tests | ||
| env: | ||
| POSTGRES_USER: postgres | ||
| POSTGRES_PASSWORD: password | ||
| POSTGRES_DB: students | ||
| POSTGRES_HOST: localhost | ||
| POSTGRES_PORT: 5432 | ||
| run: npm test |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,7 +7,3 @@ node_modules | |
|
|
||
| # MacOS | ||
| .DS_Store | ||
|
|
||
| # env files | ||
| *.env | ||
| .env* | ||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| const { categoriesService } = require('../services'); | ||
|
|
||
| const create = async (req, res) => { | ||
| const { name } = req.body; | ||
|
|
||
| if (!name) { | ||
| return res.sendStatus(400); | ||
| } | ||
|
|
||
| const category = await categoriesService.create(name); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The categories router is not registered in the server. The task requires ensuring new routes are registered in createServer.js. |
||
|
|
||
| res.status(201).json(categoriesService.normalize(category)); | ||
| }; | ||
|
|
||
| const getAll = async (req, res) => { | ||
| const categories = await categoriesService.getAll(); | ||
|
|
||
| res.send(categories.map((category) => categoriesService.normalize(category))); | ||
| }; | ||
|
|
||
| const getOne = async (req, res) => { | ||
| const category = await categoriesService.getOne(Number(req.params.id)); | ||
|
|
||
| if (!category) { | ||
| res.sendStatus(404); | ||
|
|
||
| return; | ||
| } | ||
|
|
||
| res.send(categoriesService.normalize(category)); | ||
| }; | ||
|
|
||
| const update = async (req, res) => { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's a good practice to validate the request body here, similar to how you've done it in the |
||
| const { id } = req.params; | ||
| const { name } = req.body; | ||
| const category = await categoriesService.getOne(Number(id)); | ||
|
|
||
| if (!category) { | ||
| return res.sendStatus(404); | ||
| } | ||
|
|
||
| if (!name) { | ||
| return res.sendStatus(400); | ||
| } | ||
|
|
||
| const updatedCategory = await categoriesService.update(Number(id), { | ||
| name, | ||
| }); | ||
|
|
||
| res.json(categoriesService.normalize(updatedCategory)); | ||
| }; | ||
|
|
||
| const remove = async (req, res) => { | ||
| const categoriesRemoved = await categoriesService.remove( | ||
| Number(req.params.id), | ||
| ); | ||
|
|
||
| if (!categoriesRemoved) { | ||
| return res.sendStatus(404); | ||
| } | ||
|
|
||
| res.sendStatus(204); | ||
| }; | ||
|
|
||
| const categoriesController = { | ||
| getAll, | ||
| getOne, | ||
| create, | ||
| update, | ||
| remove, | ||
| }; | ||
|
|
||
| exports.categoriesController = categoriesController; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| const { usersService, expensesService } = require('../services'); | ||
|
|
||
| const create = async (req, res) => { | ||
| const { userId, spentAt, title, amount, category, note } = req.body; | ||
| const user = await usersService.getOne(userId); | ||
|
|
||
| if (!user || !userId || !title || !amount || !spentAt) { | ||
| return res.sendStatus(400); | ||
|
Comment on lines
+4
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| } | ||
|
|
||
| const expense = await expensesService.create({ | ||
|
Comment on lines
+9
to
+11
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| userId, | ||
| spentAt, | ||
| title, | ||
| amount, | ||
| category, | ||
| note, | ||
| }); | ||
|
|
||
| res.status(201).json(expensesService.normalize(expense)); | ||
| }; | ||
|
|
||
| const getAll = async (req, res) => { | ||
| const { userId, categories, from, to } = req.query; | ||
| const expenses = await expensesService.getAll({ | ||
| userId: Number(userId), | ||
| categories, | ||
| from, | ||
| to, | ||
| }); | ||
|
|
||
| res.json(expenses.map((expense) => expensesService.normalize(expense))); | ||
| }; | ||
|
|
||
| const getOne = async (req, res) => { | ||
| const expense = await expensesService.getOne(Number(req.params.id)); | ||
|
|
||
| if (!expense) { | ||
| return res.sendStatus(404); | ||
| } | ||
|
|
||
| res.json(expensesService.normalize(expense)); | ||
| }; | ||
|
|
||
| const update = async (req, res) => { | ||
| const { id } = req.params; | ||
| const expense = await expensesService.getOne(Number(id)); | ||
|
|
||
| if (!expense) { | ||
| return res.sendStatus(404); | ||
| } | ||
|
|
||
| const allowedFields = [ | ||
| 'userId', | ||
| 'title', | ||
| 'amount', | ||
| 'spentAt', | ||
| 'category', | ||
| 'note', | ||
| ]; | ||
| const updateData = {}; | ||
|
|
||
| allowedFields.forEach((field) => { | ||
| if (req.body[field] !== undefined) { | ||
| updateData[field] = req.body[field]; | ||
| } | ||
| }); | ||
|
|
||
| if (Object.keys(updateData).length === 0) { | ||
| return res.status(400); | ||
| } | ||
|
|
||
| const updatedExpense = await expensesService.update(Number(id), updateData); | ||
|
|
||
| res.json(expensesService.normalize(updatedExpense)); | ||
| }; | ||
|
|
||
| const remove = async (req, res) => { | ||
| const expensesRemoved = await expensesService.remove(Number(req.params.id)); | ||
|
|
||
| if (!expensesRemoved) { | ||
| return res.sendStatus(404); | ||
| } | ||
|
|
||
| res.sendStatus(204); | ||
| }; | ||
|
|
||
| const expensesController = { | ||
| create, | ||
| getAll, | ||
| getOne, | ||
| update, | ||
| remove, | ||
| }; | ||
|
|
||
| exports.expensesController = expensesController; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| const { usersController } = require('./users.controller'); | ||
| const { expensesController } = require('./expenses.controller'); | ||
| const { categoriesController } = require('./categories.controller'); | ||
|
|
||
| module.exports = { | ||
| usersController, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
| expensesController, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
| categoriesController, | ||
| }; | ||
|
Comment on lines
+5
to
+9
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The task requires implementing CRUD operations for categories. This would involve creating a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| const { usersService } = require('../services'); | ||
|
|
||
| const create = async (req, res) => { | ||
| const { name } = req.body; | ||
|
|
||
| if (!name) { | ||
| return res.sendStatus(400); | ||
| } | ||
|
|
||
| const user = await usersService.create(name); | ||
|
|
||
| res.status(201).json(usersService.normalize(user)); | ||
| }; | ||
|
|
||
| const getAll = async (req, res) => { | ||
| const users = await usersService.getAll(); | ||
|
|
||
| res.send(users.map((user) => usersService.normalize(user))); | ||
| }; | ||
|
|
||
| const getOne = async (req, res) => { | ||
| const user = await usersService.getOne(Number(req.params.id)); | ||
|
|
||
| if (!user) { | ||
| res.sendStatus(404); | ||
|
|
||
| return; | ||
| } | ||
|
|
||
| res.send(usersService.normalize(user)); | ||
| }; | ||
|
|
||
| const update = async (req, res) => { | ||
| const { id } = req.params; | ||
| const { name } = req.body; | ||
| const user = await usersService.getOne(Number(id)); | ||
|
|
||
| if (!user) { | ||
| return res.sendStatus(404); | ||
| } | ||
|
|
||
| if (!name) { | ||
| return res.sendStatus(400); | ||
| } | ||
|
|
||
| const updatedUser = await usersService.update(Number(id), { | ||
| name, | ||
| }); | ||
|
|
||
| res.json(usersService.normalize(updatedUser)); | ||
| }; | ||
|
|
||
| const remove = async (req, res) => { | ||
| const usersRemoved = await usersService.remove(Number(req.params.id)); | ||
|
|
||
| if (!usersRemoved) { | ||
| return res.sendStatus(404); | ||
| } | ||
|
|
||
| res.sendStatus(204); | ||
| }; | ||
|
|
||
| const usersController = { | ||
| getAll, | ||
| getOne, | ||
| create, | ||
| update, | ||
| remove, | ||
| }; | ||
|
|
||
| exports.usersController = usersController; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,17 @@ | ||
| 'use strict'; | ||
|
|
||
| const express = require('express'); | ||
| const { routes } = require('./routes'); | ||
|
|
||
| const createServer = () => { | ||
| // your code goes here | ||
| const app = express(); | ||
|
|
||
| app.use(express.json()); | ||
| app.use('/users', routes.usersRouter); | ||
| app.use('/expenses', routes.expensesRouter); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The new routes for managing categories are missing. Based on the task requirements, you should add a new router here for the
Comment on lines
+10
to
+11
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The categories router is NOT registered in the server. The task requires: 'Ensure the new routes are registered in |
||
| app.use('/categories', routes.categoriesRouter); | ||
|
|
||
| return app; | ||
| }; | ||
|
|
||
| module.exports = { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| 'use strict'; | ||
|
|
||
| const { sequelize } = require('../db'); | ||
| const { DataTypes } = require('sequelize'); | ||
|
|
||
| const Category = sequelize.define('Category', { | ||
| name: { | ||
| type: DataTypes.STRING, | ||
| allowNull: false, | ||
| }, | ||
| }); | ||
|
|
||
| module.exports = { | ||
| Category, | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The categories router is missing from exports. Need to export categoriesRouter here so it can be used in createServer.js.