This project is a full-stack Todo application built with the MERN (MongoDB, Express.js, React, Node.js) stack.
Run the following command to clone the repository:
git clone https://github.com/alokyadav1/mern-todo-app.git
Go to frontend
and backend
directories to install packages:
cd frontend
npm install
cd backend
npm install
Create a .env
file inside the backend
directory and copy the following code:
MONGO_URI=Your mongodb URI
GMAIL_USERNAME=your gmail address
GMAIL_PASSWORD=password created inside 'App Password' section under google accounts setting
PORT=8000
JWT_SECRET=a random secret key eg. thisisasecretkey
Go to backend
and frontend
directories and start the server:
cd backend
nodemon server
cd frontend
npm start
The development of this project is managed using version control with three main branches representing different stages of the development lifecycle:
-
Development Branch:
- All new features and enhancements are first implemented and tested in the development branch.
- This branch is the active area for ongoing development activities.
-
Testing Branch:
- Once features are developed, they are merged into the testing branch.
- This branch is used for rigorous testing to ensure the stability and reliability of the features.
- Only thoroughly tested code is promoted from this branch.
-
Deployment (Main) Branch:
- The main branch contains the production-ready code.
- Only fully tested and approved features from the testing branch are merged here.
- This branch is deployed to the production environment.
- Task Management:
- Create, update, and delete tasks.
- Mark tasks as complete or incomplete.
- Mailing Feature:
- Automated email alerts to notify users when a task is due.
- MERN Stack:
- MongoDB: Database
- Express.js: Web framework for Node.js
- React: Front-end library
- Node.js: JavaScript runtime environment
- Endpoint:
/api/user/register
- Method: POST
- Request Body:
{ "name": "John Doe", "email": "johndoe@example.com", "password": "Password123!" }
- Response:
{ "user": { "_id": "user_id", "name": "John Doe", "email": "johndoe@example.com" }, "token": "jwt_token" }
- Endpoint:
/api/user/login
- Method: POST
- Request Body:
{ "email": "johndoe@example.com", "password": "Password123!" }
- Response:
{ "user": { "_id": "user_id", "name": "John Doe", "email": "johndoe@example.com" }, "token": "jwt_token" }
- Endpoint:
/api/user/getuser
- Method: GET
- Headers:
{ "Authorization": "Bearer jwt_token" }
- Response:
{ "user": { "_id": "user_id", "name": "John Doe", "email": "johndoe@example.com" } }
- Endpoint:
/api/task/addTask
- Method: POST
- Headers:
{ "Authorization": "Bearer jwt_token" }
- Request Body:
{ "title": "New Task", "description": "Task description", "dueDate": "2024-05-25T00:00:00.000Z" }
- Response:
{ "message": "Task added successfully" }
- Endpoint:
/api/task/getTask
- Method: GET
- Headers:
{ "Authorization": "Bearer jwt_token" }
- Response:
[ { "_id": "task_id", "title": "New Task", "description": "Task description", "completed": false, "dueDate": "2024-05-25T00:00:00.000Z", "userId": "user_id", "createdAt": "2024-05-24T00:00:00.000Z", "updatedAt": "2024-05-24T00:00:00.000Z" } ]
- Endpoint:
/api/task/editTask/:taskId
- Method: PUT
- Headers:
{ "Authorization": "Bearer jwt_token" }
- Request Body:
{ "title": "Updated Task", "description": "Updated description", "completed": true, "dueDate": "2024-06-25T00:00:00.000Z" }
- Response:
{ "_id": "task_id", "title": "Updated Task", "description": "Updated description", "completed": true, "dueDate": "2024-06-25T00:00:00.000Z", "userId": "user_id", "createdAt": "2024-05-24T00:00:00.000Z", "updatedAt": "2024-05-25T00:00:00.000Z" }
- Endpoint:
/api/task/removeTask/:taskId
- Method: DELETE
- Headers:
{ "Authorization": "Bearer jwt_token" }
- Response:
{ "message": "Task deleted successfully" }
- Endpoint:
/api/forgotPassword/forgotPassword
- Method: POST
- Request Body:
{ "email": "johndoe@example.com" }
- Response:
{ "message": "A link to reset your password has been sent to your email." }
- Endpoint:
/api/forgotPassword/resetPassword
- Method: POST
- Request Body:
{ "token": "reset_token", "password": "NewPassword123!" }
- Response:
{ "message": "Password reset successful" }
To run end-to-end tests using Jest, Supertest, and mongodb-memory-server, follow these steps:
-
Install testing dependencies:
npm install --save-dev jest supertest mongodb-memory-server
-
Update
package.json
: Add Jest configuration and a test script.{ "scripts": { "test": "jest" }, "jest": { "testEnvironment": "node", "setupFilesAfterEnv": ["<rootDir>/test/setup.js"] } }
-
Create test setup file (
test/setup.js
):const { MongoMemoryServer } = require('mongodb-memory-server'); const mongoose = require('mongoose'); const dotenv = require('dotenv'); dotenv.config(); let mongoServer; beforeAll(async () => { mongoServer = await MongoMemoryServer.create(); const uri = mongoServer.getUri(); await mongoose.connect(uri, { useNewUrlParser: true, useUnifiedTopology: true, }); }); afterAll(async () => { await mongoose.disconnect(); await mongoServer.stop(); }); afterEach(async () => { const collections = mongoose.connection.collections; for (const key in collections) { await collections[key].deleteMany({}); } });
-
Create test files in
test
directory:- Create
test/user.test.js
,test/task.test.js
, andtest/forgotPassword.test.js
as detailed in the previous section.
- Create
-
Run tests:
npm test
This setup ensures comprehensive testing of the user, task, and forgot password functionalities, providing confidence in the stability and reliability of your application.