Skip to content

Commit fd9da49

Browse files
committed
chore: improve check for input source, handle empty rows
1 parent 409c447 commit fd9da49

File tree

2 files changed

+122
-37
lines changed

2 files changed

+122
-37
lines changed

packages/backend/src/apps/toolbox/__tests__/common/get-for-each-variables.test.ts

Lines changed: 109 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -53,27 +53,29 @@ describe('get-for-each-variables', () => {
5353
})
5454

5555
describe('processItems', () => {
56-
it('should process tiles data (with rowId)', () => {
56+
it('should process tiles data (with UUID column IDs)', () => {
57+
const col1Id = randomUUID()
58+
const col2Id = randomUUID()
5759
const mockData = {
5860
rows: [
5961
{
6062
data: {
61-
[randomUUID()]: 'Value 1',
62-
[randomUUID()]: 'Value 2',
63+
[col1Id]: 'Value 1',
64+
[col2Id]: 'Value 2',
6365
},
6466
rowId: randomUUID(),
6567
},
6668
{
6769
data: {
68-
[randomUUID()]: 3,
69-
[randomUUID()]: 4,
70+
[col1Id]: 3,
71+
[col2Id]: 4,
7072
},
7173
rowId: randomUUID(),
7274
},
7375
],
7476
columns: [
75-
{ id: 'col1', name: 'Column 1' },
76-
{ id: 'col2', name: 'Column 2' },
77+
{ id: col1Id, name: 'Column 1' },
78+
{ id: col2Id, name: 'Column 2' },
7779
],
7880
}
7981

@@ -84,14 +86,58 @@ describe('get-for-each-variables', () => {
8486
expect(result.processedItems.rows).toEqual(mockData.rows)
8587
expect(result.processedItems.columns).toEqual([
8688
{
87-
id: 'col1',
89+
id: col1Id,
8890
name: 'Column 1',
89-
value: `items.rows.${FOR_EACH_ITERATION_KEY}.data.col1`,
91+
value: `items.rows.${FOR_EACH_ITERATION_KEY}.data.${col1Id}`,
9092
},
9193
{
92-
id: 'col2',
94+
id: col2Id,
9395
name: 'Column 2',
94-
value: `items.rows.${FOR_EACH_ITERATION_KEY}.data.col2`,
96+
value: `items.rows.${FOR_EACH_ITERATION_KEY}.data.${col2Id}`,
97+
},
98+
{
99+
id: 'rowId',
100+
name: 'Row ID',
101+
value: `items.rows.${FOR_EACH_ITERATION_KEY}.rowId`,
102+
},
103+
])
104+
})
105+
106+
it('should process tiles data (with ULID column IDs)', () => {
107+
// ULID format: 26 characters, base32 encoded
108+
const col1Id = '01ARZ3NDEKTSV4RRFFQ69G5FAV'
109+
const col2Id = '01BX5ZZKBKACTAV9WEVGEMMVS0'
110+
const mockData = {
111+
rows: [
112+
{
113+
data: {
114+
[col1Id]: 'Value 1',
115+
[col2Id]: 'Value 2',
116+
},
117+
rowId: '01ARZ3NDEKTSV4RRFFQ69G5FAX',
118+
},
119+
],
120+
columns: [
121+
{ id: col1Id, name: 'Column 1' },
122+
{ id: col2Id, name: 'Column 2' },
123+
],
124+
}
125+
126+
const result = processItems(mockData)
127+
128+
expect(result.iterations).toBe(1)
129+
expect(result.inputSource).toBe('tiles')
130+
expect(result.processedItems.rows).toEqual(mockData.rows)
131+
expect(result.processedItems.columns).toEqual([
132+
{
133+
id: col1Id,
134+
name: 'Column 1',
135+
value: `items.rows.${FOR_EACH_ITERATION_KEY}.data.${col1Id}`,
136+
},
137+
{
138+
id: col2Id,
139+
name: 'Column 2',
140+
value: `items.rows.${FOR_EACH_ITERATION_KEY}.data.${col2Id}`,
95141
},
96142
{
97143
id: 'rowId',
@@ -101,7 +147,7 @@ describe('get-for-each-variables', () => {
101147
])
102148
})
103149

104-
it('should process m365-excel data (without rowId)', () => {
150+
it('should process m365-excel data (with regular column IDs)', () => {
105151
const mockData = {
106152
rows: [
107153
{
@@ -142,6 +188,32 @@ describe('get-for-each-variables', () => {
142188
])
143189
})
144190

191+
it('should handle empty tiles rows', () => {
192+
const col1Id = randomUUID()
193+
const mockData = {
194+
rows: [] as any[],
195+
columns: [{ id: col1Id, name: 'Column 1' }],
196+
}
197+
198+
const result = processItems(mockData)
199+
200+
expect(result.iterations).toBe(0)
201+
expect(result.inputSource).toBe('tiles')
202+
expect(result.processedItems.rows).toEqual([])
203+
expect(result.processedItems.columns).toEqual([
204+
{
205+
id: col1Id,
206+
name: 'Column 1',
207+
value: `items.rows.${FOR_EACH_ITERATION_KEY}.data.${col1Id}`,
208+
},
209+
{
210+
id: 'rowId',
211+
name: 'Row ID',
212+
value: `items.rows.${FOR_EACH_ITERATION_KEY}.rowId`,
213+
},
214+
])
215+
})
216+
145217
it('should handle empty rows', () => {
146218
const mockData = {
147219
rows: [] as any[],
@@ -151,7 +223,7 @@ describe('get-for-each-variables', () => {
151223
const result = processItems(mockData)
152224

153225
expect(result.iterations).toBe(0)
154-
expect(result.inputSource).toBe(null)
226+
expect(result.inputSource).toBe('m365-excel')
155227
expect(result.processedItems.rows).toEqual([])
156228
expect(result.processedItems.columns).toEqual([
157229
{
@@ -176,28 +248,23 @@ describe('get-for-each-variables', () => {
176248
const result = processItems(mockData)
177249

178250
expect(result.iterations).toBe(1)
179-
expect(result.inputSource).toBe('tiles')
251+
expect(result.inputSource).toBe(null)
180252
expect(result.processedItems.rows).toEqual(mockData.rows)
181-
expect(result.processedItems.columns).toEqual([
182-
{
183-
id: 'rowId',
184-
name: 'Row ID',
185-
value: `items.rows.${FOR_EACH_ITERATION_KEY}.rowId`,
186-
},
187-
])
253+
expect(result.processedItems.columns).toEqual([])
188254
})
189255

190-
it('should handle single row', () => {
256+
it('should handle single row with UUID column', () => {
257+
const colId = randomUUID()
191258
const mockData = {
192259
rows: [
193260
{
194261
data: {
195-
'single-col': 'Single Value',
262+
[colId]: 'Single Value',
196263
},
197264
rowId: 'single-row',
198265
},
199266
],
200-
columns: [{ id: 'single-col', name: 'Single Column' }],
267+
columns: [{ id: colId, name: 'Single Column' }],
201268
}
202269

203270
const result = processItems(mockData)
@@ -206,9 +273,9 @@ describe('get-for-each-variables', () => {
206273
expect(result.inputSource).toBe('tiles')
207274
expect(result.processedItems.columns).toEqual([
208275
{
209-
id: 'single-col',
276+
id: colId,
210277
name: 'Single Column',
211-
value: `items.rows.${FOR_EACH_ITERATION_KEY}.data.single-col`,
278+
value: `items.rows.${FOR_EACH_ITERATION_KEY}.data.${colId}`,
212279
},
213280
{
214281
id: 'rowId',
@@ -218,18 +285,27 @@ describe('get-for-each-variables', () => {
218285
])
219286
})
220287

221-
it('should determine input source correctly based on rowId presence', () => {
222-
// Test with tiles (has rowId)
288+
it('should determine input source correctly based on column ID format', () => {
289+
// Test with tiles (UUID column IDs)
290+
const uuidCol = randomUUID()
223291
const tilesData = {
224-
rows: [{ data: {}, rowId: 'test' }],
225-
columns: [] as any[],
292+
rows: [{ data: { [uuidCol]: 'test' }, rowId: 'test' }],
293+
columns: [{ id: uuidCol, name: 'UUID Column' }],
226294
}
227295
expect(processItems(tilesData).inputSource).toBe('tiles')
228296

229-
// Test with m365-excel (no rowId)
297+
// Test with tiles (ULID column IDs)
298+
const ulidCol = '01ARZ3NDEKTSV4RRFFQ69G5FAV'
299+
const ulidData = {
300+
rows: [{ data: { [ulidCol]: 'test' }, rowId: 'test' }],
301+
columns: [{ id: ulidCol, name: 'ULID Column' }],
302+
}
303+
expect(processItems(ulidData).inputSource).toBe('tiles')
304+
305+
// Test with m365-excel (regular column IDs)
230306
const excelData = {
231-
rows: [{ data: {} }],
232-
columns: [] as any[],
307+
rows: [{ data: { col1: 'test' } }],
308+
columns: [{ id: 'col1', name: 'Regular Column' }],
233309
}
234310
expect(processItems(excelData).inputSource).toBe('m365-excel')
235311
})

packages/backend/src/apps/toolbox/common/get-for-each-variables.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ interface MultipleRowObject {
1919
columns: any[]
2020
}
2121

22+
const ULID_REGEX = /^[0-9A-HJKMNP-TV-Z]{26}$/i
23+
const UUID_REGEX =
24+
/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/
25+
2226
export function isCheckboxItems(items: string[]): boolean {
2327
return Array.isArray(items) && items.every((item) => typeof item === 'string')
2428
}
@@ -31,6 +35,14 @@ function processColumns(data: MultipleRowObject): {
3135
let inputSource = null
3236

3337
data.columns.forEach((column: any) => {
38+
// NOTE: we cam tell if its a tile column by its column id
39+
// tiles will either have uuid or ulid as column id
40+
if (ULID_REGEX.test(column.id) || UUID_REGEX.test(column.id)) {
41+
inputSource = FOR_EACH_INPUT_SOURCE.TILES
42+
} else {
43+
inputSource = FOR_EACH_INPUT_SOURCE.M365_EXCEL
44+
}
45+
3446
processedColumns.push({
3547
id: column.id,
3648
name: column.name,
@@ -39,15 +51,12 @@ function processColumns(data: MultipleRowObject): {
3951
})
4052

4153
// NOTE: only tiles will have rowId
42-
if (data.rows[0]?.rowId) {
54+
if (inputSource === FOR_EACH_INPUT_SOURCE.TILES) {
4355
processedColumns.push({
4456
id: 'rowId',
4557
name: 'Row ID',
4658
value: `items.rows.${FOR_EACH_ITERATION_KEY}.rowId`,
4759
})
48-
inputSource = FOR_EACH_INPUT_SOURCE.TILES
49-
} else if (data.rows.length > 0) {
50-
inputSource = FOR_EACH_INPUT_SOURCE.M365_EXCEL
5160
}
5261

5362
return { inputSource, processedColumns }

0 commit comments

Comments
 (0)