diff --git a/src/presentation/http/router/noteList.test.ts b/src/presentation/http/router/noteList.test.ts index edb11ed0..6e997ed5 100644 --- a/src/presentation/http/router/noteList.test.ts +++ b/src/presentation/http/router/noteList.test.ts @@ -157,6 +157,8 @@ describe('GET /notes/:parentNoteId?page', () => { expectedMessage: null, expectedLength: 30, pageNumber: 1, + isTeamMember: false, + isPublic: true, }, /** * Returns noteList with specified length (for last page) @@ -168,6 +170,8 @@ describe('GET /notes/:parentNoteId?page', () => { expectedMessage: null, expectedLength: 19, pageNumber: 2, + isTeamMember: false, + isPublic: true, }, /** * Returns noteList with no items if there are no notes for certain parentNote @@ -179,6 +183,8 @@ describe('GET /notes/:parentNoteId?page', () => { expectedMessage: null, expectedLength: 0, pageNumber: 3, + isTeamMember: false, + isPublic: true, }, /** * Returns 'querystring/page must be >= 1' message when page < 0 @@ -189,6 +195,8 @@ describe('GET /notes/:parentNoteId?page', () => { expectedMessage: 'querystring/page must be >= 1', expectedLength: 0, pageNumber: -1, + isTeamMember: false, + isPublic: true, }, /** * Returns 'querystring/page must be <= 30' message when page is too large (maximum page numbrer is 30 by default) @@ -199,6 +207,8 @@ describe('GET /notes/:parentNoteId?page', () => { expectedMessage: 'querystring/page must be <= 30', expectedLength: 0, pageNumber: 31, + isTeamMember: false, + isPublic: true, }, /** * Returns 'unauthorized' message when user is not authorized @@ -209,30 +219,69 @@ describe('GET /notes/:parentNoteId?page', () => { expectedMessage: 'You must be authenticated to access this resource', expectedLength: 0, pageNumber: 1, + isTeamMember: false, + isPublic: true, }, - ])('Get note list', async ({ isAuthorized, expectedStatusCode, expectedMessage, expectedLength, pageNumber }) => { + /** + * Returns noteList if user is in team + * User is authorized + */ + { + isAuthorized: true, + expectedStatusCode: 200, + expectedMessage: null, + expectedLength: 30, + pageNumber: 1, + isTeamMember: true, + isPublic: false, + }, + /** + * Returns error message with no items if user is not in team + * User is authorized + */ + { + isAuthorized: true, + expectedStatusCode: 403, + expectedMessage: 'Permission denied', + expectedLength: 0, + pageNumber: 1, + isTeamMember: false, + isPublic: false, + }, + ])('Get note list', async ({ isAuthorized, expectedStatusCode, expectedMessage, expectedLength, pageNumber, isTeamMember, isPublic }) => { const portionSize = 49; let accessToken; - /** Insert creator and randomGuy */ + /** Insert creator */ const creator = await global.db.insertUser(); - const randomGuy = await global.db.insertUser(); - - if (isAuthorized) { - accessToken = global.auth(randomGuy.id); - } - + /** Insert Note */ const parentNote = await global.db.insertNote({ creatorId: creator.id, }); - await global.db.insertNoteSetting({ + const noteSetting = await global.db.insertNoteSetting({ noteId: parentNote.id, cover: 'DZnvqi63.png', - isPublic: true, + isPublic: isPublic, }); + const randomGuy = await global.db.insertUser(); + + if (isAuthorized) { + accessToken = global.auth(randomGuy.id); + } + + if (isTeamMember) { + await global.api?.fakeRequest({ + method: 'POST', + headers: { + authorization: `Bearer ${accessToken}`, + }, + url: `/join/${noteSetting.invitationHash}`, + }); + } + for (let i = 0; i < portionSize; i++) { const note = await global.db.insertNote({ creatorId: creator.id, diff --git a/src/presentation/http/router/noteList.ts b/src/presentation/http/router/noteList.ts index 7a95ffc2..46fd8276 100644 --- a/src/presentation/http/router/noteList.ts +++ b/src/presentation/http/router/noteList.ts @@ -141,11 +141,8 @@ const NoteListRouter: FastifyPluginCallback = (fastify, o description: 'Query notelist', properties: { items: { - id: { type: 'string' }, - content: { type: 'string' }, - createdAt: { type: 'string' }, - creatorId: { type: 'string' }, - updatedAt: { type: 'string' }, + type: 'array', + items: { $ref: 'NoteSchema#' }, }, }, }, diff --git a/src/repository/storage/postgres/orm/sequelize/note.ts b/src/repository/storage/postgres/orm/sequelize/note.ts index c00e5a9b..7a1457db 100644 --- a/src/repository/storage/postgres/orm/sequelize/note.ts +++ b/src/repository/storage/postgres/orm/sequelize/note.ts @@ -161,7 +161,7 @@ export default class NoteSequelizeStorage { this.relationsModel = model; this.model.hasMany(this.relationsModel, { - foreignKey: 'parentId', + foreignKey: 'noteId', as: 'noteRelations', }); } @@ -373,27 +373,34 @@ export default class NoteSequelizeStorage { throw new Error('Note settings model not initialized'); } - const childNotes = await this.relationsModel.findAll({ - where: { parentId }, - attributes: ['noteId'], - }); - - const noteIds = childNotes.map(relation => relation.noteId); - const reply = await this.model.findAll({ - where: { - id: { - [Op.in]: noteIds, + include: [ + { + model: this.relationsModel, + as: 'noteRelations', + where: { + parentId, + }, + duplicating: false, + attributes: [], }, - }, - include: [{ - model: this.settingsModel, - as: 'noteSettings', - attributes: ['cover'], - duplicating: false, - }], - offset, - limit, + { + model: this.settingsModel, + as: 'noteSettings', + attributes: ['cover'], + duplicating: false, + }, + ], + order: [[ + { + model: this.relationsModel, + as: 'noteRelations', + }, + 'id', + 'DESC', + ]], + offset: offset, + limit: limit, }); return reply.map((note) => {