diff --git a/src/presentation/http/router/note.test.ts b/src/presentation/http/router/note.test.ts index f45272f5..f7a911b9 100644 --- a/src/presentation/http/router/note.test.ts +++ b/src/presentation/http/router/note.test.ts @@ -1,6 +1,7 @@ import { MemberRole } from '@domain/entities/team.js'; import { describe, test, expect, beforeEach } from 'vitest'; import type User from '@domain/entities/user.js'; +import type { Note } from '@domain/entities/note.js'; describe('Note API', () => { /** @@ -2284,64 +2285,85 @@ describe('Note API', () => { accessToken = global.auth(user.id); }); - test('Get note hierarchy with no parent or child', async () => { - /** - * Insert test note, note history record will be inserted automatically - */ - const note = await global.db.insertNote({ - creatorId: user.id, - }); - - const response = await global.api?.fakeRequest({ - method: 'GET', - headers: { - authorization: `Bearer ${accessToken}`, - }, - url: `/note/note-hierarchy/${note.publicId}`, - }); - - expect(response?.json().notehierarchy.id).toBe(note.publicId); - expect(response?.json().notehierarchy.childNotes).toHaveLength(0); - }); + test.each([ + // Test case 1: No parent or child + { + description: 'Get note hierarchy with no parent or child', + setup: async () => { + const note = await global.db.insertNote({ creatorId: user.id }); - test('Get note hierarchy with child', async () => { - /* create test child note */ - const childNote = await global.db.insertNote({ - creatorId: user.id, - }); + await global.db.insertNoteSetting({ + noteId: note.id, + isPublic: true, + }); - /* create test parent note */ - const parentNote = await global.db.insertNote({ - creatorId: user.id, - }); + return { + note: note, + childNote: null, + }; + }, - /* create note settings for child note */ - await global.db.insertNoteSetting({ - noteId: childNote.id, - isPublic: true, - }); + expected: (note: Note, childNote: Note | null) => ({ + id: note.publicId, + content: note.content, + childNotes: childNote, + }), + }, - /* create test relation */ - await global.db.insertNoteRelation({ - noteId: childNote.id, - parentId: parentNote.id, - }); + // Test case 2: With child + { + description: 'Get note hierarchy with child', + setup: async () => { + const childNote = await global.db.insertNote({ creatorId: user.id }); + const parentNote = await global.db.insertNote({ creatorId: user.id }); + + await global.db.insertNoteSetting({ + noteId: childNote.id, + isPublic: true, + }); + await global.db.insertNoteSetting({ + noteId: parentNote.id, + isPublic: true, + }); + await global.db.insertNoteRelation({ + noteId: childNote.id, + parentId: parentNote.id, + }); + + return { + note: parentNote, + childNote: childNote, + }; + }, + expected: (note: Note, childNote: Note | null) => ({ + id: note.publicId, + content: note.content, + childNotes: [ + { + id: childNote?.publicId, + content: childNote?.content, + childNotes: null, + }, + ], + }), + }, + ])('$description', async ({ setup, expected }) => { + // Setup the test data + const { note, childNote } = await setup(); + // Make the API request const response = await global.api?.fakeRequest({ method: 'GET', headers: { authorization: `Bearer ${accessToken}`, }, - url: `/note/note-hierarchy/${parentNote.publicId}`, + url: `/note/note-hierarchy/${note.publicId}`, }); - const childNoteObj = { - id: childNote.publicId, - content: childNote.content, - childNotes: [], - }; - - expect(response?.json().notehierarchy.childNotes[0]).toStrictEqual(childNoteObj); + // Verify the response + expect(response?.json().noteHierarchy).toStrictEqual( + expected(note, childNote) + ); }); }); }); diff --git a/src/presentation/http/router/note.ts b/src/presentation/http/router/note.ts index 76a1823e..f6cb0492 100644 --- a/src/presentation/http/router/note.ts +++ b/src/presentation/http/router/note.ts @@ -782,12 +782,12 @@ const NoteRouter: FastifyPluginCallback = (fastify, opts, don notePublicId: NotePublicId; }; Reply: { - notehierarchy: NoteHierarchy | null; + noteHierarchy: NoteHierarchy | null; } | ErrorResponse; }>('/note-hierarchy/:notePublicId', { config: { policy: [ - 'authRequired', + 'notePublicOrUserInTeam', ], }, schema: { @@ -800,7 +800,7 @@ const NoteRouter: FastifyPluginCallback = (fastify, opts, don '2xx': { type: 'object', properties: { - notehierarchy: { + noteHierarchy: { $ref: 'NoteHierarchySchema#', }, }, @@ -809,21 +809,23 @@ const NoteRouter: FastifyPluginCallback = (fastify, opts, don }, preHandler: [ noteResolver, + noteSettingsResolver, + memberRoleResolver, ], }, async (request, reply) => { - const noteId = request?.note?.id as number; + const noteId = request.note?.id as number; /** * Check if note exists */ if (noteId === null) { - return reply.notFound('Note not found'); + return reply.notAcceptable('Note not found'); } const noteHierarchy = await noteService.getNoteHierarchy(noteId); return reply.send({ - notehierarchy: noteHierarchy, + noteHierarchy: noteHierarchy, }); }); diff --git a/src/repository/storage/postgres/orm/sequelize/note.ts b/src/repository/storage/postgres/orm/sequelize/note.ts index 912957a4..b621ffc9 100644 --- a/src/repository/storage/postgres/orm/sequelize/note.ts +++ b/src/repository/storage/postgres/orm/sequelize/note.ts @@ -407,7 +407,7 @@ export default class NoteSequelizeStorage { notesMap.set(note.noteid, { id: note.public_id, content: note.content, - childNotes: [], + childNotes: null, }); }); @@ -419,6 +419,10 @@ export default class NoteSequelizeStorage { const parent = notesMap.get(note.parent_id); if (parent) { + // Initialize childNotes as an array if it's null + if (parent.childNotes === null) { + parent.childNotes = []; + } parent.childNotes?.push(notesMap.get(note.noteid)!); } }