Skip to content
Open
Show file tree
Hide file tree
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
Empty file added .codex
Empty file.
44 changes: 44 additions & 0 deletions .github/workflows/test.yml-template
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
16 changes: 16 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
services:
db:
image: postgres:18
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 PostgreSQL image version postgres:18 is not valid and will prevent the database container from starting. Please use a valid version, for example postgres:16. You can find available tags for the postgres image on Docker Hub.

container_name: project-db-local
restart: unless-stopped
ports:
- '${POSTGRES_PORT:-5432}:5432'
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
volumes:
- pg_data:/var/lib/postgresql

volumes:
pg_data:
36 changes: 20 additions & 16 deletions package-lock.json

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

13 changes: 11 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,16 @@
"test:only": "mate-scripts test",
"update": "mate-scripts update",
"postinstall": "npm run update",
"test": "npm run lint && npm run test:only"
"test": "npm run lint && npm run test:only",
"db:up": "docker compose up -d",
"db:down": "docker compose down",
"db:stop": "docker compose stop",
"db:logs": "docker compose logs -f db",
"db:reset": "docker compose down -v",
"build": "sequelize generate && tsc",
"test:watch": "jest --watch",
"test:user:watch": "npx jest tests/user.test.js --runInBand --verbose --watch ",
"test:expense:watch": "npx jest tests/expense.test.js --runInBand --verbose --watch "
},
"author": "Mate academy",
"license": "GPL-3.0",
Expand All @@ -23,7 +32,7 @@
},
"devDependencies": {
"@mate-academy/eslint-config": "latest",
"@mate-academy/scripts": "^1.8.6",
"@mate-academy/scripts": "^2.1.3",
"axios": "^1.7.2",
"eslint": "^8.57.0",
"eslint-plugin-jest": "^28.6.0",
Expand Down
102 changes: 102 additions & 0 deletions src/controllers/categories.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
const {
models: { Category },
} = require('../models/models');

function handleControllerError(res, action, error) {
// eslint-disable-next-line no-console
console.error(`Smth bad with: ${action}`, error);
res.sendStatus(500);
}

async function getAllCategories(req, res) {
try {
const categories = await Category.findAll({
order: [['id', 'ASC']],
});

res.send(categories);
} catch (error) {
handleControllerError(res, 'get', error);
}
}

async function getCategoryById(req, res) {
try {
const { id } = req.params;
const category = await Category.findByPk(Number(id));

if (!category) {
return res.sendStatus(404);
}

res.status(200).send(category);
} catch (error) {
handleControllerError(res, 'get', error);
}
}

async function create(req, res) {
try {
const { name } = req.body;

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

const category = await Category.create({ name });

res.status(201).send(category);
} catch (error) {
handleControllerError(res, 'create', error);
}
}

async function remove(req, res) {
try {
const { id } = req.params;
const category = await Category.findByPk(Number(id));

if (!category) {
return res.status(404).json({ error: 'Not found' });
}

await category.destroy();

return res.sendStatus(204);
} catch (error) {
handleControllerError(res, 'remove', error);
}
}

async function update(req, res) {
try {
const { id } = req.params;
const { name } = req.body;

const category = await Category.findByPk(Number(id));

if (!category) {
return res.status(404).json({ error: 'Not found' });
}

if (!name) {
return res.status(400).json({ error: 'Bad Request' });
}

category.name = name;

await category.save();

return res.status(200).send(category);
} catch (error) {
handleControllerError(res, 'update', error);
}
}

module.exports = {
getAllCategories,
getCategoryById,
remove,
create,
update,
};
Loading
Loading