|
1 | 1 | import { describe, expect, it } from 'vitest' |
| 2 | +import { diffOrderedRows } from '@/app/workspace/[workspaceId]/w/components/workflow-diff/components/change-list/ordered-row-diff' |
2 | 3 | import { getStructuredValuePresentation } from '@/app/workspace/[workspaceId]/w/components/workflow-diff/components/change-list/value-presentation' |
3 | 4 |
|
4 | 5 | describe('structured workflow value presentation', () => { |
5 | | - it('preserves duplicate header rows and order while ignoring editor row IDs and blank starter rows', () => { |
6 | | - const config = { id: 'headers', type: 'table' as const, columns: ['Key', 'Value'] } |
| 6 | + it.each([false, true])( |
| 7 | + 'preserves header order and ignores editor metadata (encoded: %s)', |
| 8 | + (encoded) => { |
| 9 | + const stored = (value: unknown) => (encoded ? JSON.stringify(value) : value) |
| 10 | + const config = { id: 'headers', type: 'table' as const, columns: ['Key', 'Value'] } |
| 11 | + const source = [ |
| 12 | + { id: 'first', cells: { Key: 'X-Mode', Value: 'first' } }, |
| 13 | + { id: 'second', cells: { Key: 'X-Mode', Value: 'last' } }, |
| 14 | + { id: 'blank', cells: { Key: '', Value: '' } }, |
| 15 | + { id: 'empty-value', cells: { Key: 'X-Empty', Value: '' } }, |
| 16 | + ] |
| 17 | + const result = getStructuredValuePresentation(config, 'headers', stored(source))! |
| 18 | + expect(result.columns).toEqual(['Key', 'Value']) |
| 19 | + expect(result.rows.map((row) => row.cells)).toEqual([ |
| 20 | + { Key: 'X-Mode', Value: 'first' }, |
| 21 | + { Key: 'X-Mode', Value: 'last' }, |
| 22 | + { Key: 'X-Empty', Value: '' }, |
| 23 | + ]) |
| 24 | + const recreated = source.map((row, index) => ({ ...row, id: `recreated-${index}` })) |
| 25 | + expect( |
| 26 | + getStructuredValuePresentation(config, 'headers', stored(recreated))?.rows.map( |
| 27 | + (row) => row.key |
| 28 | + ) |
| 29 | + ).toEqual(result.rows.map((row) => row.key)) |
| 30 | + expect( |
| 31 | + getStructuredValuePresentation(config, 'headers', stored([...source].reverse()))?.rows.map( |
| 32 | + (row) => row.key |
| 33 | + ) |
| 34 | + ).not.toEqual(result.rows.map((row) => row.key)) |
| 35 | + } |
| 36 | + ) |
| 37 | + |
| 38 | + it('keeps surviving router rows unchanged when a preceding route is removed', () => { |
| 39 | + const config = { id: 'routes', type: 'router-input' as const } |
7 | 40 | const source = [ |
8 | | - { id: 'first', cells: { Key: 'X-Mode', Value: 'first' } }, |
9 | | - { id: 'second', cells: { Key: 'X-Mode', Value: 'last' } }, |
10 | | - { id: 'blank', cells: { Key: '', Value: '' } }, |
11 | | - { id: 'empty-value', cells: { Key: 'X-Empty', Value: '' } }, |
| 41 | + { id: 'a', value: 'first' }, |
| 42 | + { id: 'b', value: 'second' }, |
| 43 | + { id: 'c', value: 'third' }, |
12 | 44 | ] |
13 | | - const result = getStructuredValuePresentation(config, 'headers', source)! |
14 | | - expect(result.columns).toEqual(['Key', 'Value']) |
15 | | - expect(result.rows.map((row) => row.cells)).toEqual([ |
16 | | - { Key: 'X-Mode', Value: 'first' }, |
17 | | - { Key: 'X-Mode', Value: 'last' }, |
18 | | - { Key: 'X-Empty', Value: '' }, |
| 45 | + const before = getStructuredValuePresentation(config, 'routes', source)! |
| 46 | + const after = getStructuredValuePresentation(config, 'routes', source.slice(1))! |
| 47 | + expect(diffOrderedRows(before.rows, after.rows).map(({ kind }) => kind)).toEqual([ |
| 48 | + 'removed', |
| 49 | + 'context', |
| 50 | + 'context', |
| 51 | + ]) |
| 52 | + const changed = getStructuredValuePresentation(config, 'routes', [ |
| 53 | + { ...source[1], value: 'edited' }, |
| 54 | + source[2], |
| 55 | + ])! |
| 56 | + expect(diffOrderedRows(after.rows, changed.rows).map(({ kind }) => kind)).toEqual([ |
| 57 | + 'removed', |
| 58 | + 'added', |
| 59 | + 'context', |
19 | 60 | ]) |
20 | | - const recreated = source.map((row, index) => ({ ...row, id: `recreated-${index}` })) |
21 | | - expect( |
22 | | - getStructuredValuePresentation(config, 'headers', recreated)?.rows.map((row) => row.key) |
23 | | - ).toEqual(result.rows.map((row) => row.key)) |
24 | | - expect( |
25 | | - getStructuredValuePresentation(config, 'headers', [...source].reverse())?.rows.map( |
26 | | - (row) => row.key |
27 | | - ) |
28 | | - ).not.toEqual(result.rows.map((row) => row.key)) |
29 | 61 | }) |
30 | 62 |
|
31 | 63 | it('keeps secret-only edits distinct before the renderer masks cells', () => { |
|
0 commit comments