Files
n8n-enterprise-unlocked/packages/editor-ui/src/views/TestDefinition/tests/TestDefinitionEditView.test.ts
2025-02-21 12:58:28 +01:00

117 lines
3.8 KiB
TypeScript

import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { createTestingPinia } from '@pinia/testing';
import { createComponentRenderer } from '@/__tests__/render';
import TestDefinitionEditView from '@/views/TestDefinition/TestDefinitionEditView.vue';
import type { useTestDefinitionForm } from '@/components/TestDefinition/composables/useTestDefinitionForm';
import { ref } from 'vue';
import { cleanupAppModals, createAppModals, mockedStore } from '@/__tests__/utils';
import { useTestDefinitionStore } from '@/stores/testDefinition.store.ee';
import userEvent from '@testing-library/user-event';
const form: Partial<ReturnType<typeof useTestDefinitionForm>> = {
state: ref({
name: { value: '', isEditing: false, tempValue: '' },
description: { value: '', isEditing: false, tempValue: '' },
tags: { value: [], tempValue: [], isEditing: false },
evaluationWorkflow: { mode: 'list', value: '', __rl: true },
metrics: [],
mockedNodes: [],
}),
loadTestData: vi.fn(),
cancelEditing: vi.fn(),
updateTest: vi.fn(),
startEditing: vi.fn(),
saveChanges: vi.fn(),
deleteMetric: vi.fn(),
updateMetrics: vi.fn(),
createTest: vi.fn(),
};
vi.mock('@/components/TestDefinition/composables/useTestDefinitionForm', () => ({
useTestDefinitionForm: () => form,
}));
const renderComponent = createComponentRenderer(TestDefinitionEditView, {
props: { testId: '1', name: 'workflow-name' },
});
describe('TestDefinitionEditView', () => {
beforeEach(() => {
createTestingPinia();
createAppModals();
});
afterEach(() => {
vi.clearAllMocks();
cleanupAppModals();
});
it('should load test data', async () => {
renderComponent();
expect(form.loadTestData).toHaveBeenCalledWith('1', 'workflow-name');
});
it('should display disabled "run test" button when editing test without tags', async () => {
const testDefinitionStore = mockedStore(useTestDefinitionStore);
testDefinitionStore.getFieldIssues.mockReturnValueOnce([
{ field: 'tags', message: 'Tag is required' },
]);
const { getByTestId } = renderComponent();
const updateButton = getByTestId('run-test-button');
expect(updateButton.textContent?.toLowerCase()).toContain('run test');
expect(updateButton).toHaveClass('disabled');
});
it('should apply "has-issues" class to inputs with issues', async () => {
const testDefinitionStore = mockedStore(useTestDefinitionStore);
testDefinitionStore.getFieldIssues.mockReturnValueOnce([
{ field: 'evaluationWorkflow', message: 'No evaluation workflow set' },
]);
const { container } = renderComponent();
const issueElements = container.querySelectorAll('.has-issues');
expect(issueElements.length).toBeGreaterThan(0);
});
describe('Test Runs functionality', () => {
it('should display test runs table when runs exist', async () => {
const testDefinitionStore = mockedStore(useTestDefinitionStore);
testDefinitionStore.testRunsById = {
run1: {
id: 'run1',
testDefinitionId: '1',
status: 'completed',
runAt: '2023-01-01',
createdAt: '2023-01-01',
updatedAt: '2023-01-01',
completedAt: '2023-01-01',
failedCases: 0,
passedCases: 1,
totalCases: 1,
},
};
const { getByTestId } = renderComponent();
expect(getByTestId('past-runs-table')).toBeInTheDocument();
});
it('should not display test runs table when no runs exist', async () => {
const { queryByTestId } = renderComponent();
expect(queryByTestId('past-runs-table')).not.toBeInTheDocument();
});
it('should start a test run when run test button is clicked', async () => {
const testDefinitionStore = mockedStore(useTestDefinitionStore);
const { getByTestId } = renderComponent();
await userEvent.click(getByTestId('run-test-button'));
expect(testDefinitionStore.startTestRun).toHaveBeenCalledWith('1');
expect(testDefinitionStore.fetchTestRuns).toHaveBeenCalledWith('1');
});
});
});