From a278f59a6766aad29748ae81e48aa2779b23e5e4 Mon Sep 17 00:00:00 2001 From: Danny Martini Date: Tue, 20 Feb 2024 12:29:57 +0100 Subject: [PATCH] fix ProjectRepository.getPersonalProjectForUser[OrFail] It was not taking the type of the project and the role the user has to the project into account. --- .../repositories/project.repository.ts | 8 +- .../repositories/project.repository.test.ts | 143 ++++++++++++++++++ 2 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 packages/cli/test/integration/database/repositories/project.repository.test.ts diff --git a/packages/cli/src/databases/repositories/project.repository.ts b/packages/cli/src/databases/repositories/project.repository.ts index 93fa393923664..c02535dc69665 100644 --- a/packages/cli/src/databases/repositories/project.repository.ts +++ b/packages/cli/src/databases/repositories/project.repository.ts @@ -9,10 +9,14 @@ export class ProjectRepository extends Repository { } async getPersonalProjectForUser(userId: string) { - return await this.findOne({ where: { projectRelations: { userId } } }); + return await this.findOne({ + where: { type: 'personal', projectRelations: { userId, role: 'project:personalOwner' } }, + }); } async getPersonalProjectForUserOrFail(userId: string) { - return await this.findOneOrFail({ where: { projectRelations: { userId } } }); + return await this.findOneOrFail({ + where: { type: 'personal', projectRelations: { userId, role: 'project:personalOwner' } }, + }); } } diff --git a/packages/cli/test/integration/database/repositories/project.repository.test.ts b/packages/cli/test/integration/database/repositories/project.repository.test.ts new file mode 100644 index 0000000000000..eebb81377a8c9 --- /dev/null +++ b/packages/cli/test/integration/database/repositories/project.repository.test.ts @@ -0,0 +1,143 @@ +import Container from 'typedi'; +import { createOwner } from '../../shared/db/users'; +import * as testDb from '../../shared/testDb'; +import { ProjectRepository } from '@/databases/repositories/project.repository'; +import type { DeepPartial } from 'ts-essentials'; +import type { Project } from '@/databases/entities/Project'; +import { ProjectRelationRepository } from '@/databases/repositories/projectRelation.repository'; +import { User } from '@/databases/entities/User'; +import { createPromptModule } from 'inquirer'; +import { ApplicationError } from 'n8n-workflow'; +import { EntityNotFoundError } from '@n8n/typeorm'; + +describe('ProjectRepository', () => { + beforeAll(async () => { + await testDb.init(); + }); + + beforeEach(async () => { + await testDb.truncate(['User', 'Workflow', 'Project']); + }); + + afterAll(async () => { + await testDb.terminate(); + }); + + async function createProject(user: User, project?: DeepPartial) { + const projectRepository = Container.get(ProjectRepository); + const projectRelationRepository = Container.get(ProjectRelationRepository); + + const savedProject = await projectRepository.save( + projectRepository.create({ + name: 'project name', + type: 'team', + ...project, + }), + ); + await projectRelationRepository.save( + projectRelationRepository.create({ + userId: user.id, + projectId: savedProject.id, + role: 'project:personalOwner', + }), + ); + + return savedProject; + } + + describe('getPersonalProjectForUser', () => { + it('returns the personal project', async () => { + // + // ARRANGE + // + const owner = await createOwner(); + const ownerPersonalProject = await Container.get(ProjectRepository).findOneByOrFail({ + projectRelations: { userId: owner.id }, + }); + + // + // ACT + // + const personalProject = await Container.get(ProjectRepository).getPersonalProjectForUser( + owner.id, + ); + + // + // ASSERT + // + if (!personalProject) { + fail('Expected personalProject to be defined.'); + } + expect(personalProject).toBeDefined(); + expect(personalProject.id).toBe(ownerPersonalProject.id); + }); + + it('does not return non personal projects', async () => { + // + // ARRANGE + // + const owner = await createOwner(); + await Container.get(ProjectRepository).delete({}); + await createProject(owner); + + // + // ACT + // + const personalProject = await Container.get(ProjectRepository).getPersonalProjectForUser( + owner.id, + ); + + // + // ASSERT + // + expect(personalProject).toBeNull(); + }); + }); + + describe('getPersonalProjectForUserOrFail', () => { + it('returns the personal project', async () => { + // + // ARRANGE + // + const owner = await createOwner(); + const ownerPersonalProject = await Container.get(ProjectRepository).findOneByOrFail({ + projectRelations: { userId: owner.id }, + }); + + // + // ACT + // + const personalProject = await Container.get( + ProjectRepository, + ).getPersonalProjectForUserOrFail(owner.id); + + // + // ASSERT + // + if (!personalProject) { + fail('Expected personalProject to be defined.'); + } + expect(personalProject).toBeDefined(); + expect(personalProject.id).toBe(ownerPersonalProject.id); + }); + + it('does not return non personal projects', async () => { + // + // ARRANGE + // + const owner = await createOwner(); + await Container.get(ProjectRepository).delete({}); + await createProject(owner); + + // + // ACT + // + const promise = Container.get(ProjectRepository).getPersonalProjectForUserOrFail(owner.id); + + // + // ASSERT + // + await expect(promise).rejects.toThrowError(EntityNotFoundError); + }); + }); +});