mirror of
https://github.com/n8n-io/n8n.git
synced 2025-02-21 02:56:40 -08:00
syncProjectRelations tests
This commit is contained in:
parent
c9052b3200
commit
a042310a55
|
@ -1,22 +1,31 @@
|
||||||
|
import type { ProjectRelation } from '@n8n/api-types';
|
||||||
|
import type { EntityManager } from '@n8n/typeorm';
|
||||||
import { mock } from 'jest-mock-extended';
|
import { mock } from 'jest-mock-extended';
|
||||||
|
|
||||||
import type { Project } from '@/databases/entities/project';
|
import type { Project } from '@/databases/entities/project';
|
||||||
import { ProjectRepository } from '@/databases/repositories/project.repository';
|
import type { SharedCredentials } from '@/databases/entities/shared-credentials';
|
||||||
import { mockInstance } from '@test/mocking';
|
import type { ProjectRelationRepository } from '@/databases/repositories/project-relation.repository';
|
||||||
|
import type { ProjectRepository } from '@/databases/repositories/project.repository';
|
||||||
|
import type { SharedCredentialsRepository } from '@/databases/repositories/shared-credentials.repository';
|
||||||
|
|
||||||
|
import type { CacheService } from '../cache/cache.service';
|
||||||
import { ProjectService } from '../project.service.ee';
|
import { ProjectService } from '../project.service.ee';
|
||||||
import { RoleService } from '../role.service';
|
import type { RoleService } from '../role.service';
|
||||||
|
|
||||||
describe('UserService', () => {
|
describe('ProjectService', () => {
|
||||||
const projectRepository = mockInstance(ProjectRepository);
|
const manager = mock<EntityManager>();
|
||||||
const roleService = mockInstance(RoleService);
|
const projectRepository = mock<ProjectRepository>();
|
||||||
|
const projectRelationRepository = mock<ProjectRelationRepository>({ manager });
|
||||||
|
const roleService = mock<RoleService>();
|
||||||
|
const sharedCredentialsRepository = mock<SharedCredentialsRepository>();
|
||||||
|
const cacheService = mock<CacheService>();
|
||||||
const projectService = new ProjectService(
|
const projectService = new ProjectService(
|
||||||
mock(),
|
mock(),
|
||||||
projectRepository,
|
projectRepository,
|
||||||
mock(),
|
projectRelationRepository,
|
||||||
roleService,
|
roleService,
|
||||||
mock(),
|
sharedCredentialsRepository,
|
||||||
mock(),
|
cacheService,
|
||||||
mock(),
|
mock(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -51,4 +60,94 @@ describe('UserService', () => {
|
||||||
).rejects.toThrowError("Can't add a personalOwner to a team project.");
|
).rejects.toThrowError("Can't add a personalOwner to a team project.");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('syncProjectRelations', () => {
|
||||||
|
const projectId = '12345';
|
||||||
|
const mockRelations: ProjectRelation[] = [
|
||||||
|
{ userId: 'user1', role: 'project:admin' },
|
||||||
|
{ userId: 'user2', role: 'project:viewer' },
|
||||||
|
];
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
manager.transaction.mockImplementation(async (arg1: unknown, arg2?: unknown) => {
|
||||||
|
const runInTransaction = (arg2 ?? arg1) as (
|
||||||
|
entityManager: EntityManager,
|
||||||
|
) => Promise<unknown>;
|
||||||
|
return await runInTransaction(manager);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should successfully sync project relations', async () => {
|
||||||
|
projectRepository.findOne.mockResolvedValueOnce(
|
||||||
|
mock<Project>({
|
||||||
|
id: projectId,
|
||||||
|
type: 'team',
|
||||||
|
projectRelations: [],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
roleService.isRoleLicensed.mockReturnValue(true);
|
||||||
|
|
||||||
|
sharedCredentialsRepository.find.mockResolvedValueOnce([
|
||||||
|
mock<SharedCredentials>({ credentialsId: 'cred1' }),
|
||||||
|
mock<SharedCredentials>({ credentialsId: 'cred2' }),
|
||||||
|
]);
|
||||||
|
|
||||||
|
await projectService.syncProjectRelations(projectId, mockRelations);
|
||||||
|
|
||||||
|
expect(projectRepository.findOne).toHaveBeenCalledWith({
|
||||||
|
where: { id: projectId, type: 'team' },
|
||||||
|
relations: { projectRelations: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(manager.delete).toHaveBeenCalled();
|
||||||
|
expect(manager.insert).toHaveBeenCalled();
|
||||||
|
expect(cacheService.deleteMany).toHaveBeenCalledWith([
|
||||||
|
'credential-can-use-secrets:cred1',
|
||||||
|
'credential-can-use-secrets:cred2',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw error if project not found', async () => {
|
||||||
|
projectRepository.findOne.mockResolvedValueOnce(null);
|
||||||
|
|
||||||
|
await expect(projectService.syncProjectRelations(projectId, mockRelations)).rejects.toThrow(
|
||||||
|
`Could not find project with ID: ${projectId}`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw error if unlicensed role is used', async () => {
|
||||||
|
projectRepository.findOne.mockResolvedValueOnce(
|
||||||
|
mock<Project>({
|
||||||
|
id: projectId,
|
||||||
|
type: 'team',
|
||||||
|
projectRelations: [],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
roleService.isRoleLicensed.mockReturnValue(false);
|
||||||
|
|
||||||
|
await expect(projectService.syncProjectRelations(projectId, mockRelations)).rejects.toThrow(
|
||||||
|
'Your instance is not licensed to use role "project:admin"',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not throw error for existing role even if unlicensed', async () => {
|
||||||
|
projectRepository.findOne.mockResolvedValueOnce(
|
||||||
|
mock<Project>({
|
||||||
|
id: projectId,
|
||||||
|
type: 'team',
|
||||||
|
projectRelations: [{ userId: 'user1', role: 'project:admin' }],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
roleService.isRoleLicensed.mockReturnValue(false);
|
||||||
|
|
||||||
|
sharedCredentialsRepository.find.mockResolvedValueOnce([]);
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
projectService.syncProjectRelations(projectId, [
|
||||||
|
{ userId: 'user1', role: 'project:admin' },
|
||||||
|
]),
|
||||||
|
).resolves.not.toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue