diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..24d099bfb803cb5d57a5f116b1839295a381b0d5 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,29 @@ +image: node:16 + +stages: + - install + - lint + - test + +cache: + paths: + - node_modules/ + +before_script: + - npm install + +lint: + stage: lint + script: + - npm run lint + only: + - develop + - main + +test: + stage: test + script: + - npm run test + only: + - develop + - main \ No newline at end of file diff --git a/FETCH_HEAD b/FETCH_HEAD new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/index.js b/src/index.js index 441d6f95ffa4de0bbfe069eb952dd50f3cfdc48f..7c815b6f0b49a851ca09044207f9c63e20978473 100644 --- a/src/index.js +++ b/src/index.js @@ -21,6 +21,40 @@ app.get('/api/tasks', (req, res) => { res.json(tasks); }); +// +app.get('/api/tasks/:id', (req, res) => { + const id = req.params.id; + const task = taskService.getTaskById(id); + if (task) { + res.json(task); + } else { + res.status(404).json({ error: 'Tâche non trouvée' }); + } +}); + +app.post('/api/tasks', (req, res) => { + const { description } = req.body; + if (!description) { + return res.status(400).json({ error: 'La description est requise' }); + } + try { + const newTask = taskService.addTask(description); + res.status(201).json(newTask); + } catch (error) { + res.status(500).json({ error: error.message }); + } +}); + +app.delete('/api/tasks/:id', (req, res) => { + const id = req.params.id; + const result = taskService.deleteTask(id); + if (result) { + res.status(204).send(); + } else { + res.status(404).json({ error: 'Tâche non trouvée' }); + } +}); + // Fonction pour démarrer le serveur const startServer = () => { const server = app.listen(port, () => { diff --git a/src/taskService.js b/src/taskService.js index aad0b48d53cc0142b908a33ebbd47eff1da5432c..e564d91f7ec3e0ed6528636d0b446d52dca238d2 100644 --- a/src/taskService.js +++ b/src/taskService.js @@ -4,12 +4,44 @@ const tasks = require('../tasks.json'); +function getTaskById(id) { + const taskId = parseInt(id, 10); + return tasks.find(task => task.id === taskId); +} + //fonction de récupération de toutes les tâches function getAllTasks() { return tasks; } +function addTask(description) { + if (!description) { + throw new Error('La description est requise'); + } + const newId = tasks.reduce((max, task) => task.id > max ? task.id : max, 0) + 1; + const newTask = { + id: newId, + description: description, + done: false + }; + tasks.push(newTask); + return newTask; +} + +function deleteTask(id) { + const taskId = parseInt(id, 10); + const index = tasks.findIndex(task => task.id === taskId); + if (index === -1) { + return false; + } + tasks.splice(index, 1); + return true; +} + //export des fonctions module.exports = { - getAllTasks + getAllTasks, + getTaskById, + addTask, + deleteTask }; diff --git a/tests/integration/app.test.js b/tests/integration/app.test.js index 04c94c89bbff985d5716ca22aaa24ac2509911ef..c83e54605139ac60b816ea0b1f1dceb97fc5fdd9 100644 --- a/tests/integration/app.test.js +++ b/tests/integration/app.test.js @@ -24,3 +24,69 @@ describe('Endpoints de base', () => { }); }); + + +describe('GET /api/tasks/:id', () => { + + // Test pour un ID existant (par exemple, ID = 1) + test('devrait retourner la tâche correspondante pour un ID existant', async () => { + const res = await request(app).get('/api/tasks/1'); + expect(res.statusCode).toEqual(200); + expect(res.body).toEqual({ id: 1, description: 'Apprendre Git', done: false }); + }); + + // Test pour un ID inexistant (par exemple, ID = 999) + test('devrait retourner 404 pour un ID inexistant', async () => { + const res = await request(app).get('/api/tasks/999'); + expect(res.statusCode).toEqual(404); + expect(res.body).toEqual({ error: 'Tâche non trouvée' }); + }); + +}); + +describe('POST /api/tasks', () => { + + test('should create a new task and return it', async () => { + const response = await request(app) + .post('/api/tasks') + .send({ description: "Nouvelle tâche" }); + expect(response.statusCode).toBe(201); + expect(response.body).toHaveProperty('id'); + expect(response.body.description).toBe("Nouvelle tâche"); + expect(response.body.done).toBe(false); + }); + + test('should return 400 if description is missing', async () => { + const response = await request(app) + .post('/api/tasks') + .send({}); + expect(response.statusCode).toBe(400); + expect(response.body).toHaveProperty('error', 'La description est requise'); + }); + +}); + + +describe('DELETE /api/tasks/:id', () => { + + test('should delete an existing task and return 204', async () => { + const addResponse = await request(app) + .post('/api/tasks') + .send({ description: "Task to delete via DELETE endpoint" }); + expect(addResponse.statusCode).toBe(201); + const taskId = addResponse.body.id; + + const deleteResponse = await request(app).delete(`/api/tasks/${taskId}`); + expect(deleteResponse.statusCode).toBe(204); + + const getResponse = await request(app).get(`/api/tasks/${taskId}`); + expect(getResponse.statusCode).toBe(404); + }); + + test('should return 404 when trying to delete a non-existent task', async () => { + const response = await request(app).delete('/api/tasks/99999'); + expect(response.statusCode).toBe(404); + expect(response.body).toEqual({ error: 'Tâche non trouvée' }); + }); + +}); \ No newline at end of file diff --git a/tests/unit/todoService.test.js b/tests/unit/todoService.test.js index 503dafd405abeef2020c5acb8fc75754dbd36ad4..a252acc5b71a8884ba3ebfafeb492b70c4e2320d 100644 --- a/tests/unit/todoService.test.js +++ b/tests/unit/todoService.test.js @@ -1,7 +1,7 @@ //test unitaire des fonctions de service // Import de la fonction à tester -const { getAllTasks } = require('../../src/taskService'); +const { getAllTasks, getTaskById, addTask, deleteTask } = require('../../src/taskService'); //Test de la fonction de récupération de toutes les tâches. test('should return all tasks', () => { @@ -10,3 +10,43 @@ test('should return all tasks', () => { expect(tasks.length).toBeGreaterThan(0); }); +test('should return the correct task for a given id', () => { + const task = getTaskById(1); + expect(task).toEqual({ id: 1, description: 'Apprendre Git', done: false }); +}); + +test('should return undefined for a non-existent task id', () => { + const task = getTaskById(999); + expect(task).toBeUndefined(); +}); + +test('should add a new task with provided description', () => { + const initialLength = getAllTasks().length; + const description = "Nouvelle tâche"; + const newTask = addTask(description); + expect(newTask).toHaveProperty('id'); + expect(newTask.description).toBe(description); + expect(newTask.done).toBe(false); + expect(getAllTasks().length).toBe(initialLength + 1); +}); + +test('should throw an error if description is missing', () => { + expect(() => addTask()).toThrow("La description est requise"); +}); + +test('should delete a task with a valid id', () => { + const initialLength = getAllTasks().length; + + const newTask = addTask("Task to delete"); + expect(getAllTasks().length).toBe(initialLength + 1); + + const result = deleteTask(newTask.id); + expect(result).toBe(true); + + expect(getAllTasks().length).toBe(initialLength); +}); + +test('should return false when deleting a non-existent task', () => { + const result = deleteTask(999); + expect(result).toBe(false); +}); \ No newline at end of file