Skip to content

Commit

Permalink
Merge pull request #165 from codex-team/feat/return-team-with-note-se…
Browse files Browse the repository at this point in the history
…ttings

Feat: return team with note settings
  • Loading branch information
kloV148 authored Feb 13, 2024
2 parents 74e5b45 + 658fc88 commit 63d49bb
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 19 deletions.
8 changes: 8 additions & 0 deletions src/domain/entities/noteSettings.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import type { Team } from './team.js';


/**
* Invitation hash. It's used to invite users to team
*/
Expand Down Expand Up @@ -31,6 +34,11 @@ export default interface NoteSettings {
* Invitation hash
*/
invitationHash: InvitationHash;

/**
* Team members. Team is empty by default because note creator is not stored in team
*/
team?: Team;
}

/**
Expand Down
10 changes: 6 additions & 4 deletions src/domain/service/noteSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,20 @@ export default class NoteSettingsService {
}

/**
* Returns settings for a note with passed id
* Returns settings for a note with all team members
*
* @param id - note internal id
*/
public async getNoteSettingsByNoteId(id: NoteInternalId): Promise<NoteSettings> {
const settings = await this.noteSettingsRepository.getNoteSettingsByNoteId(id);
const noteSettings = await this.noteSettingsRepository.getNoteSettingsByNoteId(id);

if (settings === null) {
if (noteSettings === null) {
throw new DomainError(`Note settings not found`);
}

return settings;
noteSettings.team = await this.teamRepository.getTeamMembersByNoteId(id);

return noteSettings;
}

/**
Expand Down
33 changes: 29 additions & 4 deletions src/presentation/http/router/noteSettings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ import noteSettings from '@tests/test-data/notes-settings.json';
describe('NoteSettings API', () => {
describe('GET /note-settings/:notePublicId ', () => {
test('Returns note settings by public id with 200 status', async () => {
const existingNotePublicId = 'Pq1T9vc23Q';
const existingNotePublicId = 'f43NU75weU';

const expectedNoteSettings = {
'customHostname': 'codex.so',
'id': 54,
'invitationHash': 'FfAwyaR80C',
'isPublic': true,
'id': 3,
'noteId': 3,
'invitationHash': 'E2zRXv3cp-',
'noteId': 54,
'team': [],
};

const response = await global.api?.fakeRequest({
Expand All @@ -26,6 +27,30 @@ describe('NoteSettings API', () => {
expect(response?.json()).toStrictEqual(expectedNoteSettings);
});

test('Returns team with note settings by public id with 200 status', async () => {
const existingNotePublicId = 'Pq1T9vc23Q';

const response = await global.api?.fakeRequest({
method: 'GET',
url: `/note-settings/${existingNotePublicId}`,
});

expect(response?.statusCode).toBe(200);

expect(response?.json().team).toStrictEqual([
{
'id': 2,
'role': 0,
'user': {
'email': '[email protected]',
'id': 1,
'name': 'Test user 1',
'photo': null,
},
},
]);
});

test('Returns 404 when note settings with specified note public id do not exist', async () => {
const nonexistentId = 'ishvm5qH84';

Expand Down
10 changes: 1 addition & 9 deletions src/presentation/http/router/noteSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import type { FastifyPluginCallback } from 'fastify';
import type NoteSettingsService from '@domain/service/noteSettings.js';
import type NoteSettings from '@domain/entities/noteSettings.js';
import type { InvitationHash } from '@domain/entities/noteSettings.js';
import { isEmpty } from '@infrastructure/utils/empty.js';
import useNoteResolver from '../middlewares/note/useNoteResolver.js';
import type NoteService from '@domain/service/note.js';
import useNoteSettingsResolver from '../middlewares/noteSettings/useNoteSettingsResolver.js';
Expand Down Expand Up @@ -58,7 +57,7 @@ const NoteSettingsRouter: FastifyPluginCallback<NoteSettingsRouterOptions> = (fa
Params: {
notePublicId: NotePublicId;
},
Reply: NoteSettings
Reply: NoteSettings,
}>('/:notePublicId', {
config: {
policy: [
Expand All @@ -81,13 +80,6 @@ const NoteSettingsRouter: FastifyPluginCallback<NoteSettingsRouterOptions> = (fa

const noteSettings = await noteSettingsService.getNoteSettingsByNoteId(noteId);

/**
* Check if note does not exist
*/
if (isEmpty(noteSettings)) {
return reply.notFound('Note settings not found');
}

return reply.send(noteSettings);
});

Expand Down
20 changes: 20 additions & 0 deletions src/presentation/http/schema/NoteSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,25 @@ export const NoteSettingsSchema = {
maxLength: 10,
minLength: 10,
},
team: {
type: 'array',
items: {
type: 'object',
properties: {
id: {
type: 'number',
},
noteId: {
type: 'number',
},
userId: {
type: 'number',
},
role: {
type: 'number',
},
},
},
},
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ export default class NoteSettingsSequelizeStorage {
where: {
noteId: noteId,
},
raw: true,
});

if (!settings) {
Expand Down
27 changes: 25 additions & 2 deletions src/repository/storage/postgres/orm/sequelize/teams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { UserModel } from './user.js';
import { MemberRole } from '@domain/entities/team.js';
import type User from '@domain/entities/user.js';
import type { NoteInternalId } from '@domain/entities/note.js';

import { DomainError } from '@domain/entities/DomainError.js';

/**
* Class representing a teams model in database
Expand Down Expand Up @@ -140,7 +140,7 @@ export default class TeamsSequelizeStorage {
*/
this.model.belongsTo(model, {
foreignKey: 'userId',
as: this.userModel.tableName,
as: 'user',
});
}

Expand Down Expand Up @@ -207,6 +207,29 @@ export default class TeamsSequelizeStorage {
});
}

/**
* Get all team members by note id with info about users
*
* @param noteId - note id to get all team members
* @returns team with additional info
*/
public async getTeamMembersByNoteId(noteId: NoteInternalId): Promise<Team> {
if (!this.userModel) {
throw new DomainError('User model not initialized');
}

return await this.model.findAll({
where: { noteId },
attributes: ['id', 'role'],
include: {
model: this.userModel,
as: 'user',
required: true,
attributes: ['id', 'name', 'email', 'photo'],
},
});
}

/**
* Remove team member by id
*
Expand Down
10 changes: 10 additions & 0 deletions src/repository/team.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,16 @@ export default class TeamRepository {
return await this.storage.getMembersByNoteId(noteId);
}

/**
* Get all team members by note id with info about users
*
* @param noteId - note id to get all team members
* @returns team with additional info
*/
public async getTeamMembersByNoteId(noteId: NoteInternalId): Promise<Team> {
return await this.storage.getTeamMembersByNoteId(noteId);
};

/**
* Remove team member by id
*
Expand Down

0 comments on commit 63d49bb

Please sign in to comment.