Skip to content

Commit f6af157

Browse files
committed
test(pivot-table): add unit tests for pvtRowLabelLast class
1 parent 4c7d050 commit f6af157

File tree

5 files changed

+298
-0
lines changed

5 files changed

+298
-0
lines changed

superset-frontend/plugins/plugin-chart-pivot-table/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@
3131
"@ant-design/icons": "^5.2.6",
3232
"@superset-ui/chart-controls": "*",
3333
"@superset-ui/core": "*",
34+
"@testing-library/dom": "^8.20.1",
35+
"@testing-library/jest-dom": "*",
36+
"@testing-library/react": "^12.1.5",
37+
"@testing-library/react-hooks": "*",
38+
"@testing-library/user-event": "*",
3439
"lodash": "^4.17.11",
3540
"prop-types": "*",
3641
"react": "^17.0.2",
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
import '@testing-library/jest-dom';
20+
import { render } from '@testing-library/react';
21+
import PivotTableChart from '../src/PivotTableChart';
22+
import transformProps from '../src/plugin/transformProps';
23+
import testData from './testData';
24+
import { ProviderWrapper } from './testHelpers';
25+
26+
test('applies pvtRowLabelLast class to last data row when colTotals is disabled', () => {
27+
const transformedProps = {
28+
...transformProps(testData.withoutColTotals),
29+
margin: 32,
30+
legacy_order_by: null,
31+
order_desc: false,
32+
};
33+
const { container } = render(
34+
ProviderWrapper({
35+
children: <PivotTableChart {...transformedProps} />,
36+
}),
37+
);
38+
39+
const tableBody = container.querySelector('tbody');
40+
const dataRows = Array.from(tableBody?.querySelectorAll('tr') ?? []).filter(
41+
row => !row.classList.contains('pvtRowTotals'),
42+
);
43+
44+
// Get the last data row
45+
const lastDataRow = dataRows[dataRows.length - 1];
46+
expect(lastDataRow).toBeInTheDocument();
47+
48+
// Check if any cell in the last data row has pvtRowLabelLast class
49+
const lastRowCells = lastDataRow.querySelectorAll('th.pvtRowLabel');
50+
const hasLastClass = Array.from(lastRowCells).some(cell =>
51+
cell.classList.contains('pvtRowLabelLast'),
52+
);
53+
54+
expect(hasLastClass).toBe(true);
55+
});
56+
57+
test('does not apply pvtRowLabelLast class to last data row when colTotals is enabled', () => {
58+
const transformedProps = {
59+
...transformProps(testData.withColTotals),
60+
margin: 32,
61+
legacy_order_by: null,
62+
order_desc: false,
63+
};
64+
const { container } = render(
65+
ProviderWrapper({
66+
children: <PivotTableChart {...transformedProps} />,
67+
}),
68+
);
69+
70+
const tableBody = container.querySelector('tbody');
71+
const dataRows = Array.from(tableBody?.querySelectorAll('tr') ?? []).filter(
72+
row => !row.classList.contains('pvtRowTotals'),
73+
);
74+
75+
// Get the last data row (before totals row)
76+
const lastDataRow = dataRows[dataRows.length - 1];
77+
expect(lastDataRow).toBeInTheDocument();
78+
79+
// Check if any cell in the last data row has pvtRowLabelLast class
80+
const lastRowCells = lastDataRow.querySelectorAll('th.pvtRowLabel');
81+
const hasLastClass = Array.from(lastRowCells).some(cell =>
82+
cell.classList.contains('pvtRowLabelLast'),
83+
);
84+
85+
// Should NOT have the class because totals row will have the border
86+
expect(hasLastClass).toBe(false);
87+
88+
// Verify totals row exists
89+
const totalsRow = container.querySelector('tr.pvtRowTotals');
90+
expect(totalsRow).toBeInTheDocument();
91+
});
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
import {
20+
ChartDataResponseResult,
21+
ChartProps,
22+
DatasourceType,
23+
VizType,
24+
QueryFormData,
25+
} from '@superset-ui/core';
26+
import { supersetTheme } from '@apache-superset/core/ui';
27+
import { GenericDataType } from '@apache-superset/core/api/core';
28+
29+
const basicFormData: QueryFormData = {
30+
datasource: '1__table',
31+
viz_type: VizType.PivotTable,
32+
groupbyRows: ['country'],
33+
groupbyColumns: ['city'],
34+
metrics: ['SUM(sales)'],
35+
metricsLayout: 'COLUMNS',
36+
rowOrder: 'key_a_to_z',
37+
colOrder: 'key_a_to_z',
38+
aggregateFunction: 'Sum',
39+
rowSubTotals: false,
40+
colTotals: true,
41+
colSubTotals: false,
42+
rowTotals: true,
43+
valueFormat: 'SMART_NUMBER',
44+
dateFormat: 'smart_date',
45+
transposePivot: false,
46+
combineMetric: false,
47+
rowSubtotalPosition: false,
48+
colSubtotalPosition: false,
49+
};
50+
51+
const basicChartProps = {
52+
width: 800,
53+
height: 600,
54+
datasource: {
55+
id: 1,
56+
name: 'test_dataset',
57+
type: DatasourceType.Table,
58+
columns: [],
59+
metrics: [],
60+
columnFormats: {},
61+
verboseMap: {},
62+
},
63+
hooks: {},
64+
initialValues: {},
65+
queriesData: [
66+
{
67+
data: {
68+
columns: [],
69+
records: [],
70+
},
71+
},
72+
],
73+
formData: basicFormData,
74+
theme: supersetTheme,
75+
};
76+
77+
const basicQueryResult: ChartDataResponseResult = {
78+
annotation_data: null,
79+
cache_key: null,
80+
cached_dttm: null,
81+
cache_timeout: null,
82+
data: [],
83+
colnames: [],
84+
coltypes: [],
85+
error: null,
86+
is_cached: false,
87+
query: 'SELECT ...',
88+
rowcount: 100,
89+
sql_rowcount: 100,
90+
stacktrace: null,
91+
status: 'success',
92+
from_dttm: null,
93+
to_dttm: null,
94+
};
95+
96+
// Shared test data
97+
const pivotData = [
98+
{ country: 'France', city: 'Paris', 'SUM(sales)': 1000 },
99+
{ country: 'Germany', city: 'Berlin', 'SUM(sales)': 2000 },
100+
{ country: 'Spain', city: 'Madrid', 'SUM(sales)': 1500 },
101+
{ country: 'Italy', city: 'Rome', 'SUM(sales)': 3000 },
102+
{ country: 'UK', city: 'London', 'SUM(sales)': 2500 },
103+
];
104+
105+
// Shared query result structure
106+
const basicQueriesData = [
107+
{
108+
...basicQueryResult,
109+
colnames: ['country', 'city', 'SUM(sales)'],
110+
coltypes: [
111+
GenericDataType.String,
112+
GenericDataType.String,
113+
GenericDataType.Numeric,
114+
],
115+
data: pivotData,
116+
},
117+
];
118+
119+
/**
120+
* Pivot table data with colTotals enabled
121+
*/
122+
const withColTotals = {
123+
...new ChartProps({
124+
...basicChartProps,
125+
formData: {
126+
...basicFormData,
127+
colTotals: true,
128+
rowTotals: true,
129+
rowSubTotals: false,
130+
colSubTotals: false,
131+
},
132+
}),
133+
queriesData: basicQueriesData,
134+
};
135+
136+
/**
137+
* Pivot table data without colTotals
138+
*/
139+
const withoutColTotals = {
140+
...new ChartProps({
141+
...basicChartProps,
142+
formData: {
143+
...basicFormData,
144+
colTotals: false,
145+
rowTotals: false,
146+
rowSubTotals: false,
147+
colSubTotals: false,
148+
},
149+
}),
150+
queriesData: basicQueriesData,
151+
};
152+
153+
export default {
154+
withColTotals,
155+
withoutColTotals,
156+
};
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
import {
20+
supersetTheme,
21+
ThemeProvider,
22+
EmotionCacheProvider,
23+
createEmotionCache,
24+
} from '@apache-superset/core/ui';
25+
26+
const emotionCache = createEmotionCache({
27+
key: 'test',
28+
});
29+
30+
export function ProviderWrapper(props: any) {
31+
const { children, theme = supersetTheme } = props;
32+
return (
33+
<EmotionCacheProvider value={emotionCache}>
34+
<ThemeProvider theme={theme}>{children}</ThemeProvider>
35+
</EmotionCacheProvider>
36+
);
37+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"compilerOptions": {
3+
"composite": false,
4+
"emitDeclarationOnly": false,
5+
"rootDir": "../../../"
6+
},
7+
"extends": "../../../tsconfig.json",
8+
"include": ["**/*", "../types/**/*", "../../../types/**/*"]
9+
}

0 commit comments

Comments
 (0)