mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-27 13:39:44 -08:00
596c472ecc
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>
196 lines
6 KiB
TypeScript
196 lines
6 KiB
TypeScript
import { OwnershipService } from '@/services/ownership.service';
|
|
import { SharedWorkflowRepository } from '@db/repositories/sharedWorkflow.repository';
|
|
import { SharedWorkflow } from '@db/entities/SharedWorkflow';
|
|
import { User } from '@db/entities/User';
|
|
import type { SharedCredentials } from '@db/entities/SharedCredentials';
|
|
import { mockInstance } from '../../shared/mocking';
|
|
import { WorkflowEntity } from '@/databases/entities/WorkflowEntity';
|
|
import { UserRepository } from '@/databases/repositories/user.repository';
|
|
import { mock } from 'jest-mock-extended';
|
|
import { Project } from '@/databases/entities/Project';
|
|
import { ProjectRelationRepository } from '@/databases/repositories/projectRelation.repository';
|
|
import { ProjectRelation } from '@/databases/entities/ProjectRelation';
|
|
import { mockCredential, mockProject } from '../shared/mockObjects';
|
|
|
|
describe('OwnershipService', () => {
|
|
const userRepository = mockInstance(UserRepository);
|
|
const sharedWorkflowRepository = mockInstance(SharedWorkflowRepository);
|
|
const projectRelationRepository = mockInstance(ProjectRelationRepository);
|
|
const ownershipService = new OwnershipService(
|
|
mock(),
|
|
userRepository,
|
|
mock(),
|
|
projectRelationRepository,
|
|
sharedWorkflowRepository,
|
|
);
|
|
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
|
|
describe('getWorkflowProjectCached()', () => {
|
|
test('should retrieve a workflow owner project', async () => {
|
|
const mockProject = new Project();
|
|
|
|
const sharedWorkflow = Object.assign(new SharedWorkflow(), {
|
|
role: 'workflow:owner',
|
|
project: mockProject,
|
|
});
|
|
|
|
sharedWorkflowRepository.findOneOrFail.mockResolvedValueOnce(sharedWorkflow);
|
|
|
|
const returnedProject = await ownershipService.getWorkflowProjectCached('some-workflow-id');
|
|
|
|
expect(returnedProject).toBe(mockProject);
|
|
});
|
|
|
|
test('should throw if no workflow owner project found', async () => {
|
|
sharedWorkflowRepository.findOneOrFail.mockRejectedValue(new Error());
|
|
|
|
await expect(ownershipService.getWorkflowProjectCached('some-workflow-id')).rejects.toThrow();
|
|
});
|
|
});
|
|
|
|
describe('getProjectOwnerCached()', () => {
|
|
test('should retrieve a project owner', async () => {
|
|
const mockProject = new Project();
|
|
const mockOwner = new User();
|
|
|
|
const projectRelation = Object.assign(new ProjectRelation(), {
|
|
role: 'project:personalOwner',
|
|
project: mockProject,
|
|
user: mockOwner,
|
|
});
|
|
|
|
projectRelationRepository.getPersonalProjectOwners.mockResolvedValueOnce([projectRelation]);
|
|
|
|
const returnedOwner = await ownershipService.getProjectOwnerCached('some-project-id');
|
|
|
|
expect(returnedOwner).toBe(mockOwner);
|
|
});
|
|
|
|
test('should not throw if no project owner found, should return null instead', async () => {
|
|
projectRelationRepository.getPersonalProjectOwners.mockResolvedValueOnce([]);
|
|
|
|
const owner = await ownershipService.getProjectOwnerCached('some-project-id');
|
|
|
|
expect(owner).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe('getProjectOwnerCached()', () => {
|
|
test('should retrieve a project owner', async () => {
|
|
const mockProject = new Project();
|
|
const mockOwner = new User();
|
|
|
|
const projectRelation = Object.assign(new ProjectRelation(), {
|
|
role: 'project:personalOwner',
|
|
project: mockProject,
|
|
user: mockOwner,
|
|
});
|
|
|
|
projectRelationRepository.getPersonalProjectOwners.mockResolvedValueOnce([projectRelation]);
|
|
|
|
const returnedOwner = await ownershipService.getProjectOwnerCached('some-project-id');
|
|
|
|
expect(returnedOwner).toBe(mockOwner);
|
|
});
|
|
|
|
test('should not throw if no project owner found, should return null instead', async () => {
|
|
projectRelationRepository.getPersonalProjectOwners.mockResolvedValueOnce([]);
|
|
|
|
const owner = await ownershipService.getProjectOwnerCached('some-project-id');
|
|
|
|
expect(owner).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe('addOwnedByAndSharedWith()', () => {
|
|
test('should add `ownedBy` and `sharedWith` to credential', async () => {
|
|
const ownerProject = mockProject();
|
|
const editorProject = mockProject();
|
|
|
|
const credential = mockCredential();
|
|
|
|
credential.shared = [
|
|
{ role: 'credential:owner', project: ownerProject },
|
|
{ role: 'credential:editor', project: editorProject },
|
|
] as SharedCredentials[];
|
|
|
|
const { homeProject, sharedWithProjects } =
|
|
ownershipService.addOwnedByAndSharedWith(credential);
|
|
|
|
expect(homeProject).toMatchObject({
|
|
id: ownerProject.id,
|
|
name: ownerProject.name,
|
|
type: ownerProject.type,
|
|
});
|
|
|
|
expect(sharedWithProjects).toMatchObject([
|
|
{
|
|
id: editorProject.id,
|
|
name: editorProject.name,
|
|
type: editorProject.type,
|
|
},
|
|
]);
|
|
});
|
|
|
|
test('should add `ownedBy` and `sharedWith` to workflow', async () => {
|
|
const projectOwner = mockProject();
|
|
const projectEditor = mockProject();
|
|
|
|
const workflow = new WorkflowEntity();
|
|
|
|
workflow.shared = [
|
|
{ role: 'workflow:owner', project: projectOwner },
|
|
{ role: 'workflow:editor', project: projectEditor },
|
|
] as SharedWorkflow[];
|
|
|
|
const { homeProject, sharedWithProjects } =
|
|
ownershipService.addOwnedByAndSharedWith(workflow);
|
|
|
|
expect(homeProject).toMatchObject({
|
|
id: projectOwner.id,
|
|
name: projectOwner.name,
|
|
type: projectOwner.type,
|
|
});
|
|
expect(sharedWithProjects).toMatchObject([
|
|
{
|
|
id: projectEditor.id,
|
|
name: projectEditor.name,
|
|
type: projectEditor.type,
|
|
},
|
|
]);
|
|
});
|
|
|
|
test('should produce an empty sharedWith if no sharee', async () => {
|
|
const credential = mockCredential();
|
|
|
|
const project = mockProject();
|
|
|
|
credential.shared = [{ role: 'credential:owner', project }] as SharedCredentials[];
|
|
|
|
const { homeProject, sharedWithProjects } =
|
|
ownershipService.addOwnedByAndSharedWith(credential);
|
|
|
|
expect(homeProject).toMatchObject({
|
|
id: project.id,
|
|
name: project.name,
|
|
type: project.type,
|
|
});
|
|
|
|
expect(sharedWithProjects).toHaveLength(0);
|
|
});
|
|
});
|
|
|
|
describe('getInstanceOwner()', () => {
|
|
test('should find owner using global owner role ID', async () => {
|
|
await ownershipService.getInstanceOwner();
|
|
|
|
expect(userRepository.findOneOrFail).toHaveBeenCalledWith({
|
|
where: { role: 'global:owner' },
|
|
});
|
|
});
|
|
});
|
|
});
|