Files
n8n-enterprise-unlocked/packages/cli/test/integration/database/repositories/project.repository.test.ts
Csaba Tuncsik 596c472ecc feat: RBAC (#8922)
Signed-off-by: Oleg Ivaniv <me@olegivaniv.com>
Co-authored-by: Val <68596159+valya@users.noreply.github.com>
Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ <aditya@netroy.in>
Co-authored-by: Valya Bullions <valya@n8n.io>
Co-authored-by: Danny Martini <danny@n8n.io>
Co-authored-by: Danny Martini <despair.blue@gmail.com>
Co-authored-by: Iván Ovejero <ivov.src@gmail.com>
Co-authored-by: Omar Ajoue <krynble@gmail.com>
Co-authored-by: oleg <me@olegivaniv.com>
Co-authored-by: Michael Kret <michael.k@radency.com>
Co-authored-by: Michael Kret <88898367+michael-radency@users.noreply.github.com>
Co-authored-by: Elias Meire <elias@meire.dev>
Co-authored-by: Giulio Andreini <andreini@netseven.it>
Co-authored-by: Giulio Andreini <g.andreini@gmail.com>
Co-authored-by: Ayato Hayashi <go12limchangyong@gmail.com>
2024-05-17 10:53:15 +02:00

156 lines
4.3 KiB
TypeScript

import Container from 'typedi';
import { createMember, createOwner } from '../../shared/db/users';
import * as testDb from '../../shared/testDb';
import { ProjectRepository } from '@/databases/repositories/project.repository';
import { EntityNotFoundError } from '@n8n/typeorm';
import { createTeamProject } from '../../shared/db/projects';
import { AuthIdentity } from '@/databases/entities/AuthIdentity';
import { UserRepository } from '@/databases/repositories/user.repository';
describe('ProjectRepository', () => {
beforeAll(async () => {
await testDb.init();
});
beforeEach(async () => {
await testDb.truncate(['User', 'Workflow', 'Project']);
});
afterAll(async () => {
await testDb.terminate();
});
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 createTeamProject(undefined, 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 createTeamProject(undefined, owner);
//
// ACT
//
const promise = Container.get(ProjectRepository).getPersonalProjectForUserOrFail(owner.id);
//
// ASSERT
//
await expect(promise).rejects.toThrowError(EntityNotFoundError);
});
});
describe('update personal project name', () => {
// TypeORM enters an infinite loop if you create entities with circular
// references and pass this to the `Repository.create` function.
//
// This actually happened in combination with SAML.
// `samlHelpers.updateUserFromSamlAttributes` and
// `samlHelpers.createUserFromSamlAttributes` would create a User and an
// AuthIdentity and assign them to one another. Then it would call
// `UserRepository.save(user)`. This would then call the UserSubscriber in
// `database/entities/Project.ts` which would pass the circular User into
// `UserRepository.create` and cause the infinite loop.
//
// This test simulates that behavior and makes sure the UserSubscriber
// checks if the entity is already a user and does not pass it into
// `UserRepository.create` in that case.
test('do not pass a User instance with circular references into `UserRepository.create`', async () => {
//
// ARRANGE
//
const user = await createMember();
const authIdentity = new AuthIdentity();
authIdentity.providerId = user.email;
authIdentity.providerType = 'saml';
authIdentity.user = user;
user.firstName = `updated ${user.firstName}`;
user.authIdentities = [];
user.authIdentities.push(authIdentity);
//
// ACT & ASSERT
//
await expect(Container.get(UserRepository).save(user)).resolves.not.toThrow();
});
});
});