diff --git a/superset-frontend/src/explore/components/DataTableControl/CopyButton.test.tsx b/superset-frontend/src/explore/components/DataTableControl/CopyButton.test.tsx new file mode 100644 index 0000000000000..37b5677bd6050 --- /dev/null +++ b/superset-frontend/src/explore/components/DataTableControl/CopyButton.test.tsx @@ -0,0 +1,28 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import { render, screen } from 'spec/helpers/testing-library'; + +import { CopyButton } from '.'; + +test('Render a button', () => { + render(btn); + expect(screen.getByRole('button')).toBeInTheDocument(); + expect(screen.getByRole('button')).toHaveClass('superset-button'); +}); diff --git a/superset-frontend/src/explore/components/DataTableControl/CopyToClipboardButton.test.tsx b/superset-frontend/src/explore/components/DataTableControl/CopyToClipboardButton.test.tsx new file mode 100644 index 0000000000000..2ce91590b9890 --- /dev/null +++ b/superset-frontend/src/explore/components/DataTableControl/CopyToClipboardButton.test.tsx @@ -0,0 +1,41 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import userEvent from '@testing-library/user-event'; +import React from 'react'; +import { render, screen } from 'spec/helpers/testing-library'; +import { CopyToClipboardButton } from '.'; + +test('Render a button', () => { + render(, { + useRedux: true, + }); + expect(screen.getByRole('button')).toBeInTheDocument(); +}); + +test('Should copy to clipboard', () => { + document.execCommand = jest.fn(); + + render(, { + useRedux: true, + }); + + expect(document.execCommand).toHaveBeenCalledTimes(0); + userEvent.click(screen.getByRole('button')); + expect(document.execCommand).toHaveBeenCalledWith('copy'); +}); diff --git a/superset-frontend/src/explore/components/DataTableControl/FilterInput.test.tsx b/superset-frontend/src/explore/components/DataTableControl/FilterInput.test.tsx new file mode 100644 index 0000000000000..fb77c21d7a779 --- /dev/null +++ b/superset-frontend/src/explore/components/DataTableControl/FilterInput.test.tsx @@ -0,0 +1,37 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import userEvent from '@testing-library/user-event'; +import React from 'react'; +import { render, screen } from 'spec/helpers/testing-library'; +import { FilterInput } from '.'; + +jest.mock('lodash/debounce', () => ({ + __esModule: true, + default: (fuc: Function) => fuc, +})); + +test('Render a FilterInput', async () => { + const onChangeHandler = jest.fn(); + render(); + + expect(onChangeHandler).toBeCalledTimes(0); + userEvent.type(screen.getByRole('textbox'), 'test'); + + expect(onChangeHandler).toBeCalledTimes(4); +}); diff --git a/superset-frontend/src/explore/components/DataTableControl/RowCount.test.tsx b/superset-frontend/src/explore/components/DataTableControl/RowCount.test.tsx new file mode 100644 index 0000000000000..be3f0e980c2b8 --- /dev/null +++ b/superset-frontend/src/explore/components/DataTableControl/RowCount.test.tsx @@ -0,0 +1,31 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import React from 'react'; +import { render, screen } from 'spec/helpers/testing-library'; +import { RowCount } from '.'; + +test('Render a RowCount', () => { + render(); + expect(screen.getByText('3 rows retrieved')).toBeInTheDocument(); +}); + +test('Render a RowCount on loading', () => { + render(); + expect(screen.getByText('Loading...')).toBeInTheDocument(); +}); diff --git a/superset-frontend/src/explore/components/DataTableControl.tsx b/superset-frontend/src/explore/components/DataTableControl/index.tsx similarity index 98% rename from superset-frontend/src/explore/components/DataTableControl.tsx rename to superset-frontend/src/explore/components/DataTableControl/index.tsx index 359dc7ecd96c9..934ebe72add76 100644 --- a/superset-frontend/src/explore/components/DataTableControl.tsx +++ b/superset-frontend/src/explore/components/DataTableControl/index.tsx @@ -33,7 +33,7 @@ import { prepareCopyToClipboardTabularData, } from 'src/utils/common'; import CopyToClipboard from 'src/components/CopyToClipboard'; -import RowCountLabel from './RowCountLabel'; +import RowCountLabel from 'src/explore/components/RowCountLabel'; export const CopyButton = styled(Button)` font-size: ${({ theme }) => theme.typography.sizes.s}px; diff --git a/superset-frontend/src/explore/components/DataTableControl/useFilteredTableData.test.ts b/superset-frontend/src/explore/components/DataTableControl/useFilteredTableData.test.ts new file mode 100644 index 0000000000000..f321aee362f08 --- /dev/null +++ b/superset-frontend/src/explore/components/DataTableControl/useFilteredTableData.test.ts @@ -0,0 +1,57 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { renderHook } from '@testing-library/react-hooks'; +import { useFilteredTableData } from '.'; + +const data = [ + { col01: 'some', col02: 'data' }, + { col01: 'any', col02: 'data' }, + { col01: 'some', col02: 'thing' }, + { col01: 'any', col02: 'things' }, +]; + +test('Empty filter', () => { + const hook = renderHook(() => useFilteredTableData('', data)); + expect(hook.result.current).toEqual(data); +}); + +test('Filter by the word "data"', () => { + const hook = renderHook(() => useFilteredTableData('data', data)); + expect(hook.result.current).toEqual([ + { col01: 'some', col02: 'data' }, + { col01: 'any', col02: 'data' }, + ]); +}); + +test('Filter by the word "thing"', () => { + const hook = renderHook(() => useFilteredTableData('thing', data)); + expect(hook.result.current).toEqual([ + { col01: 'some', col02: 'thing' }, + { col01: 'any', col02: 'things' }, + ]); +}); + +test('Filter by the word "any"', () => { + const hook = renderHook(() => useFilteredTableData('any', data)); + expect(hook.result.current).toEqual([ + { col01: 'any', col02: 'data' }, + { col01: 'any', col02: 'things' }, + ]); +}); diff --git a/superset-frontend/src/explore/components/DataTableControl/useTableColumns.test.ts b/superset-frontend/src/explore/components/DataTableControl/useTableColumns.test.ts new file mode 100644 index 0000000000000..b950dbdf60ad0 --- /dev/null +++ b/superset-frontend/src/explore/components/DataTableControl/useTableColumns.test.ts @@ -0,0 +1,64 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { renderHook } from '@testing-library/react-hooks'; +import { useTableColumns } from '.'; + +const data = [ + { col01: 'some', col02: 'data' }, + { col01: 'any', col02: 'data' }, + { col01: 'some', col02: 'thing' }, + { col01: 'any', col02: 'things', col03: 'secret' }, +]; + +test('useTableColumns with no options', () => { + const hook = renderHook(() => useTableColumns(data)); + expect(hook.result.current).toEqual([ + { Cell: expect.any(Function), Header: 'col01', accessor: 'col01' }, + { Cell: expect.any(Function), Header: 'col02', accessor: 'col02' }, + ]); +}); + +test('use only the first record columns', () => { + const hook = renderHook(() => useTableColumns(data)); + expect(hook.result.current).toEqual([ + { Cell: expect.any(Function), Header: 'col01', accessor: 'col01' }, + { Cell: expect.any(Function), Header: 'col02', accessor: 'col02' }, + ]); + + const hook2 = renderHook(() => useTableColumns([data[3], data[0]])); + expect(hook2.result.current).toEqual([ + { Cell: expect.any(Function), Header: 'col01', accessor: 'col01' }, + { Cell: expect.any(Function), Header: 'col02', accessor: 'col02' }, + { Cell: expect.any(Function), Header: 'col03', accessor: 'col03' }, + ]); +}); + +test('useTableColumns with options', () => { + const hook = renderHook(() => useTableColumns(data, { col01: { id: 'ID' } })); + expect(hook.result.current).toEqual([ + { + Cell: expect.any(Function), + Header: 'col01', + accessor: 'col01', + id: 'ID', + }, + { Cell: expect.any(Function), Header: 'col02', accessor: 'col02' }, + ]); +});