|
| 1 | +import { describe, expect, it, vi } from 'vitest'; |
| 2 | +import { EnhancedConfigValidator } from '@/services/enhanced-config-validator'; |
| 3 | +import { WorkflowValidator } from '@/services/workflow-validator'; |
| 4 | +import type { NodeRepository } from '@/database/node-repository'; |
| 5 | + |
| 6 | +vi.mock('@/utils/logger'); |
| 7 | + |
| 8 | +describe('WorkflowValidator version-specific schemas', () => { |
| 9 | + it('validates a Notion 2.2 database page against its own schema', async () => { |
| 10 | + const title = { |
| 11 | + displayName: 'Title', |
| 12 | + name: 'title', |
| 13 | + type: 'string', |
| 14 | + default: '', |
| 15 | + required: true, |
| 16 | + displayOptions: { show: { resource: ['databasePage'], operation: ['create'] } }, |
| 17 | + }; |
| 18 | + const properties = [ |
| 19 | + { displayName: 'Resource', name: 'resource', type: 'options', default: 'page' }, |
| 20 | + { displayName: 'Operation', name: 'operation', type: 'options', default: 'create', displayOptions: { show: { resource: ['databasePage'] } } }, |
| 21 | + title, |
| 22 | + ]; |
| 23 | + const repository = { |
| 24 | + getAllNodes: vi.fn(() => []), |
| 25 | + getNode: vi.fn((type: string) => type === 'nodes-base.manualTrigger' |
| 26 | + ? { nodeType: type, displayName: 'Manual Trigger', package: 'n8n-nodes-base', isTrigger: true, isVersioned: false, outputs: ['main'], properties: [] } |
| 27 | + : { nodeType: type, displayName: 'Notion', package: 'n8n-nodes-base', version: 3, isVersioned: true, outputs: ['main'], properties }), |
| 28 | + getNodeVersion: vi.fn(() => ({ propertiesSchema: properties.map(property => property === title ? { ...property, required: false } : property) })), |
| 29 | + } as unknown as NodeRepository; |
| 30 | + const validator = new WorkflowValidator(repository, EnhancedConfigValidator); |
| 31 | + const workflow = { |
| 32 | + name: 'notion-title-expression-repro', |
| 33 | + nodes: [ |
| 34 | + { parameters: {}, id: 'trigger', name: 'Manual Trigger', type: 'n8n-nodes-base.manualTrigger', position: [0, 0], typeVersion: 1 }, |
| 35 | + { |
| 36 | + parameters: { |
| 37 | + resource: 'databasePage', |
| 38 | + databaseId: { __rl: true, mode: 'list', value: '00000000-0000-0000-0000-000000000000', cachedResultName: 'example-db' }, |
| 39 | + propertiesUi: { propertyValues: [ |
| 40 | + { key: 'URL|url', urlValue: "={{ 'https://example.com' + $json.path }}" }, |
| 41 | + { key: 'title|title', title: '={{ $json.title }}' }, |
| 42 | + { key: 'abstract|rich_text', textContent: '={{ $json.abstract }}' }, |
| 43 | + ] }, |
| 44 | + options: {}, |
| 45 | + }, |
| 46 | + id: 'notion', |
| 47 | + name: 'Store Page', |
| 48 | + type: 'n8n-nodes-base.notion', |
| 49 | + position: [220, 0], |
| 50 | + typeVersion: 2.2, |
| 51 | + }, |
| 52 | + ], |
| 53 | + connections: { 'Manual Trigger': { main: [[{ node: 'Store Page', type: 'main', index: 0 }]] } }, |
| 54 | + }; |
| 55 | + |
| 56 | + const result = await validator.validateWorkflow(workflow as any, { profile: 'runtime' }); |
| 57 | + |
| 58 | + expect(result.errors).toEqual([]); |
| 59 | + expect(repository.getNodeVersion).toHaveBeenCalledWith('nodes-base.notion', '2.2'); |
| 60 | + }); |
| 61 | +}); |
0 commit comments