msyavuz commented on code in PR #34056:
URL: https://github.com/apache/superset/pull/34056#discussion_r2184745263
##########
superset-frontend/src/features/databases/UploadDataModel/UploadDataModal.test.tsx:
##########
@@ -86,803 +84,520 @@ beforeEach(() => {
fetchMock.get('glob:*api/v1/database/2/schemas/?q=(upload_allowed:!t)', {
result: ['schema1', 'schema2'],
});
+};
+
+// Set timeout for all tests in this file to 30 seconds
+jest.setTimeout(30000);
+
+beforeEach(() => {
+ setupMocks();
});
afterEach(() => {
fetchMock.restore();
});
-test('CSV, renders the general information elements correctly', () => {
- render(<UploadDataModal {...csvProps} />, {
- useRedux: true,
- });
-
- const cancelButton = screen.getByRole('button', {
- name: 'Cancel',
- });
- const uploadButton = screen.getByRole('button', {
- name: 'Upload',
- });
- const selectButton = screen.getByRole('button', {
- name: 'Select',
- });
-
- const title = screen.getByRole('heading', {
- name: /csv upload/i,
- });
- const panel1 = screen.getByRole('heading', {
- name: /General information/i,
- });
- const panel2 = screen.getByRole('heading', {
- name: /file settings/i,
- });
- const panel3 = screen.getByRole('heading', {
- name: /columns/i,
- });
- const panel4 = screen.getByRole('heading', {
- name: /rows/i,
- });
- const selectDatabase = screen.getByRole('combobox', {
- name: /select a database/i,
- });
- const selectDelimiter = screen.getByRole('combobox', {
- name: /choose a delimiter/i,
- });
- const inputTableName = screen.getByRole('textbox', {
- name: /table name/i,
- });
- const inputSchema = screen.getByRole('combobox', {
- name: /schema/i,
- });
-
- const visibleComponents = [
- cancelButton,
- uploadButton,
- selectButton,
- title,
- panel1,
- panel2,
- panel3,
- panel4,
- selectDatabase,
- selectDelimiter,
- inputTableName,
- inputSchema,
- ];
- visibleComponents.forEach(component => {
- expect(component).toBeInTheDocument();
- });
+// Helper function to get common elements
+const getCommonElements = () => ({
+ cancelButton: screen.getByRole('button', { name: 'Cancel' }),
+ uploadButton: screen.getByRole('button', { name: 'Upload' }),
+ selectButton: screen.getByRole('button', { name: 'Select' }),
+ panel1: screen.getByRole('heading', { name: /General information/i }),
+ panel2: screen.getByRole('heading', { name: /file settings/i }),
+ panel3: screen.getByRole('heading', { name: /columns/i }),
+ selectDatabase: screen.getByRole('combobox', { name: /select a database/i }),
+ inputTableName: screen.getByRole('textbox', { name: /table name/i }),
+ inputSchema: screen.getByRole('combobox', { name: /schema/i }),
});
-test('Excel, renders the general information elements correctly', () => {
- render(<UploadDataModal {...excelProps} />, {
- useRedux: true,
- });
-
- const cancelButton = screen.getByRole('button', {
- name: 'Cancel',
- });
- const uploadButton = screen.getByRole('button', {
- name: 'Upload',
- });
- const selectButton = screen.getByRole('button', {
- name: 'Select',
+// Helper function to check element visibility
+const expectElementsVisible = (elements: any[]) => {
+ elements.forEach((element: any) => {
+ expect(element).toBeInTheDocument();
});
+};
- const title = screen.getByRole('heading', {
- name: /excel upload/i,
- });
- const missingTitle = screen.queryByRole('heading', {
- name: /csv upload/i,
- });
- expect(missingTitle).not.toBeInTheDocument();
- const panel1 = screen.getByRole('heading', {
- name: /General information/i,
- });
- const panel2 = screen.getByRole('heading', {
- name: /file settings/i,
- });
- const panel3 = screen.getByRole('heading', {
- name: /columns/i,
- });
- const panel4 = screen.getByRole('heading', {
- name: /rows/i,
- });
- const selectDatabase = screen.getByRole('combobox', {
- name: /select a database/i,
- });
- const selectDelimiter = screen.queryByRole('combobox', {
- name: /choose a delimiter/i,
- });
- expect(selectDelimiter).not.toBeInTheDocument();
- const selectSheetName = screen.getByRole('combobox', {
- name: /choose sheet name/i,
- });
- const inputTableName = screen.getByRole('textbox', {
- name: /table name/i,
- });
- const inputSchema = screen.getByRole('combobox', {
- name: /schema/i,
+// Helper function to check element absence
+const expectElementsNotVisible = (elements: any[]) => {
+ elements.forEach((element: any) => {
+ expect(element).not.toBeInTheDocument();
});
+};
- const visibleComponents = [
- cancelButton,
- uploadButton,
- selectButton,
- title,
- panel1,
- panel2,
- panel3,
- panel4,
- selectDatabase,
- selectSheetName,
- inputTableName,
- inputSchema,
- ];
- visibleComponents.forEach(component => {
- expect(component).toBeInTheDocument();
+describe('UploadDataModal - General Information Elements', () => {
+ test('CSV renders correctly', () => {
+ render(<UploadDataModal {...csvProps} />, { useRedux: true });
+
+ const common = getCommonElements();
+ const title = screen.getByRole('heading', { name: /csv upload/i });
+ const panel4 = screen.getByRole('heading', { name: /rows/i });
+ const selectDelimiter = screen.getByRole('combobox', {
+ name: /choose a delimiter/i,
+ });
+
+ expectElementsVisible([
+ common.cancelButton,
+ common.uploadButton,
+ common.selectButton,
+ title,
+ common.panel1,
+ common.panel2,
+ common.panel3,
+ panel4,
+ common.selectDatabase,
+ selectDelimiter,
+ common.inputTableName,
+ common.inputSchema,
+ ]);
+ });
+
+ test('Excel renders correctly', () => {
+ render(<UploadDataModal {...excelProps} />, { useRedux: true });
+
+ const common = getCommonElements();
+ const title = screen.getByRole('heading', { name: /excel upload/i });
+ const panel4 = screen.getByRole('heading', { name: /rows/i });
+ const selectSheetName = screen.getByRole('combobox', {
+ name: /choose sheet name/i,
+ });
+
+ expectElementsVisible([
+ common.cancelButton,
+ common.uploadButton,
+ common.selectButton,
+ title,
+ common.panel1,
+ common.panel2,
+ common.panel3,
+ panel4,
+ common.selectDatabase,
+ selectSheetName,
+ common.inputTableName,
+ common.inputSchema,
+ ]);
+
+ // Check elements that should NOT be visible
+ expect(
+ screen.queryByRole('heading', { name: /csv upload/i }),
+ ).not.toBeInTheDocument();
+ expect(
+ screen.queryByRole('combobox', { name: /choose a delimiter/i }),
+ ).not.toBeInTheDocument();
+ });
+
+ test('Columnar renders correctly', () => {
+ render(<UploadDataModal {...columnarProps} />, { useRedux: true });
+
+ const common = getCommonElements();
+ const title = screen.getByRole('heading', { name: /columnar upload/i });
+
+ expectElementsVisible([
+ common.cancelButton,
+ common.uploadButton,
+ common.selectButton,
+ title,
+ common.panel1,
+ common.panel2,
+ common.panel3,
+ common.selectDatabase,
+ common.inputTableName,
+ common.inputSchema,
+ ]);
+
+ // Check elements that should NOT be visible
+ expectElementsNotVisible([
+ screen.queryByRole('heading', { name: /csv upload/i }),
+ screen.queryByRole('heading', { name: /rows/i }),
+ screen.queryByRole('combobox', { name: /choose a delimiter/i }),
+ screen.queryByRole('combobox', { name: /choose sheet name/i }),
+ ]);
});
});
-test('Columnar, renders the general information elements correctly', () => {
- render(<UploadDataModal {...columnarProps} />, {
- useRedux: true,
- });
-
- const cancelButton = screen.getByRole('button', {
- name: 'Cancel',
- });
- const uploadButton = screen.getByRole('button', {
- name: 'Upload',
- });
- const selectButton = screen.getByRole('button', {
- name: 'Select',
- });
-
- const title = screen.getByRole('heading', {
- name: /columnar upload/i,
- });
- const missingTitle = screen.queryByRole('heading', {
- name: /csv upload/i,
- });
- expect(missingTitle).not.toBeInTheDocument();
- const panel1 = screen.getByRole('heading', {
- name: /General information/i,
- });
- const panel2 = screen.getByRole('heading', {
- name: /file settings/i,
- });
- const panel3 = screen.getByRole('heading', {
- name: /columns/i,
- });
- const panel4 = screen.queryByRole('heading', {
- name: /rows/i,
- });
- expect(panel4).not.toBeInTheDocument();
-
- const selectDatabase = screen.getByRole('combobox', {
- name: /select a database/i,
- });
- const selectDelimiter = screen.queryByRole('combobox', {
- name: /choose a delimiter/i,
+describe('UploadDataModal - File Settings Elements', () => {
+ const openFileSettings = async () => {
+ const panelHeader = screen.getByRole('heading', { name: /file settings/i
});
+ await userEvent.click(panelHeader);
+ };
+
+ test('CSV file settings render correctly', async () => {
+ render(<UploadDataModal {...csvProps} />, { useRedux: true });
+
+ expect(
+ screen.queryByText('If Table Already Exists'),
+ ).not.toBeInTheDocument();
+ await openFileSettings();
+
+ const elements = [
+ screen.getByRole('combobox', { name: /choose already exists/i }),
+ screen.getByTestId('skipInitialSpace'),
+ screen.getByTestId('skipBlankLines'),
+ screen.getByTestId('dayFirst'),
+ screen.getByRole('textbox', { name: /decimal character/i }),
+ screen.getByRole('combobox', { name: /null values/i }),
+ ];
+
+ expectElementsVisible(elements);
+ });
+
+ test('Excel file settings render correctly', async () => {
+ render(<UploadDataModal {...excelProps} />, { useRedux: true });
+
+ expect(
+ screen.queryByText('If Table Already Exists'),
+ ).not.toBeInTheDocument();
+ await openFileSettings();
+
+ const visibleElements = [
+ screen.getByRole('combobox', { name: /choose already exists/i }),
+ screen.getByRole('textbox', { name: /decimal character/i }),
+ screen.getByRole('combobox', { name: /null values/i }),
+ ];
+
+ expectElementsVisible(visibleElements);
+
+ // Check elements that should NOT be visible
+ expectElementsNotVisible([
+ screen.queryByText('skipInitialSpace'),
+ screen.queryByText('skipBlankLines'),
+ screen.queryByText('dayFirst'),
+ ]);
+ });
+
+ test('Columnar file settings render correctly', async () => {
+ render(<UploadDataModal {...columnarProps} />, { useRedux: true });
+
+ expect(
+ screen.queryByText('If Table Already Exists'),
+ ).not.toBeInTheDocument();
+ await openFileSettings();
+
+ const visibleElements = [
+ screen.getByRole('combobox', { name: /choose already exists/i }),
+ ];
+
+ expectElementsVisible(visibleElements);
+
+ // Check elements that should NOT be visible
+ expectElementsNotVisible([
+ screen.queryByRole('textbox', { name: /decimal character/i }),
+ screen.queryByRole('combobox', {
+ name: /choose columns to be parsed as dates/i,
+ }),
+ screen.queryByRole('combobox', { name: /null values/i }),
+ screen.queryByText('skipInitialSpace'),
+ screen.queryByText('skipBlankLines'),
+ screen.queryByText('dayFirst'),
+ ]);
});
- expect(selectDelimiter).not.toBeInTheDocument();
+});
- const selectSheetName = screen.queryByRole('combobox', {
- name: /choose sheet name/i,
- });
- expect(selectSheetName).not.toBeInTheDocument();
- const inputTableName = screen.getByRole('textbox', {
- name: /table name/i,
- });
- const inputSchema = screen.getByRole('combobox', {
- name: /schema/i,
- });
+describe('UploadDataModal - Columns Elements', () => {
+ const openColumns = async () => {
+ const panelHeader = screen.getByRole('heading', { name: /columns/i });
+ await userEvent.click(panelHeader);
+ };
- const visibleComponents = [
- cancelButton,
- uploadButton,
- selectButton,
- title,
- panel1,
- panel2,
- panel3,
- selectDatabase,
- inputTableName,
- inputSchema,
- ];
- visibleComponents.forEach(component => {
- expect(component).toBeInTheDocument();
- });
-});
+ test('CSV columns render correctly', async () => {
+ render(<UploadDataModal {...csvProps} />, { useRedux: true });
-test('CSV, renders the file settings elements correctly', () => {
- render(<UploadDataModal {...csvProps} />, {
- useRedux: true,
- });
+ await openColumns();
+ const switchDataFrameIndex = screen.getByTestId('dataFrameIndex');
+ await userEvent.click(switchDataFrameIndex);
- expect(screen.queryByText('If Table Already
Exists')).not.toBeInTheDocument();
- const panelHeader = screen.getByRole('heading', {
- name: /file settings/i,
- });
- userEvent.click(panelHeader);
- const selectTableAlreadyExists = screen.getByRole('combobox', {
- name: /choose already exists/i,
- });
- const switchSkipInitialSpace = screen.getByTestId('skipInitialSpace');
- const switchSkipBlankLines = screen.getByTestId('skipBlankLines');
- const switchDayFirst = screen.getByTestId('dayFirst');
- const inputDecimalCharacter = screen.getByRole('textbox', {
- name: /decimal character/i,
- });
- const selectColumnsDates = screen.getByRole('combobox', {
- name: /choose columns to be parsed as dates/i,
- });
- const selectNullValues = screen.getByRole('combobox', {
- name: /null values/i,
- });
- userEvent.click(selectColumnsDates);
- userEvent.click(selectNullValues);
- const visibleComponents = [
- selectTableAlreadyExists,
- switchSkipInitialSpace,
- switchDayFirst,
- switchSkipBlankLines,
- inputDecimalCharacter,
- selectNullValues,
- ];
- visibleComponents.forEach(component => {
- expect(component).toBeInTheDocument();
- });
-});
+ const elements = [
+ screen.getByRole('combobox', { name: /Choose index column/i }),
+ switchDataFrameIndex,
+ screen.getByRole('textbox', { name: /Index label/i }),
+ screen.getByRole('combobox', { name: /Choose columns to read/i }),
+ screen.getByRole('textbox', { name: /Column data types/i }),
+ ];
-test('Excel, renders the file settings elements correctly', () => {
- render(<UploadDataModal {...excelProps} />, {
- useRedux: true,
+ expectElementsVisible(elements);
});
- expect(screen.queryByText('If Table Already
Exists')).not.toBeInTheDocument();
- const panelHeader = screen.getByRole('heading', {
- name: /file settings/i,
- });
- userEvent.click(panelHeader);
- const selectTableAlreadyExists = screen.getByRole('combobox', {
- name: /choose already exists/i,
- });
- const inputDecimalCharacter = screen.getByRole('textbox', {
- name: /decimal character/i,
- });
- const selectColumnsDates = screen.getByRole('combobox', {
- name: /choose columns to be parsed as dates/i,
- });
- const selectNullValues = screen.getByRole('combobox', {
- name: /null values/i,
- });
- userEvent.click(selectColumnsDates);
- userEvent.click(selectNullValues);
-
- const switchSkipInitialSpace = screen.queryByText('skipInitialSpace');
- expect(switchSkipInitialSpace).not.toBeInTheDocument();
- const switchSkipBlankLines = screen.queryByText('skipBlankLines');
- expect(switchSkipBlankLines).not.toBeInTheDocument();
- const switchDayFirst = screen.queryByText('dayFirst');
- expect(switchDayFirst).not.toBeInTheDocument();
-
- const visibleComponents = [
- selectTableAlreadyExists,
- inputDecimalCharacter,
- selectNullValues,
- ];
- visibleComponents.forEach(component => {
- expect(component).toBeInTheDocument();
- });
-});
+ test('Excel columns render correctly', async () => {
+ render(<UploadDataModal {...excelProps} />, { useRedux: true });
-test('Columnar, renders the file settings elements correctly', () => {
- render(<UploadDataModal {...columnarProps} />, {
- useRedux: true,
- });
+ await openColumns();
+ const switchDataFrameIndex = screen.getByTestId('dataFrameIndex');
+ await userEvent.click(switchDataFrameIndex);
- expect(screen.queryByText('If Table Already
Exists')).not.toBeInTheDocument();
- const panelHeader = screen.getByRole('heading', {
- name: /file settings/i,
- });
- userEvent.click(panelHeader);
- const selectTableAlreadyExists = screen.getByRole('combobox', {
- name: /choose already exists/i,
- });
- const inputDecimalCharacter = screen.queryByRole('textbox', {
- name: /decimal character/i,
- });
- expect(inputDecimalCharacter).not.toBeInTheDocument();
- const selectColumnsDates = screen.queryByRole('combobox', {
- name: /choose columns to be parsed as dates/i,
- });
- expect(selectColumnsDates).not.toBeInTheDocument();
- const selectNullValues = screen.queryByRole('combobox', {
- name: /null values/i,
- });
- expect(selectNullValues).not.toBeInTheDocument();
-
- const switchSkipInitialSpace = screen.queryByText('skipInitialSpace');
- expect(switchSkipInitialSpace).not.toBeInTheDocument();
- const switchSkipBlankLines = screen.queryByText('skipBlankLines');
- expect(switchSkipBlankLines).not.toBeInTheDocument();
- const switchDayFirst = screen.queryByText('dayFirst');
- expect(switchDayFirst).not.toBeInTheDocument();
-
- const visibleComponents = [selectTableAlreadyExists];
- visibleComponents.forEach(component => {
- expect(component).toBeInTheDocument();
- });
-});
+ const visibleElements = [
+ screen.getByRole('combobox', { name: /Choose index column/i }),
+ switchDataFrameIndex,
+ screen.getByRole('textbox', { name: /Index label/i }),
+ screen.getByRole('combobox', { name: /Choose columns to read/i }),
+ ];
-test('CSV, renders the columns elements correctly', () => {
- render(<UploadDataModal {...csvProps} />, {
- useRedux: true,
- });
+ expectElementsVisible(visibleElements);
- const panelHeader = screen.getByRole('heading', {
- name: /columns/i,
- });
- userEvent.click(panelHeader);
- const switchDataFrameIndex = screen.getByTestId('dataFrameIndex');
- userEvent.click(switchDataFrameIndex);
- const selectIndexColumn = screen.getByRole('combobox', {
- name: /Choose index column/i,
- });
- const inputColumnLabels = screen.getByRole('textbox', {
- name: /Index label/i,
+ // Check elements that should NOT be visible
+ expect(
+ screen.queryByRole('textbox', { name: /Column data types/i }),
+ ).not.toBeInTheDocument();
});
- const selectColumnsToRead = screen.getByRole('combobox', {
- name: /Choose columns to read/i,
- });
- const inputColumnDataTypes = screen.getByRole('textbox', {
- name: /Column data types/i,
- });
- userEvent.click(selectColumnsToRead);
-
- const visibleComponents = [
- selectIndexColumn,
- switchDataFrameIndex,
- inputColumnLabels,
- selectColumnsToRead,
- inputColumnDataTypes,
- ];
- visibleComponents.forEach(component => {
- expect(component).toBeInTheDocument();
- });
-});
-test('Excel, renders the columns elements correctly', () => {
- render(<UploadDataModal {...excelProps} />, {
- useRedux: true,
- });
+ test('Columnar columns render correctly', async () => {
+ render(<UploadDataModal {...columnarProps} />, { useRedux: true });
- const panelHeader = screen.getByRole('heading', {
- name: /columns/i,
- });
- userEvent.click(panelHeader);
- const switchDataFrameIndex = screen.getByTestId('dataFrameIndex');
- userEvent.click(switchDataFrameIndex);
- const selectIndexColumn = screen.getByRole('combobox', {
- name: /Choose index column/i,
- });
- const inputIndexLabel = screen.getByRole('textbox', {
- name: /Index label/i,
- });
- const selectColumnsToRead = screen.getByRole('combobox', {
- name: /Choose columns to read/i,
- });
- userEvent.click(selectColumnsToRead);
+ await openColumns();
+ const switchDataFrameIndex = screen.getByTestId('dataFrameIndex');
+ await userEvent.click(switchDataFrameIndex);
- const columnDataTypes = screen.queryByRole('textbox', {
- name: /Column data types/i,
- });
+ const visibleElements = [
+ switchDataFrameIndex,
+ screen.getByRole('textbox', { name: /Index label/i }),
+ screen.getByRole('combobox', { name: /Choose columns to read/i }),
+ ];
- expect(columnDataTypes).not.toBeInTheDocument();
+ expectElementsVisible(visibleElements);
- const visibleComponents = [
- selectIndexColumn,
- switchDataFrameIndex,
- inputIndexLabel,
- selectColumnsToRead,
- ];
- visibleComponents.forEach(component => {
- expect(component).toBeInTheDocument();
+ // Check elements that should NOT be visible
+ expectElementsNotVisible([
+ screen.queryByRole('combobox', { name: /Choose index column/i }),
+ screen.queryByRole('textbox', { name: /Column data types/i }),
+ ]);
});
});
-test('Columnar, renders the columns elements correctly', () => {
- render(<UploadDataModal {...columnarProps} />, {
- useRedux: true,
- });
+describe('UploadDataModal - Rows Elements', () => {
+ test('CSV/Excel rows render correctly', async () => {
+ render(<UploadDataModal {...csvProps} />, { useRedux: true });
- const panelHeader = screen.getByRole('heading', {
- name: /columns/i,
- });
- userEvent.click(panelHeader);
- const selectIndexColumn = screen.queryByRole('combobox', {
- name: /Choose index column/i,
- });
- expect(selectIndexColumn).not.toBeInTheDocument();
- const switchDataFrameIndex = screen.getByTestId('dataFrameIndex');
- userEvent.click(switchDataFrameIndex);
- const inputIndexLabel = screen.getByRole('textbox', {
- name: /Index label/i,
- });
- const selectColumnsToRead = screen.getByRole('combobox', {
- name: /Choose columns to read/i,
- });
- userEvent.click(selectColumnsToRead);
+ const panelHeader = screen.getByRole('heading', { name: /rows/i });
+ await userEvent.click(panelHeader);
- const columnDataTypes = screen.queryByRole('textbox', {
- name: /Column data types/i,
- });
- expect(columnDataTypes).not.toBeInTheDocument();
-
- const visibleComponents = [
- switchDataFrameIndex,
- inputIndexLabel,
- selectColumnsToRead,
- ];
- visibleComponents.forEach(component => {
- expect(component).toBeInTheDocument();
- });
-});
+ const elements = [
+ screen.getByRole('spinbutton', { name: /header row/i }),
+ screen.getByRole('spinbutton', { name: /rows to read/i }),
+ screen.getByRole('spinbutton', { name: /skip rows/i }),
+ ];
-test('renders the rows elements correctly', () => {
- render(<UploadDataModal {...csvProps} />, {
- useRedux: true,
+ expectElementsVisible(elements);
});
- const panelHeader = screen.getByRole('heading', {
- name: /rows/i,
- });
- userEvent.click(panelHeader);
- const inputHeaderRow = screen.getByRole('spinbutton', {
- name: /header row/i,
- });
- const inputRowsToRead = screen.getByRole('spinbutton', {
- name: /rows to read/i,
- });
- const inputSkipRows = screen.getByRole('spinbutton', {
- name: /skip rows/i,
- });
+ test('Columnar does not render rows', () => {
+ render(<UploadDataModal {...columnarProps} />, { useRedux: true });
- const visibleComponents = [inputHeaderRow, inputRowsToRead, inputSkipRows];
- visibleComponents.forEach(component => {
- expect(component).toBeInTheDocument();
+ const panelHeader = screen.queryByRole('heading', { name: /rows/i });
+ expect(panelHeader).not.toBeInTheDocument();
});
});
-test('Columnar, does not render the rows', () => {
- render(<UploadDataModal {...columnarProps} />, {
- useRedux: true,
+describe('UploadDataModal - Database and Schema Population', () => {
+ test('database and schema are correctly populated', async () => {
+ render(<UploadDataModal {...csvProps} />, { useRedux: true });
+
+ const selectDatabase = screen.getByRole('combobox', {
+ name: /select a database/i,
+ });
+ const selectSchema = screen.getByRole('combobox', { name: /schema/i });
+
+ // Test database selection
+ await userEvent.click(selectDatabase);
+ await waitFor(() => screen.getByText('database1'));
+ await waitFor(() => screen.getByText('database2'));
+
+ // Select database1 and check schemas
+ await userEvent.click(screen.getByText('database1'));
+ await userEvent.click(selectSchema);
+ await waitFor(() => screen.getAllByText('information_schema'));
+ await waitFor(() => screen.getAllByText('public'));
+
+ // Switch to database2 and check schemas
+ await userEvent.click(selectDatabase);
+ await userEvent.click(screen.getByText('database2'));
+ await userEvent.click(selectSchema);
+ await waitFor(() => screen.getAllByText('schema1'));
+ await waitFor(() => screen.getAllByText('schema2'));
});
-
- const panelHeader = screen.queryByRole('heading', {
- name: /rows/i,
- });
- expect(panelHeader).not.toBeInTheDocument();
});
-test('database and schema are correctly populated', async () => {
- render(<UploadDataModal {...csvProps} />, {
- useRedux: true,
- });
-
- const selectDatabase = screen.getByRole('combobox', {
- name: /select a database/i,
- });
- const selectSchema = screen.getByRole('combobox', {
- name: /schema/i,
- });
-
- userEvent.click(selectDatabase);
-
- await waitFor(() => screen.getByText('database1'));
- await waitFor(() => screen.getByText('database2'));
+describe('UploadDataModal - Form Validation', () => {
+ test('form validation without required fields', async () => {
+ render(<UploadDataModal {...csvProps} />, { useRedux: true });
- screen.getByText('database1').click();
-
- userEvent.click(selectSchema);
-
- // make sure the schemas for database1 are displayed
- await waitFor(() => screen.getAllByText('information_schema'));
- await waitFor(() => screen.getAllByText('public'));
-
- screen.getByText('database2').click();
- userEvent.click(selectSchema);
- // make sure the schemas for database2 are displayed
- await waitFor(() => screen.getAllByText('schema1'));
- await waitFor(() => screen.getAllByText('schema2'));
-}, 30000);
-
-test('form without required fields', async () => {
- render(<UploadDataModal {...csvProps} />, {
- useRedux: true,
- });
+ const uploadButton = screen.getByRole('button', { name: 'Upload' });
+ await userEvent.click(uploadButton);
- const uploadButton = screen.getByRole('button', {
- name: 'Upload',
+ await waitFor(() => {
+ expect(
+ screen.getByText('Uploading a file is required'),
+ ).toBeInTheDocument();
+ expect(
+ screen.getByText('Selecting a database is required'),
+ ).toBeInTheDocument();
+ expect(screen.getByText('Table name is required')).toBeInTheDocument();
+ });
});
-
- // Submit form without filling any fields
- userEvent.click(uploadButton);
-
- expect(
- await screen.findByText('Uploading a file is required'),
- ).toBeInTheDocument();
- expect(
- await screen.findByText('Selecting a database is required'),
- ).toBeInTheDocument();
- expect(await screen.findByText('Table name is
required')).toBeInTheDocument();
});
-test('CSV form post', async () => {
- render(<UploadDataModal {...csvProps} />, {
- useRedux: true,
- });
-
- const selectButton = screen.getByRole('button', {
- name: 'Select',
- });
- userEvent.click(selectButton);
-
- // Select a file from the file dialog
- const file = new File(['test'], 'test.csv', { type: 'text/csv' });
- const inputElement = screen.getByTestId('model-file-input');
-
- expect(inputElement).toBeInTheDocument();
- fireEvent.change(inputElement, { target: { files: [file] } });
-
- const selectDatabase = screen.getByRole('combobox', {
- name: /select a database/i,
- });
- userEvent.click(selectDatabase);
-
- await screen.findByText('database1');
- await screen.findByText('database2');
-
- screen.getByText('database1').click();
- const selectSchema = screen.getByRole('combobox', {
- name: /schema/i,
- });
- userEvent.click(selectSchema);
-
- await screen.findAllByText('public');
- screen.getAllByText('public')[1].click();
-
- // Fill out form fields
- const inputTableName = screen.getByRole('textbox', {
- name: /table name/i,
- });
- userEvent.type(inputTableName, 'table1');
- const uploadButton = screen.getByRole('button', {
- name: 'Upload',
- });
-
- userEvent.click(uploadButton);
- await waitFor(() => fetchMock.called('glob:*api/v1/database/1/upload/'));
-
- // Get the matching fetch calls made
- const matchingCalls = fetchMock.calls('glob:*api/v1/database/1/upload/');
- expect(matchingCalls).toHaveLength(1);
- const [, options] = matchingCalls[0];
- const formData = options?.body as FormData;
- expect(formData.get('type')).toBe('csv');
- expect(formData.get('table_name')).toBe('table1');
- expect(formData.get('schema')).toBe('public');
- expect(formData.get('table_name')).toBe('table1');
- const fileData = formData.get('file') as File;
- expect(fileData.name).toBe('test.csv');
-}, 30000);
-
-test('Excel form post', async () => {
- render(<UploadDataModal {...excelProps} />, {
- useRedux: true,
- });
-
- const selectButton = screen.getByRole('button', {
- name: 'Select',
- });
- userEvent.click(selectButton);
-
- // Select a file from the file dialog
- const file = new File(['test'], 'test.xls', { type: 'text' });
- const inputElement = screen.getByTestId('model-file-input');
-
- expect(inputElement).toBeInTheDocument();
- fireEvent.change(inputElement, { target: { files: [file] } });
+describe('UploadDataModal - Form Submission', () => {
+ // Helper function to fill out form
+ const fillForm = async (
+ fileType: string,
+ fileName: string,
+ mimeType = 'text/csv',
+ ) => {
+ const selectButton = screen.getByRole('button', { name: 'Select' });
+ await userEvent.click(selectButton);
- const selectDatabase = screen.getByRole('combobox', {
- name: /select a database/i,
- });
- userEvent.click(selectDatabase);
+ const file = new File(['test'], fileName, { type: mimeType });
+ const inputElement = screen.getByTestId('model-file-input');
+ fireEvent.change(inputElement, { target: { files: [file] } });
- await screen.findByText('database1');
- await screen.findByText('database2');
-
- screen.getByText('database1').click();
- const selectSchema = screen.getByRole('combobox', {
- name: /schema/i,
- });
- userEvent.click(selectSchema);
+ const selectDatabase = screen.getByRole('combobox', {
+ name: /select a database/i,
+ });
+ await userEvent.click(selectDatabase);
- await screen.findAllByText('public');
- screen.getAllByText('public')[1].click();
+ await waitFor(() => screen.getByText('database1'));
+ await userEvent.click(screen.getByText('database1'));
- // Fill out form fields
- const inputTableName = screen.getByRole('textbox', {
- name: /table name/i,
- });
- userEvent.type(inputTableName, 'table1');
- const uploadButton = screen.getByRole('button', {
- name: 'Upload',
- });
+ const selectSchema = screen.getByRole('combobox', { name: /schema/i });
+ await userEvent.click(selectSchema);
- userEvent.click(uploadButton);
- await waitFor(() => fetchMock.called('glob:*api/v1/database/1/upload/'));
-
- // Get the matching fetch calls made
- const matchingCalls = fetchMock.calls('glob:*api/v1/database/1/upload/');
- expect(matchingCalls).toHaveLength(1);
- const [, options] = matchingCalls[0];
- const formData = options?.body as FormData;
- expect(formData.get('type')).toBe('excel');
- expect(formData.get('table_name')).toBe('table1');
- expect(formData.get('schema')).toBe('public');
- expect(formData.get('table_name')).toBe('table1');
- const fileData = formData.get('file') as File;
- expect(fileData.name).toBe('test.xls');
-}, 30000);
-
-test('Columnar form post', async () => {
- render(<UploadDataModal {...columnarProps} />, {
- useRedux: true,
- });
+ await waitFor(() => screen.getAllByText('public'));
+ await userEvent.click(screen.getAllByText('public')[1]);
- const selectButton = screen.getByRole('button', {
- name: 'Select',
- });
- userEvent.click(selectButton);
+ const inputTableName = screen.getByRole('textbox', { name: /table name/i
});
+ await userEvent.type(inputTableName, 'table1');
- // Select a file from the file dialog
- const file = new File(['test'], 'test.parquet', { type: 'text' });
- const inputElement = screen.getByTestId('model-file-input');
+ const uploadButton = screen.getByRole('button', { name: 'Upload' });
+ await userEvent.click(uploadButton);
- expect(inputElement).toBeInTheDocument();
- fireEvent.change(inputElement, { target: { files: [file] } });
+ await waitFor(() => fetchMock.called('glob:*api/v1/database/1/upload/'), {
+ timeout: 10000,
+ });
+ return fetchMock.calls('glob:*api/v1/database/1/upload/')[0];
+ };
- const selectDatabase = screen.getByRole('combobox', {
- name: /select a database/i,
- });
- userEvent.click(selectDatabase);
+ test('CSV form submission', async () => {
+ render(<UploadDataModal {...csvProps} />, { useRedux: true });
- await screen.findByText('database1');
- await screen.findByText('database2');
+ const [, options] = await fillForm('csv', 'test.csv');
+ const formData = options?.body as FormData;
- screen.getByText('database1').click();
- const selectSchema = screen.getByRole('combobox', {
- name: /schema/i,
+ expect(formData.get('type')).toBe('csv');
+ expect(formData.get('table_name')).toBe('table1');
+ expect(formData.get('schema')).toBe('public');
+ expect((formData.get('file') as File).name).toBe('test.csv');
});
- userEvent.click(selectSchema);
- await screen.findAllByText('public');
- screen.getAllByText('public')[1].click();
+ test('Excel form submission', async () => {
+ render(<UploadDataModal {...excelProps} />, { useRedux: true });
- // Fill out form fields
- const inputTableName = screen.getByRole('textbox', {
- name: /table name/i,
- });
- userEvent.type(inputTableName, 'table1');
- const uploadButton = screen.getByRole('button', {
- name: 'Upload',
- });
-
- expect(uploadButton).toBeEnabled();
- userEvent.click(uploadButton);
- await waitFor(() => fetchMock.called('glob:*api/v1/database/1/upload/'));
-
- // Get the matching fetch calls made
- const matchingCalls = fetchMock.calls('glob:*api/v1/database/1/upload/');
- expect(matchingCalls).toHaveLength(1);
- const [, options] = matchingCalls[0];
- const formData = options?.body as FormData;
- expect(formData.get('type')).toBe('columnar');
- expect(formData.get('table_name')).toBe('table1');
- expect(formData.get('schema')).toBe('public');
- expect(formData.get('table_name')).toBe('table1');
- const fileData = formData.get('file') as File;
- expect(fileData.name).toBe('test.parquet');
-}, 30000);
-
-test('CSV, validate file extension returns false', () => {
- const invalidFileNames = ['out', 'out.exe', 'out.csv.exe', '.csv',
'out.xls'];
- invalidFileNames.forEach(fileName => {
- const file: UploadFile<any> = {
- name: fileName,
- uid: 'xp',
- size: 100,
- type: 'text/csv',
- };
- expect(validateUploadFileExtension(file, ['csv', 'tsv'])).toBe(false);
- });
-});
+ const [, options] = await fillForm('excel', 'test.xls', 'text');
+ const formData = options?.body as FormData;
-test('Excel, validate file extension returns false', () => {
- const invalidFileNames = ['out', 'out.exe', 'out.xls.exe', '.csv',
'out.csv'];
- invalidFileNames.forEach(fileName => {
- const file: UploadFile<any> = {
- name: fileName,
- uid: 'xp',
- size: 100,
- type: 'text/csv',
- };
- expect(validateUploadFileExtension(file, ['xls', 'xlsx'])).toBe(false);
+ expect(formData.get('type')).toBe('excel');
+ expect(formData.get('table_name')).toBe('table1');
+ expect(formData.get('schema')).toBe('public');
+ expect((formData.get('file') as File).name).toBe('test.xls');
});
-});
-test('Columnar, validate file extension returns false', () => {
- const invalidFileNames = [
- 'out',
- 'out.exe',
- 'out.parquet.exe',
- '.parquet',
- 'out.excel',
- ];
- invalidFileNames.forEach(fileName => {
- const file: UploadFile<any> = {
- name: fileName,
- uid: 'xp',
- size: 100,
- type: 'text/csv',
- };
- expect(validateUploadFileExtension(file, ['parquet', 'zip'])).toBe(false);
- });
-});
+ test('Columnar form submission', async () => {
+ render(<UploadDataModal {...columnarProps} />, { useRedux: true });
-test('CSV, validate file extension returns true', () => {
- const invalidFileNames = ['out.csv', 'out.tsv', 'out.exe.csv', 'out a.csv'];
- invalidFileNames.forEach(fileName => {
- const file: UploadFile<any> = {
- name: fileName,
- uid: 'xp',
- size: 100,
- type: 'text/csv',
- };
- expect(validateUploadFileExtension(file, ['csv', 'tsv'])).toBe(true);
- });
-});
+ const [, options] = await fillForm('columnar', 'test.parquet', 'text');
+ const formData = options?.body as FormData;
-test('Excel, validate file extension returns true', () => {
- const invalidFileNames = ['out.xls', 'out.xlsx', 'out.exe.xls', 'out a.xls'];
- invalidFileNames.forEach(fileName => {
- const file: UploadFile<any> = {
- name: fileName,
- uid: 'xp',
- size: 100,
- type: 'text/csv',
- };
- expect(validateUploadFileExtension(file, ['xls', 'xlsx'])).toBe(true);
+ expect(formData.get('type')).toBe('columnar');
+ expect(formData.get('table_name')).toBe('table1');
+ expect(formData.get('schema')).toBe('public');
+ expect((formData.get('file') as File).name).toBe('test.parquet');
});
});
-test('Columnar, validate file extension returns true', () => {
- const invalidFileNames = [
- 'out.parquet',
- 'out.zip',
- 'out.exe.zip',
- 'out a.parquet',
- ];
- invalidFileNames.forEach(fileName => {
- const file: UploadFile<any> = {
- name: fileName,
- uid: 'xp',
- size: 100,
- type: 'text/csv',
- };
- expect(validateUploadFileExtension(file, ['parquet', 'zip'])).toBe(true);
+describe('File Extension Validation', () => {
+ const createTestFile = (fileName: string) => ({
+ name: fileName,
+ uid: 'xp',
+ size: 100,
+ type: 'text/csv',
+ });
+
+ describe('CSV validation', () => {
+ test('returns false for invalid extensions', () => {
+ const invalidFiles = ['out', 'out.exe', 'out.csv.exe', '.csv',
'out.xls'];
+ invalidFiles.forEach(fileName => {
+ expect(
+ validateUploadFileExtension(createTestFile(fileName), ['csv',
'tsv']),
+ ).toBe(false);
+ });
+ });
+
+ test('returns true for valid extensions', () => {
+ const validFiles = ['out.csv', 'out.tsv', 'out.exe.csv', 'out a.csv'];
+ validFiles.forEach(fileName => {
+ expect(
+ validateUploadFileExtension(createTestFile(fileName), ['csv',
'tsv']),
+ ).toBe(true);
+ });
+ });
+ });
+
+ describe('Excel validation', () => {
+ test('returns false for invalid extensions', () => {
+ const invalidFiles = ['out', 'out.exe', 'out.xls.exe', '.csv',
'out.csv'];
+ invalidFiles.forEach(fileName => {
+ expect(
+ validateUploadFileExtension(createTestFile(fileName), [
+ 'xls',
+ 'xlsx',
+ ]),
+ ).toBe(false);
+ });
+ });
+
+ test('returns true for valid extensions', () => {
+ const validFiles = ['out.xls', 'out.xlsx', 'out.exe.xls', 'out a.xls'];
+ validFiles.forEach(fileName => {
+ expect(
+ validateUploadFileExtension(createTestFile(fileName), [
+ 'xls',
+ 'xlsx',
+ ]),
+ ).toBe(true);
+ });
+ });
+ });
+
+ describe('Columnar validation', () => {
+ test('returns false for invalid extensions', () => {
+ const invalidFiles = [
+ 'out',
+ 'out.exe',
+ 'out.parquet.exe',
+ '.parquet',
+ 'out.excel',
+ ];
+ invalidFiles.forEach(fileName => {
+ expect(
+ validateUploadFileExtension(createTestFile(fileName), [
+ 'parquet',
+ 'zip',
+ ]),
+ ).toBe(false);
+ });
+ });
+
+ test('returns true for valid extensions', () => {
+ const validFiles = [
+ 'out.parquet',
+ 'out.zip',
+ 'out.exe.zip',
+ 'out a.parquet',
+ ];
+ validFiles.forEach(fileName => {
+ expect(
+ validateUploadFileExtension(createTestFile(fileName), [
+ 'parquet',
+ 'zip',
+ ]),
+ ).toBe(true);
+ });
+ });
Review Comment:
Thanks for touching on this, this was one of the really flaky tests.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]