Skip to content

Commit cd44be6

Browse files
authored
Database blob (#210)
* Integrate database blob diff and lazy row loading * chore: load blob * chore: fix cell render * chore: create csv api endpoint * chore: add test * chore: fix lint
1 parent 2b48a05 commit cd44be6

File tree

35 files changed

+7886
-113
lines changed

35 files changed

+7886
-113
lines changed
Lines changed: 375 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,375 @@
1+
/**
2+
* Number Filter Tests
3+
* Migrated from desktop: grid_number_filter_test.dart
4+
*
5+
* Desktop test data (v020GridFileName):
6+
* - 10 rows total
7+
* - Number column: -1, -2, 0.1, 0.2, 1, 2, 10, 11, 12, (empty)
8+
* - 9 rows with numbers, 1 row empty
9+
*
10+
* Tests number field filtering with all conditions:
11+
* - Equal, NotEqual, GreaterThan, LessThan
12+
* - GreaterThanOrEqualTo, LessThanOrEqualTo
13+
* - NumberIsEmpty, NumberIsNotEmpty
14+
*/
15+
import {
16+
setupFilterTest,
17+
loginAndCreateGrid,
18+
addFilterByFieldName,
19+
clickFilterChip,
20+
changeFilterCondition,
21+
deleteFilter,
22+
assertRowCount,
23+
NumberFilterCondition,
24+
generateRandomEmail,
25+
} from '../../support/filter-test-helpers';
26+
import {
27+
DatabaseFilterSelectors,
28+
DatabaseGridSelectors,
29+
PropertyMenuSelectors,
30+
GridFieldSelectors,
31+
RowControlsSelectors,
32+
waitForReactUpdate,
33+
FieldType,
34+
} from '../../support/selectors';
35+
36+
/**
37+
* Add a Number field and return its ID
38+
*/
39+
const addNumberField = (): Cypress.Chainable<string> => {
40+
PropertyMenuSelectors.newPropertyButton().first().scrollIntoView().click({ force: true });
41+
waitForReactUpdate(1200);
42+
PropertyMenuSelectors.propertyTypeTrigger().first().realHover();
43+
waitForReactUpdate(600);
44+
PropertyMenuSelectors.propertyTypeOption(FieldType.Number).scrollIntoView().click({ force: true });
45+
waitForReactUpdate(800);
46+
cy.get('body').type('{esc}');
47+
waitForReactUpdate(500);
48+
49+
return GridFieldSelectors.allFieldHeaders()
50+
.last()
51+
.invoke('attr', 'data-testid')
52+
.then((testId) => testId?.replace('grid-field-header-', '') || '');
53+
};
54+
55+
/**
56+
* Type a number into a cell
57+
*/
58+
const typeNumberIntoCell = (fieldId: string, cellIndex: number, value: string): void => {
59+
DatabaseGridSelectors.dataRowCellsForField(fieldId)
60+
.eq(cellIndex)
61+
.should('be.visible')
62+
.scrollIntoView()
63+
.click()
64+
.click();
65+
66+
// Type the value and press Enter to save (Escape doesn't save in number cells)
67+
cy.get('input:visible, textarea:visible', { timeout: 8000 })
68+
.should('exist')
69+
.first()
70+
.clear()
71+
.type(`${value}{enter}`, { delay: 30 });
72+
cy.wait(500);
73+
};
74+
75+
/**
76+
* Add more rows to the grid
77+
*/
78+
const addRows = (count: number): void => {
79+
for (let i = 0; i < count; i++) {
80+
DatabaseGridSelectors.dataRows().last().scrollIntoView();
81+
RowControlsSelectors.rowAccessoryButton().last().click({ force: true });
82+
waitForReactUpdate(300);
83+
RowControlsSelectors.rowMenuInsertBelow().click({ force: true });
84+
waitForReactUpdate(500);
85+
}
86+
};
87+
88+
/**
89+
* Setup test data matching desktop v020 database:
90+
* Numbers: -1, -2, 0.1, 0.2, 1, 2, 10, 11, 12, (empty) - 10 rows
91+
*/
92+
const setupV020NumberData = (numberFieldId: string) => {
93+
const numbers = ['-1', '-2', '0.1', '0.2', '1', '2', '10', '11', '12'];
94+
95+
// Add 7 more rows (default grid has 3 rows, we need 10)
96+
addRows(7);
97+
98+
// Type numbers into the first 9 rows (row 10 stays empty)
99+
numbers.forEach((num, index) => {
100+
typeNumberIntoCell(numberFieldId, index, num);
101+
});
102+
// Row 10 (index 9) remains empty
103+
};
104+
105+
describe('Database Number Filter Tests (Desktop Parity)', () => {
106+
beforeEach(() => {
107+
setupFilterTest();
108+
});
109+
110+
it('number filter - Equal condition', () => {
111+
// Desktop test: grid_number_filter_test.dart:17-31
112+
// Expected: Filter for 1 with Equal should show 1 row
113+
const testEmail = generateRandomEmail();
114+
loginAndCreateGrid(testEmail);
115+
116+
addNumberField().then((fieldId) => {
117+
setupV020NumberData(fieldId);
118+
});
119+
120+
assertRowCount(10);
121+
122+
addFilterByFieldName('Numbers');
123+
// Default condition is Equal
124+
DatabaseFilterSelectors.filterInput().should('be.visible').clear().type('1', { delay: 30 });
125+
waitForReactUpdate(500);
126+
127+
// Should show row with exactly 1
128+
assertRowCount(1);
129+
});
130+
131+
it('number filter - NotEqual condition', () => {
132+
// Desktop test: grid_number_filter_test.dart:33-48
133+
// Expected: Filter for 1 with NotEqual should show 8 rows (not 1, not empty)
134+
const testEmail = generateRandomEmail();
135+
loginAndCreateGrid(testEmail);
136+
137+
addNumberField().then((fieldId) => {
138+
setupV020NumberData(fieldId);
139+
});
140+
141+
assertRowCount(10);
142+
143+
addFilterByFieldName('Numbers');
144+
changeFilterCondition(NumberFilterCondition.NotEqual);
145+
DatabaseFilterSelectors.filterInput().should('be.visible').clear().type('1', { delay: 30 });
146+
waitForReactUpdate(500);
147+
148+
// Should show all rows except the one with 1 (8 rows - excludes 1 and empty)
149+
assertRowCount(8);
150+
});
151+
152+
it('number filter - GreaterThan condition', () => {
153+
// Desktop test: grid_number_filter_test.dart:50-65
154+
// Expected: Filter for >1 should show 4 rows (2, 10, 11, 12)
155+
const testEmail = generateRandomEmail();
156+
loginAndCreateGrid(testEmail);
157+
158+
addNumberField().then((fieldId) => {
159+
setupV020NumberData(fieldId);
160+
});
161+
162+
assertRowCount(10);
163+
164+
addFilterByFieldName('Numbers');
165+
changeFilterCondition(NumberFilterCondition.GreaterThan);
166+
DatabaseFilterSelectors.filterInput().should('be.visible').clear().type('1', { delay: 30 });
167+
waitForReactUpdate(500);
168+
169+
// Should show rows > 1: 2, 10, 11, 12 (4 rows)
170+
assertRowCount(4);
171+
});
172+
173+
it('number filter - LessThan condition', () => {
174+
// Desktop test: grid_number_filter_test.dart:67-82
175+
// Expected: Filter for <1 should show 4 rows (-2, -1, 0.1, 0.2)
176+
const testEmail = generateRandomEmail();
177+
loginAndCreateGrid(testEmail);
178+
179+
addNumberField().then((fieldId) => {
180+
setupV020NumberData(fieldId);
181+
});
182+
183+
assertRowCount(10);
184+
185+
addFilterByFieldName('Numbers');
186+
changeFilterCondition(NumberFilterCondition.LessThan);
187+
DatabaseFilterSelectors.filterInput().should('be.visible').clear().type('1', { delay: 30 });
188+
waitForReactUpdate(500);
189+
190+
// Should show rows < 1: -2, -1, 0.1, 0.2 (4 rows)
191+
assertRowCount(4);
192+
});
193+
194+
it('number filter - GreaterThanOrEqualTo condition', () => {
195+
// Desktop test: grid_number_filter_test.dart:84-101
196+
// Expected: Filter for >=1 should show 5 rows (1, 2, 10, 11, 12)
197+
const testEmail = generateRandomEmail();
198+
loginAndCreateGrid(testEmail);
199+
200+
addNumberField().then((fieldId) => {
201+
setupV020NumberData(fieldId);
202+
});
203+
204+
assertRowCount(10);
205+
206+
addFilterByFieldName('Numbers');
207+
changeFilterCondition(NumberFilterCondition.GreaterThanOrEqualTo);
208+
DatabaseFilterSelectors.filterInput().should('be.visible').clear().type('1', { delay: 30 });
209+
waitForReactUpdate(500);
210+
211+
// Should show rows >= 1: 1, 2, 10, 11, 12 (5 rows)
212+
assertRowCount(5);
213+
});
214+
215+
it('number filter - LessThanOrEqualTo condition', () => {
216+
// Desktop test: grid_number_filter_test.dart:103-119
217+
// Expected: Filter for <=1 should show 5 rows (-2, -1, 0.1, 0.2, 1)
218+
const testEmail = generateRandomEmail();
219+
loginAndCreateGrid(testEmail);
220+
221+
addNumberField().then((fieldId) => {
222+
setupV020NumberData(fieldId);
223+
});
224+
225+
assertRowCount(10);
226+
227+
addFilterByFieldName('Numbers');
228+
changeFilterCondition(NumberFilterCondition.LessThanOrEqualTo);
229+
DatabaseFilterSelectors.filterInput().should('be.visible').clear().type('1', { delay: 30 });
230+
waitForReactUpdate(500);
231+
232+
// Should show rows <= 1: -2, -1, 0.1, 0.2, 1 (5 rows)
233+
assertRowCount(5);
234+
});
235+
236+
it('number filter - NumberIsEmpty condition', () => {
237+
// Desktop test: grid_number_filter_test.dart:121-135
238+
// Expected: NumberIsEmpty should show 1 row
239+
const testEmail = generateRandomEmail();
240+
loginAndCreateGrid(testEmail);
241+
242+
addNumberField().then((fieldId) => {
243+
setupV020NumberData(fieldId);
244+
});
245+
246+
assertRowCount(10);
247+
248+
addFilterByFieldName('Numbers');
249+
changeFilterCondition(NumberFilterCondition.NumberIsEmpty);
250+
251+
// Should show rows with empty number (1 row in test database)
252+
assertRowCount(1);
253+
});
254+
255+
it('number filter - NumberIsNotEmpty condition', () => {
256+
// Desktop test: grid_number_filter_test.dart:137-152
257+
// Expected: NumberIsNotEmpty should show 9 rows
258+
const testEmail = generateRandomEmail();
259+
loginAndCreateGrid(testEmail);
260+
261+
addNumberField().then((fieldId) => {
262+
setupV020NumberData(fieldId);
263+
});
264+
265+
assertRowCount(10);
266+
267+
addFilterByFieldName('Numbers');
268+
changeFilterCondition(NumberFilterCondition.NumberIsNotEmpty);
269+
270+
// Should show rows with non-empty number (9 rows)
271+
assertRowCount(9);
272+
});
273+
274+
it('number filter - negative numbers', () => {
275+
// Desktop test: grid_number_filter_test.dart:154-169
276+
// Expected: Filter for <0 should show 2 rows (-1, -2)
277+
const testEmail = generateRandomEmail();
278+
loginAndCreateGrid(testEmail);
279+
280+
addNumberField().then((fieldId) => {
281+
setupV020NumberData(fieldId);
282+
});
283+
284+
assertRowCount(10);
285+
286+
addFilterByFieldName('Numbers');
287+
changeFilterCondition(NumberFilterCondition.LessThan);
288+
DatabaseFilterSelectors.filterInput().should('be.visible').clear().type('0', { delay: 30 });
289+
waitForReactUpdate(500);
290+
291+
// Should show negative numbers: -2, -1 (2 rows)
292+
assertRowCount(2);
293+
});
294+
295+
it('number filter - decimal numbers', () => {
296+
// Desktop test: grid_number_filter_test.dart:171-187
297+
// Expected: Filter for <1 should show 4 rows (0.1, 0.2, -1, -2)
298+
const testEmail = generateRandomEmail();
299+
loginAndCreateGrid(testEmail);
300+
301+
addNumberField().then((fieldId) => {
302+
setupV020NumberData(fieldId);
303+
});
304+
305+
assertRowCount(10);
306+
307+
addFilterByFieldName('Numbers');
308+
changeFilterCondition(NumberFilterCondition.LessThan);
309+
DatabaseFilterSelectors.filterInput().should('be.visible').clear().type('1', { delay: 30 });
310+
waitForReactUpdate(500);
311+
312+
// Should show 0.1, 0.2, -1, -2 (4 rows with values < 1, not including empty)
313+
assertRowCount(4);
314+
});
315+
316+
it('number filter - delete filter restores all rows', () => {
317+
// Desktop test: grid_number_filter_test.dart:189-214
318+
// Expected: After deleting filter, all 10 rows should be visible
319+
const testEmail = generateRandomEmail();
320+
loginAndCreateGrid(testEmail);
321+
322+
addNumberField().then((fieldId) => {
323+
setupV020NumberData(fieldId);
324+
});
325+
326+
assertRowCount(10);
327+
328+
addFilterByFieldName('Numbers');
329+
changeFilterCondition(NumberFilterCondition.GreaterThan);
330+
DatabaseFilterSelectors.filterInput().should('be.visible').clear().type('100', { delay: 30 });
331+
waitForReactUpdate(500);
332+
333+
// No rows match > 100
334+
assertRowCount(0);
335+
336+
// Delete the filter
337+
clickFilterChip();
338+
deleteFilter();
339+
340+
// All rows should be visible again
341+
assertRowCount(10);
342+
});
343+
344+
it('number filter - change condition dynamically', () => {
345+
// Desktop test: grid_number_filter_test.dart:216-239
346+
// Tests changing filter condition on the fly
347+
const testEmail = generateRandomEmail();
348+
loginAndCreateGrid(testEmail);
349+
350+
addNumberField().then((fieldId) => {
351+
setupV020NumberData(fieldId);
352+
});
353+
354+
assertRowCount(10);
355+
356+
// Add filter with Equal
357+
addFilterByFieldName('Numbers');
358+
DatabaseFilterSelectors.filterInput().should('be.visible').clear().type('1', { delay: 30 });
359+
waitForReactUpdate(500);
360+
assertRowCount(1);
361+
362+
// Change to GreaterThan
363+
clickFilterChip();
364+
waitForReactUpdate(300);
365+
changeFilterCondition(NumberFilterCondition.GreaterThan);
366+
// Value is still 1, so should show 2, 10, 11, 12 (4 rows)
367+
assertRowCount(4);
368+
369+
// Change to NumberIsEmpty (content should be ignored)
370+
clickFilterChip();
371+
waitForReactUpdate(300);
372+
changeFilterCondition(NumberFilterCondition.NumberIsEmpty);
373+
assertRowCount(1);
374+
});
375+
});

0 commit comments

Comments
 (0)