tududi/backend/tests/integration/notes.test.js
Antonis Anastasiadis e594d1075b
Linting cleanup (#99)
* Add eslint and prettier dependencies and configs

* Lint project.
2025-07-01 11:40:09 +03:00

304 lines
10 KiB
JavaScript

const request = require('supertest');
const app = require('../../app');
const { Note, User, Project } = require('../../models');
const { createTestUser } = require('../helpers/testUtils');
describe('Notes Routes', () => {
let user, project, agent;
beforeEach(async () => {
user = await createTestUser({
email: 'test@example.com',
});
project = await Project.create({
name: 'Test Project',
user_id: user.id,
});
// Create authenticated agent
agent = request.agent(app);
await agent.post('/api/login').send({
email: 'test@example.com',
password: 'password123',
});
});
describe('POST /api/note', () => {
it('should create a new note', async () => {
const noteData = {
title: 'Test Note',
content: 'This is a test note content',
project_id: project.id,
};
const response = await agent.post('/api/note').send(noteData);
expect(response.status).toBe(201);
expect(response.body.title).toBe(noteData.title);
expect(response.body.content).toBe(noteData.content);
expect(response.body.project_id).toBe(project.id);
expect(response.body.user_id).toBe(user.id);
});
it('should create note without project', async () => {
const noteData = {
title: 'Test Note',
content: 'This is a test note content',
};
const response = await agent.post('/api/note').send(noteData);
expect(response.status).toBe(201);
expect(response.body.title).toBe(noteData.title);
expect(response.body.content).toBe(noteData.content);
expect(response.body.project_id).toBeNull();
expect(response.body.user_id).toBe(user.id);
});
it('should require authentication', async () => {
const noteData = {
title: 'Test Note',
content: 'Test content',
};
const response = await request(app)
.post('/api/note')
.send(noteData);
expect(response.status).toBe(401);
expect(response.body.error).toBe('Authentication required');
});
});
describe('GET /api/notes', () => {
let note1, note2;
beforeEach(async () => {
note1 = await Note.create({
title: 'Note 1',
content: 'First note content',
user_id: user.id,
project_id: project.id,
});
note2 = await Note.create({
title: 'Note 2',
content: 'Second note content',
user_id: user.id,
});
});
it('should get all user notes', async () => {
const response = await agent.get('/api/notes');
expect(response.status).toBe(200);
expect(Array.isArray(response.body)).toBe(true);
expect(response.body.length).toBe(2);
expect(response.body.map((n) => n.id)).toContain(note1.id);
expect(response.body.map((n) => n.id)).toContain(note2.id);
});
it('should include project information', async () => {
const response = await agent.get('/api/notes');
expect(response.status).toBe(200);
const noteWithProject = response.body.find(
(n) => n.id === note1.id
);
expect(noteWithProject.Project).toBeDefined();
expect(noteWithProject.Project.name).toBe(project.name);
});
it('should return all notes when no filter is applied', async () => {
const response = await agent.get('/api/notes');
expect(response.status).toBe(200);
expect(response.body.length).toBe(2);
expect(response.body.map((n) => n.id)).toContain(note1.id);
expect(response.body.map((n) => n.id)).toContain(note2.id);
});
it('should require authentication', async () => {
const response = await request(app).get('/api/notes');
expect(response.status).toBe(401);
expect(response.body.error).toBe('Authentication required');
});
});
describe('GET /api/note/:id', () => {
let note;
beforeEach(async () => {
note = await Note.create({
title: 'Test Note',
content: 'Test content',
user_id: user.id,
project_id: project.id,
});
});
it('should get note by id', async () => {
const response = await agent.get(`/api/note/${note.id}`);
expect(response.status).toBe(200);
expect(response.body.id).toBe(note.id);
expect(response.body.title).toBe(note.title);
expect(response.body.content).toBe(note.content);
});
it('should return 404 for non-existent note', async () => {
const response = await agent.get('/api/note/999999');
expect(response.status).toBe(404);
expect(response.body.error).toBe('Note not found.');
});
it("should not allow access to other user's notes", async () => {
const bcrypt = require('bcrypt');
const otherUser = await User.create({
email: 'other@example.com',
password_digest: await bcrypt.hash('password123', 10),
});
const otherNote = await Note.create({
title: 'Other Note',
user_id: otherUser.id,
});
const response = await agent.get(`/api/note/${otherNote.id}`);
expect(response.status).toBe(404);
expect(response.body.error).toBe('Note not found.');
});
it('should require authentication', async () => {
const response = await request(app).get(`/api/note/${note.id}`);
expect(response.status).toBe(401);
expect(response.body.error).toBe('Authentication required');
});
});
describe('PATCH /api/note/:id', () => {
let note;
beforeEach(async () => {
note = await Note.create({
title: 'Test Note',
content: 'Test content',
user_id: user.id,
});
});
it('should update note', async () => {
const updateData = {
title: 'Updated Note',
content: 'Updated content',
project_id: project.id,
};
const response = await agent
.patch(`/api/note/${note.id}`)
.send(updateData);
expect(response.status).toBe(200);
expect(response.body.title).toBe(updateData.title);
expect(response.body.content).toBe(updateData.content);
expect(response.body.project_id).toBe(project.id);
});
it('should return 404 for non-existent note', async () => {
const response = await agent
.patch('/api/note/999999')
.send({ title: 'Updated' });
expect(response.status).toBe(404);
expect(response.body.error).toBe('Note not found.');
});
it("should not allow updating other user's notes", async () => {
const bcrypt = require('bcrypt');
const otherUser = await User.create({
email: 'other@example.com',
password_digest: await bcrypt.hash('password123', 10),
});
const otherNote = await Note.create({
title: 'Other Note',
user_id: otherUser.id,
});
const response = await agent
.patch(`/api/note/${otherNote.id}`)
.send({ title: 'Updated' });
expect(response.status).toBe(404);
expect(response.body.error).toBe('Note not found.');
});
it('should require authentication', async () => {
const response = await request(app)
.patch(`/api/note/${note.id}`)
.send({ title: 'Updated' });
expect(response.status).toBe(401);
expect(response.body.error).toBe('Authentication required');
});
});
describe('DELETE /api/note/:id', () => {
let note;
beforeEach(async () => {
note = await Note.create({
title: 'Test Note',
user_id: user.id,
});
});
it('should delete note', async () => {
const response = await agent.delete(`/api/note/${note.id}`);
expect(response.status).toBe(200);
expect(response.body.message).toBe('Note deleted successfully.');
// Verify note is deleted
const deletedNote = await Note.findByPk(note.id);
expect(deletedNote).toBeNull();
});
it('should return 404 for non-existent note', async () => {
const response = await agent.delete('/api/note/999999');
expect(response.status).toBe(404);
expect(response.body.error).toBe('Note not found.');
});
it("should not allow deleting other user's notes", async () => {
const bcrypt = require('bcrypt');
const otherUser = await User.create({
email: 'other@example.com',
password_digest: await bcrypt.hash('password123', 10),
});
const otherNote = await Note.create({
title: 'Other Note',
user_id: otherUser.id,
});
const response = await agent.delete(`/api/note/${otherNote.id}`);
expect(response.status).toBe(404);
expect(response.body.error).toBe('Note not found.');
});
it('should require authentication', async () => {
const response = await request(app).delete(`/api/note/${note.id}`);
expect(response.status).toBe(401);
expect(response.body.error).toBe('Authentication required');
});
});
});