mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-18 10:31:15 +00:00
fix(editor): Add "time saved per execution" workflow setting (#13369)
This commit is contained in:
@@ -1,55 +1,61 @@
|
||||
import { createPinia, setActivePinia } from 'pinia';
|
||||
import WorkflowSettingsVue from '@/components/WorkflowSettings.vue';
|
||||
|
||||
import { setupServer } from '@/__tests__/server';
|
||||
import { nextTick, reactive } from 'vue';
|
||||
import { createTestingPinia } from '@pinia/testing';
|
||||
import type { MockInstance } from 'vitest';
|
||||
import { afterAll, beforeAll } from 'vitest';
|
||||
import { within } from '@testing-library/vue';
|
||||
import { within, waitFor } from '@testing-library/vue';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
|
||||
import type { FrontendSettings } from '@n8n/api-types';
|
||||
import { createComponentRenderer } from '@/__tests__/render';
|
||||
import { getDropdownItems, mockedStore, type MockedStore } from '@/__tests__/utils';
|
||||
import { EnterpriseEditionFeature } from '@/constants';
|
||||
import WorkflowSettingsVue from '@/components/WorkflowSettings.vue';
|
||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import { useSettingsStore } from '@/stores/settings.store';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
import { useSourceControlStore } from '@/stores/sourceControl.store';
|
||||
|
||||
import { createComponentRenderer } from '@/__tests__/render';
|
||||
import { cleanupAppModals, createAppModals, getDropdownItems } from '@/__tests__/utils';
|
||||
import { EnterpriseEditionFeature, WORKFLOW_SETTINGS_MODAL_KEY } from '@/constants';
|
||||
vi.mock('vue-router', async () => ({
|
||||
useRouter: vi.fn(),
|
||||
useRoute: () =>
|
||||
reactive({
|
||||
params: {
|
||||
name: '1',
|
||||
},
|
||||
}),
|
||||
RouterLink: {
|
||||
template: '<a><slot /></a>',
|
||||
},
|
||||
}));
|
||||
|
||||
import { nextTick } from 'vue';
|
||||
import type { IWorkflowDb } from '@/Interface';
|
||||
import * as permissions from '@/permissions';
|
||||
import type { PermissionsRecord } from '@/permissions';
|
||||
|
||||
let pinia: ReturnType<typeof createPinia>;
|
||||
let workflowsStore: ReturnType<typeof useWorkflowsStore>;
|
||||
let settingsStore: ReturnType<typeof useSettingsStore>;
|
||||
let uiStore: ReturnType<typeof useUIStore>;
|
||||
let workflowsStore: MockedStore<typeof useWorkflowsStore>;
|
||||
let settingsStore: MockedStore<typeof useSettingsStore>;
|
||||
let sourceControlStore: MockedStore<typeof useSourceControlStore>;
|
||||
let pinia: ReturnType<typeof createTestingPinia>;
|
||||
|
||||
let fetchAllWorkflowsSpy: MockInstance<(typeof workflowsStore)['fetchAllWorkflows']>;
|
||||
|
||||
const createComponent = createComponentRenderer(WorkflowSettingsVue);
|
||||
const createComponent = createComponentRenderer(WorkflowSettingsVue, {
|
||||
global: {
|
||||
stubs: {
|
||||
Modal: {
|
||||
template:
|
||||
'<div role="dialog"><slot name="header" /><slot name="content" /><slot name="footer" /></div>',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
describe('WorkflowSettingsVue', () => {
|
||||
let server: ReturnType<typeof setupServer>;
|
||||
beforeAll(() => {
|
||||
server = setupServer();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
pinia = createPinia();
|
||||
setActivePinia(pinia);
|
||||
pinia = createTestingPinia();
|
||||
workflowsStore = mockedStore(useWorkflowsStore);
|
||||
settingsStore = mockedStore(useSettingsStore);
|
||||
sourceControlStore = mockedStore(useSourceControlStore);
|
||||
|
||||
createAppModals();
|
||||
|
||||
workflowsStore = useWorkflowsStore();
|
||||
settingsStore = useSettingsStore();
|
||||
uiStore = useUIStore();
|
||||
|
||||
await settingsStore.getSettings();
|
||||
|
||||
vi.spyOn(workflowsStore, 'workflowName', 'get').mockReturnValue('Test Workflow');
|
||||
vi.spyOn(workflowsStore, 'workflowId', 'get').mockReturnValue('1');
|
||||
fetchAllWorkflowsSpy = vi.spyOn(workflowsStore, 'fetchAllWorkflows').mockResolvedValue([
|
||||
settingsStore.settings = {
|
||||
enterprise: {},
|
||||
} as FrontendSettings;
|
||||
workflowsStore.workflowName = 'Test Workflow';
|
||||
workflowsStore.workflowId = '1';
|
||||
fetchAllWorkflowsSpy = workflowsStore.fetchAllWorkflows.mockResolvedValue([
|
||||
{
|
||||
id: '1',
|
||||
name: 'Test Workflow',
|
||||
@@ -61,7 +67,7 @@ describe('WorkflowSettingsVue', () => {
|
||||
versionId: '123',
|
||||
},
|
||||
]);
|
||||
vi.spyOn(workflowsStore, 'getWorkflowById').mockReturnValue({
|
||||
workflowsStore.getWorkflowById.mockImplementation(() => ({
|
||||
id: '1',
|
||||
name: 'Test Workflow',
|
||||
active: true,
|
||||
@@ -70,24 +76,12 @@ describe('WorkflowSettingsVue', () => {
|
||||
createdAt: 1,
|
||||
updatedAt: 1,
|
||||
versionId: '123',
|
||||
} as IWorkflowDb);
|
||||
vi.spyOn(permissions, 'getResourcePermissions').mockReturnValue({
|
||||
workflow: {
|
||||
update: true,
|
||||
},
|
||||
} as PermissionsRecord);
|
||||
|
||||
uiStore.modalsById[WORKFLOW_SETTINGS_MODAL_KEY] = {
|
||||
open: true,
|
||||
};
|
||||
scopes: ['workflow:update'],
|
||||
}));
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
cleanupAppModals();
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
server.shutdown();
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should render correctly', async () => {
|
||||
@@ -220,4 +214,79 @@ describe('WorkflowSettingsVue', () => {
|
||||
expect(dropdownItems[0]).toHaveTextContent(optionText);
|
||||
},
|
||||
);
|
||||
|
||||
it('should save time saved per execution correctly', async () => {
|
||||
const { getByTestId, getByRole } = createComponent({ pinia });
|
||||
await nextTick();
|
||||
|
||||
const timeSavedPerExecutionInput = getByTestId('workflow-settings-time-saved-per-execution');
|
||||
|
||||
expect(timeSavedPerExecutionInput).toBeVisible();
|
||||
|
||||
await userEvent.type(timeSavedPerExecutionInput as Element, '10');
|
||||
expect(timeSavedPerExecutionInput).toHaveValue(10);
|
||||
|
||||
await userEvent.click(getByRole('button', { name: 'Save' }));
|
||||
expect(workflowsStore.updateWorkflow).toHaveBeenCalledWith(
|
||||
expect.any(String),
|
||||
expect.objectContaining({ settings: expect.objectContaining({ timeSavedPerExecution: 10 }) }),
|
||||
);
|
||||
});
|
||||
|
||||
it('should remove time saved per execution setting', async () => {
|
||||
workflowsStore.workflowSettings.timeSavedPerExecution = 10;
|
||||
|
||||
const { getByTestId, getByRole } = createComponent({ pinia });
|
||||
await nextTick();
|
||||
|
||||
const timeSavedPerExecutionInput = getByTestId('workflow-settings-time-saved-per-execution');
|
||||
|
||||
expect(timeSavedPerExecutionInput).toBeVisible();
|
||||
await waitFor(() => expect(timeSavedPerExecutionInput).toHaveValue(10));
|
||||
|
||||
await userEvent.clear(timeSavedPerExecutionInput as Element);
|
||||
expect(timeSavedPerExecutionInput).not.toHaveValue();
|
||||
|
||||
await userEvent.click(getByRole('button', { name: 'Save' }));
|
||||
expect(workflowsStore.updateWorkflow).toHaveBeenCalledWith(
|
||||
expect.any(String),
|
||||
expect.objectContaining({
|
||||
settings: expect.not.objectContaining({ timeSavedPerExecution: 10 }),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('should disable save time saved per execution if env is read-only', async () => {
|
||||
sourceControlStore.preferences.branchReadOnly = true;
|
||||
|
||||
const { getByTestId } = createComponent({ pinia });
|
||||
await nextTick();
|
||||
|
||||
const timeSavedPerExecutionInput = getByTestId('workflow-settings-time-saved-per-execution');
|
||||
|
||||
expect(timeSavedPerExecutionInput).toBeVisible();
|
||||
expect(timeSavedPerExecutionInput).toBeDisabled();
|
||||
});
|
||||
|
||||
it('should disable save time saved per execution if user has no permission to update workflow', async () => {
|
||||
workflowsStore.getWorkflowById.mockImplementation(() => ({
|
||||
id: '1',
|
||||
name: 'Test Workflow',
|
||||
active: true,
|
||||
nodes: [],
|
||||
connections: {},
|
||||
createdAt: 1,
|
||||
updatedAt: 1,
|
||||
versionId: '123',
|
||||
scopes: ['workflow:read'],
|
||||
}));
|
||||
|
||||
const { getByTestId } = createComponent({ pinia });
|
||||
await nextTick();
|
||||
|
||||
const timeSavedPerExecutionInput = getByTestId('workflow-settings-time-saved-per-execution');
|
||||
|
||||
expect(timeSavedPerExecutionInput).toBeVisible();
|
||||
expect(timeSavedPerExecutionInput).toBeDisabled();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user