From 86f2221303fca823408e129821846b46717a9cb5 Mon Sep 17 00:00:00 2001 From: lyndsiWilliams Date: Thu, 24 Jun 2021 22:05:20 -0500 Subject: [PATCH 1/4] RTL testing on DatabaseModal --- .../database/DatabaseModal/index.test.jsx | 811 ++++++++++++++---- 1 file changed, 625 insertions(+), 186 deletions(-) diff --git a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.test.jsx b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.test.jsx index eec45618e7150..80c963237b497 100644 --- a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.test.jsx +++ b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.test.jsx @@ -18,13 +18,14 @@ */ import React from 'react'; import fetchMock from 'fetch-mock'; -// import userEvent from '@testing-library/user-event'; -import { render, screen } from 'spec/helpers/testing-library'; +import userEvent from '@testing-library/user-event'; +import { render, screen, within, cleanup } from 'spec/helpers/testing-library'; +import { act } from 'react-dom/test-utils'; import DatabaseModal from './index'; const dbProps = { show: true, - databaseId: 10, + // databaseId: 10, database_name: 'my database', sqlalchemy_uri: 'postgres://superset:superset@something:1234/superset', }; @@ -48,162 +49,600 @@ fetchMock.mock(AVAILABLE_DB_ENDPOINT, { { engine: 'mysql', name: 'MySQL', + preferred: true, + }, + { + engine: 'postgresql', + name: 'PostgreSQL', preferred: false, }, ], }); describe('DatabaseModal', () => { - afterEach(fetchMock.restore); - // describe('initial load', () => { - // it('hides the forms from the db when not selected', () => { - // render(, { useRedux: true }); - // // Select Advanced tab - // const advancedTab = screen.getByRole('tab', { - // name: /advanced/i, - // }); - // userEvent.click(advancedTab); - // // Select SQL Lab tab - // const sqlLabSettingsTab = screen.getByRole('tab', { - // name: /sql lab/i, - // }); - // userEvent.click(sqlLabSettingsTab); - - // const exposeInSqlLab = screen.getByText('Expose in SQL Lab'); - // const exposeChoicesForm = exposeInSqlLab.parentElement.nextSibling; - // const schemaField = screen.getByText('CTAS & CVAS SCHEMA').parentElement; - // expect(exposeChoicesForm).not.toHaveClass('open'); - // expect(schemaField).not.toHaveClass('open'); - // }); - // }); - // it('renders all settings when "Expose in SQL Lab" is checked', () => { - // render(, { useRedux: true }); - - // // Select Advanced tab - // const advancedTab = screen.getByRole('tab', { - // name: /advanced/i, - // }); - // userEvent.click(advancedTab); - - // // Select SQL Lab tab - // const sqlLabSettingsTab = screen.getByRole('tab', { - // name: /sql lab/i, - // }); - - // userEvent.click(sqlLabSettingsTab); - - // // Grab all SQL Lab settings by their labels - // // const exposeInSqlLab = screen.getByText('Expose in SQL Lab'); - // const exposeInSqlLab = screen.getByRole('checkbox', { - // name: /expose in sql lab/i, - // }); + async function renderAndWait() { + const mounted = act(async () => { + render(, { + useRedux: true, + }); + }); - // expect(exposeInSqlLab).not.toBeChecked(); - // userEvent.click(exposeInSqlLab); + return mounted; + } + + async function renderAndWaitStep3() { + const newProps = { + ...dbProps, + configuration_method: 'SQLALCHEMY_URI', + }; + const mounted = act(async () => { + render(, { + useRedux: true, + }); + }); - // // While checked make sure all checkboxes are showing - // expect(exposeInSqlLab).toBeChecked(); - // const checkboxes = screen - // .getAllByRole('checkbox') - // .filter(checkbox => !checkbox.checked); + return mounted; + } - // expect(checkboxes.length).toEqual(4); + // beforeEach(async () => { + // await renderAndWait(); // }); - // it('renders the schema field when allowCTAS is checked', () => { - // render(, { useRedux: true }); + afterEach(() => { + cleanup(); + }); - // // Select Advanced tab - // const advancedTab = screen.getByRole('tab', { - // name: /advanced/i, - // }); - // userEvent.click(advancedTab); + describe('New database connection', () => { + it('visually renders the initial load of Step 1 correctly', async () => { + await renderAndWait(); + // ---------- Components ---------- + // - AntD header + const closeButton = screen.getByRole('button', { name: /close/i }); + const step1Header = screen.getByRole('heading', { + name: /connect a database/i, + }); + // - Connection header + const step1Helper = screen.getByText(/step 1 of 3/i); + const selectDbHeader = screen.getByRole('heading', { + name: /select a database to connect/i, + }); + // - Preferred database buttons + const preferredDbButton = screen.getByRole('button', { + name: /default-database mysql/i, + }); + const preferredDbIcon = screen.getByRole('img', { + name: /default-database/i, + }); + const preferredDbText = within(preferredDbButton).getByText(/mysql/i); + // renderAvailableSelector() => - Supported databases selector const supportedDbsHeader = screen.getByRole('heading', { name: /or choose from a list of other databases we support:/i, @@ -149,27 +292,36 @@ describe('DatabaseModal', () => { alertMessage, alertDescription, alertLink, - preferredDbButton, - preferredDbIcon, - preferredDbText, + preferredDbButtonPostgreSQL, + preferredDbButtonPresto, + preferredDbButtonMySQL, + preferredDbButtonSQLite, + preferredDbIcon[0], + preferredDbIcon[1], + preferredDbIcon[2], + preferredDbIcon[3], + preferredDbTextPostgreSQL, + preferredDbTextPresto, + preferredDbTextMySQL, + preferredDbTextSQLite, ]; visibleComponents.forEach(component => { expect(component).toBeVisible(); }); + // This is how many preferred databases are rendered + expect(preferredDbIcon).toHaveLength(4); }); - it('visually renders the "Basic" tab of Step 2 correctly', async () => { - await renderAndWait(); - // ---------- Components ---------- - // On step 1, click dbButton to access step 2 + it('renders the "Basic" tab of SQL Alchemy form (step 2 of 2) correctly', async () => { + // On step 1, click dbButton to access SQL Alchemy form userEvent.click( screen.getByRole('button', { - name: /default-database mysql/i, + name: /default-database sqlite/i, }), ); - // ----- BEGIN STEP 2 (BASIC) + // ---------- Components ---------- // - AntD header const closeButton = screen.getByRole('button', { name: /close/i }); const basicHeader = screen.getByRole('heading', { @@ -246,19 +398,17 @@ describe('DatabaseModal', () => { }); }); - it('visually renders the unexpanded "Advanced" tab of Step 2 correctly', async () => { - await renderAndWait(); - // ---------- Components ---------- + it('renders the unexpanded "Advanced" tab correctly', async () => { // On step 1, click dbButton to access step 2 userEvent.click( screen.getByRole('button', { - name: /default-database mysql/i, + name: /default-database sqlite/i, }), ); // Click the "Advanced" tab userEvent.click(screen.getByRole('tab', { name: /advanced/i })); - // ----- BEGIN STEP 2 (ADVANCED) + // ---------- Components ---------- // - AntD header const closeButton = screen.getByRole('button', { name: /close/i }); const advancedHeader = screen.getByRole('heading', { @@ -346,13 +496,12 @@ describe('DatabaseModal', () => { }); }); - it('visually renders the "Advanced" - SQL LAB tab correctly', async () => { - await renderAndWait(); + it('renders the "Advanced" - SQL LAB tab correctly (unexpanded)', async () => { // ---------- Components ---------- // On step 1, click dbButton to access step 2 userEvent.click( screen.getByRole('button', { - name: /default-database mysql/i, + name: /default-database sqlite/i, }), ); // Click the "Advanced" tab @@ -364,8 +513,6 @@ describe('DatabaseModal', () => { }), ); - // screen.logTestingPlaygroundURL(); - // ----- BEGIN STEP 2 (ADVANCED - SQL LAB) // - AntD header const closeButton = screen.getByRole('button', { name: /close/i }); @@ -388,6 +535,59 @@ describe('DatabaseModal', () => { const sqlLabTab = screen.getByRole('tab', { name: /right sql lab adjust how this database will interact with sql lab\./i, }); + // These are the checkbox SVGs that cover the actual checkboxes + const checkboxOffSVGs = screen.getAllByRole('img', { + name: /checkbox-off/i, + }); + const tooltipIcons = screen.getAllByRole('img', { + name: /info-solid-small/i, + }); + const exposeInSQLLabCheckbox = screen.getByRole('checkbox', { + name: /expose database in sql lab/i, + }); + // This is both the checkbox and it's respective SVG + // const exposeInSQLLabCheckboxSVG = checkboxOffSVGs[0].parentElement; + const exposeInSQLLabText = screen.getByText( + /expose database in sql lab/i, + ); + const allowCTASCheckbox = screen.getByRole('checkbox', { + name: /allow create table as/i, + }); + const allowCTASText = screen.getByText(/allow create table as/i); + const allowCVASCheckbox = screen.getByRole('checkbox', { + name: /allow create table as/i, + }); + const allowCVASText = screen.getByText(/allow create table as/i); + const CTASCVASLabelText = screen.getByText(/ctas & cvas schema/i); + // This grabs the whole input by placeholder text + const CTASCVASInput = screen.getByPlaceholderText( + /create or select schema\.\.\./i, + ); + const CTASCVASHelperText = screen.getByText( + /force all tables and views to be created in this schema when clicking ctas or cvas in sql lab\./i, + ); + const allowDMLCheckbox = screen.getByRole('checkbox', { + name: /allow dml/i, + }); + const allowDMLText = screen.getByText(/allow dml/i); + const allowMultiSchemaMDFetchCheckbox = screen.getByRole('checkbox', { + name: /allow multi schema metadata fetch/i, + }); + const allowMultiSchemaMDFetchText = screen.getByText( + /allow multi schema metadata fetch/i, + ); + const enableQueryCostEstimationCheckbox = screen.getByRole('checkbox', { + name: /enable query cost estimation/i, + }); + const enableQueryCostEstimationText = screen.getByText( + /enable query cost estimation/i, + ); + const allowDbExplorationCheckbox = screen.getByRole('checkbox', { + name: /allow this database to be explored/i, + }); + const allowDbExplorationText = screen.getByText( + /allow this database to be explored/i, + ); // ---------- Assertions ---------- const visibleComponents = [ @@ -400,20 +600,58 @@ describe('DatabaseModal', () => { basicTab, advancedTab, sqlLabTab, + checkboxOffSVGs[0], + checkboxOffSVGs[1], + checkboxOffSVGs[2], + checkboxOffSVGs[3], + checkboxOffSVGs[4], + checkboxOffSVGs[5], + checkboxOffSVGs[6], + tooltipIcons[0], + tooltipIcons[1], + tooltipIcons[2], + tooltipIcons[3], + tooltipIcons[4], + tooltipIcons[5], + tooltipIcons[6], + exposeInSQLLabText, + allowCTASText, + allowCVASText, + CTASCVASLabelText, + CTASCVASInput, + CTASCVASHelperText, + allowDMLText, + allowMultiSchemaMDFetchText, + enableQueryCostEstimationText, + allowDbExplorationText, + ]; + // These components exist in the DOM but are not visible + const invisibleComponents = [ + exposeInSQLLabCheckbox, + allowCTASCheckbox, + allowCVASCheckbox, + allowDMLCheckbox, + allowMultiSchemaMDFetchCheckbox, + enableQueryCostEstimationCheckbox, + allowDbExplorationCheckbox, ]; visibleComponents.forEach(component => { expect(component).toBeVisible(); }); + invisibleComponents.forEach(component => { + expect(component).not.toBeVisible(); + }); + expect(checkboxOffSVGs).toHaveLength(7); + expect(tooltipIcons).toHaveLength(7); }); - it('visually renders the "Advanced" - PERFORMANCE tab correctly', async () => { - await renderAndWait(); + it('renders the "Advanced" - PERFORMANCE tab correctly', async () => { // ---------- Components ---------- // On step 1, click dbButton to access step 2 userEvent.click( screen.getByRole('button', { - name: /default-database mysql/i, + name: /default-database sqlite/i, }), ); // Click the "Advanced" tab @@ -472,13 +710,12 @@ describe('DatabaseModal', () => { }); }); - it('visually renders the "Advanced" - SECURITY tab correctly', async () => { - await renderAndWait(); + it('renders the "Advanced" - SECURITY tab correctly', async () => { // ---------- Components ---------- // On step 1, click dbButton to access step 2 userEvent.click( screen.getByRole('button', { - name: /default-database mysql/i, + name: /default-database sqlite/i, }), ); // Click the "Advanced" tab @@ -541,13 +778,12 @@ describe('DatabaseModal', () => { }); }); - it('visually renders the "Advanced" - OTHER tab correctly', async () => { - await renderAndWait(); + it('renders the "Advanced" - OTHER tab correctly', async () => { // ---------- Components ---------- // On step 1, click dbButton to access step 2 userEvent.click( screen.getByRole('button', { - name: /default-database mysql/i, + name: /default-database sqlite/i, }), ); // Click the "Advanced" tab @@ -614,22 +850,7 @@ describe('DatabaseModal', () => { }); }); - it('Postgres form', async () => { - fetchMock.mock(AVAILABLE_DB_ENDPOINT, { - databases: [ - { - engine: 'mysql', - name: 'MySQL', - preferred: true, - }, - { - engine: 'postgresql', - name: 'PostgreSQL', - preferred: true, - }, - ], - }); - await renderAndWaitStep3(); + it('Dynamic form', async () => { // ---------- Components ---------- // On step 1, click dbButton to access step 2 userEvent.click( @@ -638,123 +859,156 @@ describe('DatabaseModal', () => { }), ); - screen.logTestingPlaygroundURL(); + // screen.logTestingPlaygroundURL(); expect.anything(); }); }); - // describe('create database', () => { - // beforeEach(() => { - // fetchMock.post(DATABASE_POST_ENDPOINT, { - // id: 10, - // }); - // fetchMock.mock(AVAILABLE_DB_ENDPOINT, { - // databases: [ - // { - // engine: 'mysql', - // name: 'MySQL', - // preferred: false, - // }, - // ], - // }); - // }); - // const props = { - // ...dbProps, - // databaseId: null, - // database_name: null, - // sqlalchemy_uri: null, - // }; - // it('should show a form when dynamic_form is selected', async () => { - // render(, { useRedux: true }); - // // it should have the correct header text - // const headerText = screen.getByText(/connect a database/i); - // expect(headerText).toBeVisible(); - - // await screen.findByText(/display name/i); - - // // it does not fetch any databases if no id is passed in - // expect(fetchMock.calls(DATABASE_FETCH_ENDPOINT).length).toEqual(0); - - // // todo we haven't hooked this up to load dynamically yet so - // // we can't currently test it - // }); - // it('should close the modal on save if using the sqlalchemy form', async () => { - // const onHideMock = jest.fn(); - // render(, { - // useRedux: true, - // }); - // // button should be disabled by default - // const submitButton = screen.getByTestId('modal-confirm-button'); - // expect(submitButton).toBeDisabled(); - - // const displayName = screen.getByTestId('database-name-input'); - // userEvent.type(displayName, 'MyTestDB'); - // expect(displayName.value).toBe('MyTestDB'); - // const sqlalchemyInput = screen.getByTestId('sqlalchemy-uri-input'); - // userEvent.type(sqlalchemyInput, 'some_url'); - // expect(sqlalchemyInput.value).toBe('some_url'); - - // // button should not be disabled now - // expect(submitButton).toBeEnabled(); - - // await waitFor(() => { - // userEvent.click(submitButton); - // }); - // expect(fetchMock.calls(DATABASE_POST_ENDPOINT)).toHaveLength(1); - // expect(onHideMock).toHaveBeenCalled(); - // }); - // }); - - // describe('edit database', () => { - // beforeEach(() => { - // fetchMock.mock(AVAILABLE_DB_ENDPOINT, { - // databases: [ - // { - // engine: 'mysql', - // name: 'MySQL', - // preferred: false, - // }, - // ], - // }); - // }); - // it('renders the sqlalchemy form when the sqlalchemy_form configuration method is set', async () => { - // render(, { useRedux: true }); - - // // it should have tabs - // const tabs = screen.getAllByRole('tab'); - // expect(tabs.length).toEqual(2); - // expect(tabs[0]).toHaveTextContent('Basic'); - // expect(tabs[1]).toHaveTextContent('Advanced'); - - // // it should have the correct header text - // const headerText = screen.getByText(/edit database/i); - // expect(headerText).toBeVisible(); - // }); - // it('renders the dynamic form when the dynamic_form configuration method is set', async () => { - // fetchMock.get(DATABASE_FETCH_ENDPOINT, { - // result: { - // id: 10, - // database_name: 'my database', - // expose_in_sqllab: false, - // allow_ctas: false, - // allow_cvas: false, - // configuration_method: 'dynamic_form', - // parameters: { - // database: 'mydatabase', - // }, - // }, - // }); - // render(, { useRedux: true }); - - // await screen.findByText(/edit database/i); - - // // // it should have tabs - // const tabs = screen.getAllByRole('tab'); - // expect(tabs.length).toEqual(2); - - // // it should show a TODO for now - // const headerText = screen.getByText(/edit database/i); - // expect(headerText).toBeVisible(); - // }); - // }); + describe('Functional: Create new database', () => { + it('directs databases to the appropriate form (dynamic vs. SQL Alchemy)', () => { + // ---------- Dynamic example (3-step form) + // Click the PostgreSQL button to enter the dynamic form + const postgreSQLButton = screen.getByRole('button', { + name: /default-database postgresql/i, + }); + userEvent.click(postgreSQLButton); + + // Dynamic form has 3 steps, seeing this text means the dynamic form is present + const dynamicFormStepText = screen.getByText(/step 2 of 3/i); + + expect(dynamicFormStepText).toBeVisible(); + + // ---------- SQL Alchemy example (2-step form) + // Click the back button to go back to step 1, + // then click the SQLite button to enter the SQL Alchemy form + const backButton = screen.getByRole('button', { name: /back/i }); + userEvent.click(backButton); + + const sqliteButton = screen.getByRole('button', { + name: /default-database sqlite/i, + }); + userEvent.click(sqliteButton); + + // SQL Alchemy form has 2 steps, seeing this text means the SQL Alchemy form is present + const sqlAlchemyFormStepText = screen.getByText(/step 2 of 2/i); + + expect(sqlAlchemyFormStepText).toBeVisible(); + }); + + describe('SQL Alchemy form flow', () => { + beforeEach(() => { + userEvent.click( + screen.getByRole('button', { + name: /default-database sqlite/i, + }), + ); + }); + + it('enters step 2 of 2 when proper database is selected', () => { + const step2text = screen.getByText(/step 2 of 2/i); + expect(step2text).toBeVisible(); + }); + + it('runs fetchResource when "Connect" is clicked', () => { + // Mock useSingleViewResource + const mockUseSingleViewResource = jest.fn(); + mockUseSingleViewResource.mockImplementation(useSingleViewResource); + + const { fetchResource } = mockUseSingleViewResource('database'); + + // ---------- 🐞 Not working yet 🐞 ---------- + // Invalid hook call? + userEvent.click(screen.getByRole('button', { name: 'Connect' })); + expect(fetchResource).toHaveBeenCalled(); + }); + + describe('step 2 component interaction', () => { + it('properly interacts with textboxes', () => { + const dbNametextBox = screen.getByTestId('database-name-input'); + expect(dbNametextBox).toHaveValue('SQLite'); + + userEvent.type(dbNametextBox, 'Different text'); + expect(dbNametextBox).toHaveValue('SQLiteDifferent text'); + + const sqlAlchemyURItextBox = screen.getByTestId( + 'sqlalchemy-uri-input', + ); + expect(sqlAlchemyURItextBox).toHaveValue(''); + + userEvent.type(sqlAlchemyURItextBox, 'Different text'); + expect(sqlAlchemyURItextBox).toHaveValue('Different text'); + }); + + it('runs testDatabaseConnection when "TEST CONNECTION" is clicked', () => { + // Mock testDatabaseConnection + const mockTestDatabaseConnection = jest.fn(); + mockTestDatabaseConnection.mockImplementation(testDatabaseConnection); + + userEvent.click( + screen.getByRole('button', { + name: /test connection/i, + }), + ); + + // ---------- 🐞 Not working yet 🐞 ---------- + expect(mockTestDatabaseConnection).toHaveBeenCalled(); + }); + }); + }); + + describe('Dynamic form flow', () => { + beforeEach(() => { + userEvent.click( + screen.getByRole('button', { + name: /default-database postgresql/i, + }), + ); + }); + + it('enters step 2 of 3 when proper database is selected', () => { + const step2of3text = screen.getByText(/step 2 of 3/i); + expect(step2of3text).toBeVisible(); + }); + + it('enters form credentials and runs fetchResource when "Connect" is clicked', () => { + const textboxes = screen.getAllByRole('textbox'); + const hostField = textboxes[0]; + const portField = screen.getByRole('spinbutton'); + const databaseNameField = textboxes[1]; + const usernameField = textboxes[2]; + const passwordField = textboxes[3]; + screen.debug(portField); + + expect(hostField).toHaveValue(''); + expect(portField).toHaveValue(null); + expect(databaseNameField).toHaveValue(''); + expect(usernameField).toHaveValue(''); + expect(passwordField).toHaveValue(''); + + userEvent.type(hostField, 'localhost'); + userEvent.type(portField, '5432'); + userEvent.type(databaseNameField, 'postgres'); + userEvent.type(usernameField, 'testdb'); + userEvent.type(passwordField, 'demoPassword'); + + expect(hostField).toHaveValue('localhost'); + expect(portField).toHaveValue(5432); + expect(databaseNameField).toHaveValue('postgres'); + expect(usernameField).toHaveValue('testdb'); + expect(passwordField).toHaveValue('demoPassword'); + + // Mock useSingleViewResource + const mockUseSingleViewResource = jest.fn(); + mockUseSingleViewResource.mockImplementation(useSingleViewResource); + + const { fetchResource } = mockUseSingleViewResource('database'); + + // ---------- 🐞 Not working yet 🐞 ---------- + // Invalid hook call? + userEvent.click(screen.getByRole('button', { name: 'Connect' })); + expect(fetchResource).toHaveBeenCalled(); + // screen.logTestingPlaygroundURL(); + }); + }); + }); }); From e246738ec78895a5d1220edc1115e2412c49ac33 Mon Sep 17 00:00:00 2001 From: lyndsiWilliams Date: Tue, 29 Jun 2021 11:12:45 -0500 Subject: [PATCH 3/4] Code cleanup --- .../database/DatabaseModal/index.test.jsx | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.test.jsx b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.test.jsx index b7cb0e0fc1c46..5a270de7c44b2 100644 --- a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.test.jsx +++ b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.test.jsx @@ -1,5 +1,3 @@ -/* eslint-disable no-only-tests/no-only-tests */ -/* eslint-disable jest/no-focused-tests */ /** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -28,10 +26,11 @@ import { cleanup, act, } from 'spec/helpers/testing-library'; +/* -- These imports are used for the mock functions that currently don't work import { testDatabaseConnection, useSingleViewResource, -} from 'src/views/CRUD/hooks'; +} from 'src/views/CRUD/hooks'; */ import DatabaseModal from './index'; const dbProps = { @@ -663,8 +662,6 @@ describe('DatabaseModal', () => { }), ); - // screen.logTestingPlaygroundURL(); - // ----- BEGIN STEP 2 (ADVANCED - PERFORMANCE) // - AntD header const closeButton = screen.getByRole('button', { name: /close/i }); @@ -727,8 +724,6 @@ describe('DatabaseModal', () => { }), ); - // screen.logTestingPlaygroundURL(); - // ----- BEGIN STEP 2 (ADVANCED - SECURITY) // - AntD header const closeButton = screen.getByRole('button', { name: /close/i }); @@ -795,8 +790,6 @@ describe('DatabaseModal', () => { }), ); - // screen.logTestingPlaygroundURL(); - // ----- BEGIN STEP 2 (ADVANCED - OTHER) // - AntD header const closeButton = screen.getByRole('button', { name: /close/i }); @@ -859,7 +852,6 @@ describe('DatabaseModal', () => { }), ); - // screen.logTestingPlaygroundURL(); expect.anything(); }); }); @@ -910,16 +902,20 @@ describe('DatabaseModal', () => { }); it('runs fetchResource when "Connect" is clicked', () => { + /* ---------- 🐞 TODO: function mock is not currently working 🐞 ---------- + // Mock useSingleViewResource const mockUseSingleViewResource = jest.fn(); mockUseSingleViewResource.mockImplementation(useSingleViewResource); const { fetchResource } = mockUseSingleViewResource('database'); - // ---------- 🐞 Not working yet 🐞 ---------- // Invalid hook call? userEvent.click(screen.getByRole('button', { name: 'Connect' })); expect(fetchResource).toHaveBeenCalled(); + + The line below makes the linter happy */ + expect.anything(); }); describe('step 2 component interaction', () => { @@ -940,6 +936,8 @@ describe('DatabaseModal', () => { }); it('runs testDatabaseConnection when "TEST CONNECTION" is clicked', () => { + /* ---------- 🐞 TODO: function mock is not currently working 🐞 ---------- + // Mock testDatabaseConnection const mockTestDatabaseConnection = jest.fn(); mockTestDatabaseConnection.mockImplementation(testDatabaseConnection); @@ -950,8 +948,10 @@ describe('DatabaseModal', () => { }), ); - // ---------- 🐞 Not working yet 🐞 ---------- expect(mockTestDatabaseConnection).toHaveBeenCalled(); + + The line below makes the linter happy */ + expect.anything(); }); }); }); @@ -977,7 +977,6 @@ describe('DatabaseModal', () => { const databaseNameField = textboxes[1]; const usernameField = textboxes[2]; const passwordField = textboxes[3]; - screen.debug(portField); expect(hostField).toHaveValue(''); expect(portField).toHaveValue(null); @@ -997,17 +996,19 @@ describe('DatabaseModal', () => { expect(usernameField).toHaveValue('testdb'); expect(passwordField).toHaveValue('demoPassword'); + /* ---------- 🐞 TODO: function mock is not currently working 🐞 ---------- + // Mock useSingleViewResource const mockUseSingleViewResource = jest.fn(); mockUseSingleViewResource.mockImplementation(useSingleViewResource); const { fetchResource } = mockUseSingleViewResource('database'); - // ---------- 🐞 Not working yet 🐞 ---------- // Invalid hook call? userEvent.click(screen.getByRole('button', { name: 'Connect' })); expect(fetchResource).toHaveBeenCalled(); - // screen.logTestingPlaygroundURL(); + + */ }); }); }); From bd15afe23141700eed0b34b97681c305c08b66e0 Mon Sep 17 00:00:00 2001 From: lyndsiWilliams Date: Tue, 29 Jun 2021 11:46:01 -0500 Subject: [PATCH 4/4] Removed a comment that missed my radar --- .../src/views/CRUD/data/database/DatabaseModal/index.test.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.test.jsx b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.test.jsx index 5a270de7c44b2..7b8d822cbcae5 100644 --- a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.test.jsx +++ b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.test.jsx @@ -35,7 +35,6 @@ import DatabaseModal from './index'; const dbProps = { show: true, - // databaseId: 10, database_name: 'my database', sqlalchemy_uri: 'postgres://superset:superset@something:1234/superset', };