mirror of
https://github.com/n8n-io/n8n.git
synced 2026-06-03 10:17:00 +02:00
fix(editor): Prevent evaluations tab crash on unsaved workflows (#30744)
This commit is contained in:
parent
d5d619c452
commit
3ee618b35b
|
|
@ -18,6 +18,10 @@ import { EVALUATION_NODE_TYPE, EVALUATION_TRIGGER_NODE_TYPE, NodeHelpers } from
|
|||
import { mockNodeTypeDescription } from '@/__tests__/mocks';
|
||||
import type { SourceControlPreferences } from '@/features/integrations/sourceControl.ee/sourceControl.types';
|
||||
|
||||
const { showError } = vi.hoisted(() => ({
|
||||
showError: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('vue-router', () => ({
|
||||
useRoute: () => ({
|
||||
query: {},
|
||||
|
|
@ -38,7 +42,7 @@ vi.mock('@/app/composables/useTelemetry', () => {
|
|||
|
||||
vi.mock('@/app/composables/useToast', () => ({
|
||||
useToast: () => ({
|
||||
showError: vi.fn(),
|
||||
showError,
|
||||
showMessage: vi.fn(),
|
||||
}),
|
||||
}));
|
||||
|
|
@ -92,6 +96,8 @@ describe('EvaluationsRootView', () => {
|
|||
createTestingPinia();
|
||||
vi.clearAllMocks();
|
||||
|
||||
mockedStore(useWorkflowsStore).isWorkflowSaved = { [mockWorkflow.id]: true };
|
||||
|
||||
vi.spyOn(NodeHelpers, 'getNodeParameters').mockReturnValue({
|
||||
assignments: {
|
||||
assignments: [
|
||||
|
|
@ -125,6 +131,24 @@ describe('EvaluationsRootView', () => {
|
|||
expect(evaluationStore.fetchTestRuns).toHaveBeenCalledWith(mockWorkflow.id);
|
||||
});
|
||||
|
||||
it('should not fetch test runs for an unsaved workflow', async () => {
|
||||
const workflowsStore = mockedStore(useWorkflowsStore);
|
||||
const usageStore = mockedStore(useUsageStore);
|
||||
const evaluationStore = mockedStore(useEvaluationStore);
|
||||
|
||||
workflowsStore.isWorkflowSaved = {};
|
||||
usageStore.getLicenseInfo.mockResolvedValue(undefined);
|
||||
evaluationStore.fetchTestRuns.mockRejectedValue(new Error('Workflow not found'));
|
||||
|
||||
renderComponent({ props: { workflowId: mockWorkflow.id } });
|
||||
|
||||
await flushPromises();
|
||||
|
||||
expect(usageStore.getLicenseInfo).toHaveBeenCalled();
|
||||
expect(evaluationStore.fetchTestRuns).not.toHaveBeenCalled();
|
||||
expect(showError).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should load test data', async () => {
|
||||
const evaluationStore = mockedStore(useEvaluationStore);
|
||||
evaluationStore.fetchTestRuns.mockResolvedValue(mockTestRuns);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { useToast } from '@/app/composables/useToast';
|
|||
import { useI18n } from '@n8n/i18n';
|
||||
import { useEvaluationStore } from '../evaluation.store';
|
||||
import { useSourceControlStore } from '@/features/integrations/sourceControl.ee/sourceControl.store';
|
||||
import { useWorkflowsStore } from '@/app/stores/workflows.store';
|
||||
|
||||
import { computed, watch } from 'vue';
|
||||
import EvaluationsPaywall from '../components/Paywall/EvaluationsPaywall.vue';
|
||||
|
|
@ -19,6 +20,7 @@ const props = defineProps<{
|
|||
|
||||
const usageStore = useUsageStore();
|
||||
const evaluationStore = useEvaluationStore();
|
||||
const workflowsStore = useWorkflowsStore();
|
||||
const telemetry = useTelemetry();
|
||||
const toast = useToast();
|
||||
const locale = useI18n();
|
||||
|
|
@ -32,6 +34,8 @@ const isProtectedEnvironment = computed(() => {
|
|||
return sourceControlStore.preferences.branchReadOnly;
|
||||
});
|
||||
|
||||
const workflowIsSaved = computed(() => workflowsStore.isWorkflowSaved[props.workflowId] === true);
|
||||
|
||||
const runs = computed(() => {
|
||||
return Object.values(evaluationStore.testRunsById ?? {}).filter(
|
||||
({ workflowId }) => workflowId === props.workflowId,
|
||||
|
|
@ -46,6 +50,8 @@ const showWizard = computed(() => !hasRuns.value);
|
|||
|
||||
// Method to run a test - will be used by the SetupWizard component
|
||||
async function runTest() {
|
||||
if (!workflowIsSaved.value) return;
|
||||
|
||||
try {
|
||||
await evaluationStore.startTestRun(props.workflowId);
|
||||
} catch (error) {
|
||||
|
|
@ -67,15 +73,32 @@ const evaluationsQuotaExceeded = computed(() => {
|
|||
);
|
||||
});
|
||||
|
||||
const { isReady } = useAsyncState(async () => {
|
||||
async function fetchTestRuns() {
|
||||
if (!workflowIsSaved.value) return;
|
||||
|
||||
try {
|
||||
await usageStore.getLicenseInfo();
|
||||
await evaluationStore.fetchTestRuns(props.workflowId);
|
||||
} catch (error) {
|
||||
toast.showError(error, locale.baseText('evaluation.listRuns.error.cantFetchTestRuns'));
|
||||
}
|
||||
}
|
||||
|
||||
const { isReady } = useAsyncState(async () => {
|
||||
try {
|
||||
await usageStore.getLicenseInfo();
|
||||
} catch (error) {
|
||||
toast.showError(error, locale.baseText('evaluation.listRuns.error.cantFetchTestRuns'));
|
||||
}
|
||||
|
||||
await fetchTestRuns();
|
||||
}, undefined);
|
||||
|
||||
watch(workflowIsSaved, async (isSaved) => {
|
||||
if (isSaved) {
|
||||
await fetchTestRuns();
|
||||
}
|
||||
});
|
||||
|
||||
watch(
|
||||
isReady,
|
||||
(ready) => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user