This is an automated email from the ASF dual-hosted git repository.

michaelsmolina pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 69732d9dca fix(superset-ui-core): achieve 100% coverage for npm run 
core:cover (#38397)
69732d9dca is described below

commit 69732d9dca662a415e020488be98f5bacbb7de76
Author: Michael S. Molina <[email protected]>
AuthorDate: Wed Mar 4 13:56:51 2026 -0300

    fix(superset-ui-core): achieve 100% coverage for npm run core:cover (#38397)
---
 .../src/utils/metricColumnFilter.test.ts           |   8 +
 .../test/utils/getColorFormatters.test.ts          |  41 ++
 .../Matrixify/MatrixifyGridGenerator.test.ts       | 120 +++++
 .../components/Matrixify/MatrixifyGridGenerator.ts |   8 +-
 .../types/matrixify.mocks.test.ts}                 |  20 +-
 .../src/chart/types/matrixify.test.ts              |  82 +++
 .../superset-ui-core/src/chart/types/matrixify.ts  |  36 +-
 .../AsyncAceEditor/useJsonValidation.test.ts       |  25 +
 .../src/components/List/List.test.tsx              |  10 +
 .../src/components/Select/constants.test.ts        |  49 ++
 .../Table/utils/InteractiveTableUtils.test.ts      | 574 +++++++++++++++++++++
 .../src/types/react-syntax-highlighter.d.ts        |   7 -
 .../src/utils/rankedSearchCompare.test.ts          |  20 +
 .../List/List.test.tsx => utils/withLabel.test.ts} |  33 +-
 .../test/connection/SupersetClient.test.ts         |   6 +
 .../test/connection/SupersetClientClass.test.ts    |  33 ++
 .../test/currency-format/CurrencyFormatter.test.ts |  78 +++
 .../test/currency-format/utils.test.ts             | 193 +++++++
 .../test/query/types/Column.test.ts                |  14 +
 .../test/query/types/Dashboard.test.ts             |  33 ++
 20 files changed, 1328 insertions(+), 62 deletions(-)

diff --git 
a/superset-frontend/packages/superset-ui-chart-controls/src/utils/metricColumnFilter.test.ts
 
b/superset-frontend/packages/superset-ui-chart-controls/src/utils/metricColumnFilter.test.ts
index f6202263a2..a81ea54a62 100644
--- 
a/superset-frontend/packages/superset-ui-chart-controls/src/utils/metricColumnFilter.test.ts
+++ 
b/superset-frontend/packages/superset-ui-chart-controls/src/utils/metricColumnFilter.test.ts
@@ -45,6 +45,14 @@ describe('metricColumnFilter', () => {
     }) as SqlaFormData;
 
   describe('shouldSkipMetricColumn', () => {
+    test('should return false for empty colname', () => {
+      const colnames = ['metric1', '%metric1'];
+      const formData = createFormData([], ['metric1']);
+      expect(shouldSkipMetricColumn({ colname: '', colnames, formData })).toBe(
+        false,
+      );
+    });
+
     test('should skip unprefixed percent metric columns if prefixed version 
exists', () => {
       const colnames = ['metric1', '%metric1'];
       const formData = createFormData([], ['metric1']);
diff --git 
a/superset-frontend/packages/superset-ui-chart-controls/test/utils/getColorFormatters.test.ts
 
b/superset-frontend/packages/superset-ui-chart-controls/test/utils/getColorFormatters.test.ts
index 0c0563049f..16e4feeb3e 100644
--- 
a/superset-frontend/packages/superset-ui-chart-controls/test/utils/getColorFormatters.test.ts
+++ 
b/superset-frontend/packages/superset-ui-chart-controls/test/utils/getColorFormatters.test.ts
@@ -506,6 +506,19 @@ test('getColorFunction IsNotNull', () => {
   expect(colorFunction(null)).toBeUndefined();
 });
 
+test('getColorFunction IsNotNull returns undefined for non-boolean value', () 
=> {
+  const colorFunction = getColorFunction(
+    {
+      operator: Comparator.IsNotNull,
+      targetValue: '',
+      colorScheme: '#FF0000',
+      column: 'isMember',
+    },
+    boolValues,
+  );
+  expect(colorFunction(50 as unknown as boolean)).toBeUndefined();
+});
+
 test('getColorFunction returns undefined for null values on numeric 
comparators', () => {
   const operators = [
     { operator: Comparator.LessThan, targetValue: 50 },
@@ -805,6 +818,34 @@ test('getColorFormatters with useGradient flag', () => {
   expect(colorFormatters[1].getColorFromValue(100)).toEqual('#00FF00FF');
 });
 
+test('getColorFunction NOT_EQUAL returns undefined when targetValue is 
non-numeric', () => {
+  const colorFunction = getColorFunction(
+    {
+      operator: Comparator.NotEqual,
+      targetValue: 'not-a-number' as unknown as number,
+      colorScheme: '#FF0000',
+      column: 'count',
+    },
+    countValues,
+  );
+  expect(colorFunction(50)).toBeUndefined();
+  expect(colorFunction(100)).toBeUndefined();
+});
+
+test('getColorFormatters resolves colorScheme from theme when it starts with 
"color"', () => {
+  const theme = { colorPrimary: '#AABBCC' };
+  const columnConfig = [
+    {
+      operator: Comparator.None,
+      colorScheme: 'colorPrimary',
+      column: 'count',
+    },
+  ];
+  const colorFormatters = getColorFormatters(columnConfig, mockData, theme);
+  expect(colorFormatters).toHaveLength(1);
+  expect(colorFormatters[0].getColorFromValue(75)).toContain('#AABBCC');
+});
+
 test('correct column boolean config', () => {
   const columnConfigBoolean = [
     {
diff --git 
a/superset-frontend/packages/superset-ui-core/src/chart/components/Matrixify/MatrixifyGridGenerator.test.ts
 
b/superset-frontend/packages/superset-ui-core/src/chart/components/Matrixify/MatrixifyGridGenerator.test.ts
index 5a66173718..a2915fef43 100644
--- 
a/superset-frontend/packages/superset-ui-core/src/chart/components/Matrixify/MatrixifyGridGenerator.test.ts
+++ 
b/superset-frontend/packages/superset-ui-core/src/chart/components/Matrixify/MatrixifyGridGenerator.test.ts
@@ -294,6 +294,126 @@ test('should preserve existing adhoc filters', () => {
   );
 });
 
+test('should return null when no matrixify configuration exists', () => {
+  const formData: TestFormData = {
+    viz_type: 'table',
+    datasource: '1__table',
+    // No matrixify_mode_rows or matrixify_mode_columns
+  };
+
+  const grid = generateMatrixifyGrid(formData);
+  expect(grid).toBeNull();
+});
+
+test('should generate single-column grid when only rows are configured', () => 
{
+  const rowsOnlyFormData: TestFormData = {
+    viz_type: 'table',
+    datasource: '1__table',
+    matrixify_mode_rows: 'metrics',
+    matrixify_rows: [createAdhocMetric('Revenue'), 
createAdhocMetric('Profit')],
+    // No column config
+  };
+
+  const grid = generateMatrixifyGrid(rowsOnlyFormData);
+  expect(grid).not.toBeNull();
+  expect(grid!.rowHeaders).toEqual(['Revenue', 'Profit']);
+  expect(grid!.colHeaders).toEqual(['']);
+  expect(grid!.cells).toHaveLength(2);
+  expect(grid!.cells[0]).toHaveLength(1);
+});
+
+test('should generate single-row grid when only columns are configured', () => 
{
+  const colsOnlyFormData: TestFormData = {
+    viz_type: 'table',
+    datasource: '1__table',
+    matrixify_mode_columns: 'metrics',
+    matrixify_columns: [
+      createSqlMetric('Q1', 'SUM(q1)'),
+      createSqlMetric('Q2', 'SUM(q2)'),
+    ],
+    // No row config
+  };
+
+  const grid = generateMatrixifyGrid(colsOnlyFormData);
+  expect(grid).not.toBeNull();
+  expect(grid!.rowHeaders).toEqual(['']);
+  expect(grid!.colHeaders).toEqual(['Q1', 'Q2']);
+  expect(grid!.cells).toHaveLength(1);
+  expect(grid!.cells[0]).toHaveLength(2);
+});
+
+test('should handle invalid Handlebars template gracefully', () => {
+  const formDataWithBadTemplate: TestFormData = {
+    ...baseFormData,
+    matrixify_cell_title_template: '{{#if}}unclosed',
+  };
+
+  const grid = generateMatrixifyGrid(formDataWithBadTemplate);
+  expect(grid).not.toBeNull();
+  // Should not throw - returns empty title on template error
+  const firstCell = grid!.cells[0][0];
+  expect(firstCell!.title).toBe('');
+});
+
+test('should return empty string header for null metric in array (line 76)', 
() => {
+  const formData: TestFormData = {
+    viz_type: 'table',
+    datasource: '1__table',
+    matrixify_mode_rows: 'metrics',
+    matrixify_mode_columns: 'metrics',
+    matrixify_rows: [null],
+    matrixify_columns: [createAdhocMetric('Q1')],
+  };
+  const grid = generateMatrixifyGrid(formData);
+  expect(grid).not.toBeNull();
+  expect(grid!.rowHeaders).toEqual(['']);
+});
+
+test('should return empty string header for empty-string dimension value (line 
86)', () => {
+  const formData: TestFormData = {
+    viz_type: 'table',
+    datasource: '1__table',
+    matrixify_mode_rows: 'dimensions',
+    matrixify_mode_columns: 'dimensions',
+    matrixify_dimension_rows: { dimension: 'country', values: [''] },
+    matrixify_dimension_columns: { dimension: 'product', values: ['Widget'] },
+  };
+  const grid = generateMatrixifyGrid(formData);
+  expect(grid).not.toBeNull();
+  expect(grid!.rowHeaders).toEqual(['']);
+});
+
+test('should skip dimension filter when value is undefined (lines 151, 165)', 
() => {
+  const formData: TestFormData = {
+    viz_type: 'table',
+    datasource: '1__table',
+    matrixify_mode_rows: 'dimensions',
+    matrixify_mode_columns: 'dimensions',
+    matrixify_dimension_rows: {
+      dimension: 'country',
+      values: [undefined, 'USA'],
+    },
+    matrixify_dimension_columns: {
+      dimension: 'product',
+      values: [undefined, 'Widget'],
+    },
+  };
+  const grid = generateMatrixifyGrid(formData);
+  expect(grid).not.toBeNull();
+  // Cell at row=0, col=0 has undefined values on both axes — no filters 
applied
+  const cell00 = grid!.cells[0][0];
+  expect(cell00).toBeDefined();
+  expect(cell00!.formData.adhoc_filters ?? []).toEqual([]);
+  // Cell at row=1, col=1 has defined values — filters applied
+  const cell11 = grid!.cells[1][1];
+  expect(cell11!.formData.adhoc_filters).toEqual(
+    expect.arrayContaining([
+      expect.objectContaining({ subject: 'country', comparator: 'USA' }),
+      expect.objectContaining({ subject: 'product', comparator: 'Widget' }),
+    ]),
+  );
+});
+
 test('should handle metrics without labels', () => {
   const metricsWithoutLabels: TestFormData = {
     viz_type: 'table',
diff --git 
a/superset-frontend/packages/superset-ui-core/src/chart/components/Matrixify/MatrixifyGridGenerator.ts
 
b/superset-frontend/packages/superset-ui-core/src/chart/components/Matrixify/MatrixifyGridGenerator.ts
index 7895bf23a2..cc12d396b9 100644
--- 
a/superset-frontend/packages/superset-ui-core/src/chart/components/Matrixify/MatrixifyGridGenerator.ts
+++ 
b/superset-frontend/packages/superset-ui-core/src/chart/components/Matrixify/MatrixifyGridGenerator.ts
@@ -276,10 +276,10 @@ export function generateMatrixifyGrid(
 
       const cellFormData = generateCellFormData(
         formData,
-        rowCount > 0 ? config.rows : null,
-        colCount > 0 ? config.columns : null,
-        rowCount > 0 ? row : null,
-        colCount > 0 ? col : null,
+        config.rows,
+        config.columns,
+        row,
+        col,
       );
 
       // Generate title using template if provided
diff --git 
a/superset-frontend/packages/superset-ui-core/src/types/react-syntax-highlighter.d.ts
 
b/superset-frontend/packages/superset-ui-core/src/chart/types/matrixify.mocks.test.ts
similarity index 60%
copy from 
superset-frontend/packages/superset-ui-core/src/types/react-syntax-highlighter.d.ts
copy to 
superset-frontend/packages/superset-ui-core/src/chart/types/matrixify.mocks.test.ts
index f0860387dd..3fd4d0160d 100644
--- 
a/superset-frontend/packages/superset-ui-core/src/types/react-syntax-highlighter.d.ts
+++ 
b/superset-frontend/packages/superset-ui-core/src/chart/types/matrixify.mocks.test.ts
@@ -16,19 +16,13 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-declare module 'react-syntax-highlighter/dist/cjs/light' {
-  import SyntaxHighlighter from 'react-syntax-highlighter';
-  export default SyntaxHighlighter;
-}
 
-declare module 'react-syntax-highlighter/dist/cjs/styles/hljs/github' {
-  const style: any;
-  export default style;
-}
+import { isMatrixifyEnabled, MatrixifyGridRenderer } from './matrixify.mocks';
 
-type SupportedLanguages = 'markdown' | 'htmlbars' | 'sql' | 'json';
+test('isMatrixifyEnabled mock returns false by default', () => {
+  expect(isMatrixifyEnabled()).toBe(false);
+});
 
-// For type checking when importing languages
-function importLanguage<T extends SupportedLanguages>(language: T) {
-  return 
import(`react-syntax-highlighter/dist/cjs/languages/hljs/${language}`);
-}
+test('MatrixifyGridRenderer mock returns null by default', () => {
+  expect(MatrixifyGridRenderer()).toBeNull();
+});
diff --git 
a/superset-frontend/packages/superset-ui-core/src/chart/types/matrixify.test.ts 
b/superset-frontend/packages/superset-ui-core/src/chart/types/matrixify.test.ts
index 3ac8fa4b0a..6fe052a5a7 100644
--- 
a/superset-frontend/packages/superset-ui-core/src/chart/types/matrixify.test.ts
+++ 
b/superset-frontend/packages/superset-ui-core/src/chart/types/matrixify.test.ts
@@ -260,6 +260,88 @@ test('should handle empty form data object', () => {
   expect(isMatrixifyEnabled(formData)).toBe(false);
 });
 
+test('isMatrixifyEnabled should return false when layout enabled but no axis 
modes configured', () => {
+  const formData = {
+    viz_type: 'table',
+    matrixify_enable_vertical_layout: true,
+    // No matrixify_mode_rows or matrixify_mode_columns set
+  } as MatrixifyFormData;
+  expect(isMatrixifyEnabled(formData)).toBe(false);
+});
+
+test('getMatrixifyValidationErrors should return dimension error for rows when 
dimension has no data', () => {
+  const formData = {
+    viz_type: 'table',
+    matrixify_enable_vertical_layout: true,
+    matrixify_mode_rows: 'dimensions',
+    // No matrixify_dimension_rows set
+    matrixify_mode_columns: 'metrics',
+    matrixify_columns: [createMetric('Q1')],
+  } as MatrixifyFormData;
+
+  const errors = getMatrixifyValidationErrors(formData);
+  expect(errors).toContain('Please select a dimension and values for rows');
+});
+
+test('getMatrixifyValidationErrors should return metric error for columns when 
metrics array is empty', () => {
+  const formData = {
+    viz_type: 'table',
+    matrixify_enable_vertical_layout: true,
+    matrixify_mode_rows: 'metrics',
+    matrixify_rows: [createMetric('Revenue')],
+    matrixify_mode_columns: 'metrics',
+    matrixify_columns: [],
+  } as MatrixifyFormData;
+
+  const errors = getMatrixifyValidationErrors(formData);
+  expect(errors).toContain('Please select at least one metric for columns');
+});
+
+test('getMatrixifyValidationErrors should return dimension error for columns 
when no dimension data', () => {
+  const formData = {
+    viz_type: 'table',
+    matrixify_enable_vertical_layout: true,
+    matrixify_mode_rows: 'metrics',
+    matrixify_rows: [createMetric('Revenue')],
+    matrixify_mode_columns: 'dimensions',
+    // No matrixify_dimension_columns set
+  } as MatrixifyFormData;
+
+  const errors = getMatrixifyValidationErrors(formData);
+  expect(errors).toContain('Please select a dimension and values for columns');
+});
+
+test('getMatrixifyValidationErrors skips row check when matrixify_mode_rows is 
not set (line 240 false, line 279 || false)', () => {
+  const formData = {
+    viz_type: 'table',
+    matrixify_enable_vertical_layout: true,
+    // No matrixify_mode_rows — hasRowMode = false
+    matrixify_mode_columns: 'metrics',
+    matrixify_columns: [createMetric('Q1')],
+  } as MatrixifyFormData;
+
+  const errors = getMatrixifyValidationErrors(formData);
+  expect(errors).toEqual([]);
+});
+
+test('getMatrixifyValidationErrors evaluates full && expression when dimension 
is set but values are empty (lines 244, 264, 283, 291 true branches)', () => {
+  const formData = {
+    viz_type: 'table',
+    matrixify_enable_vertical_layout: true,
+    matrixify_mode_rows: 'dimensions',
+    matrixify_dimension_rows: { dimension: 'country', values: [] },
+    matrixify_mode_columns: 'dimensions',
+    matrixify_dimension_columns: { dimension: 'product', values: [] },
+  } as MatrixifyFormData;
+
+  const errors = getMatrixifyValidationErrors(formData);
+  expect(errors).toContain('Please select a dimension and values for rows');
+  expect(errors).toContain('Please select a dimension and values for columns');
+  expect(errors).toContain(
+    'Configure at least one complete row or column axis',
+  );
+});
+
 test('should handle partial configuration with one axis only', () => {
   const formData = {
     viz_type: 'table',
diff --git 
a/superset-frontend/packages/superset-ui-core/src/chart/types/matrixify.ts 
b/superset-frontend/packages/superset-ui-core/src/chart/types/matrixify.ts
index e90a6b3a87..8c01651ca6 100644
--- a/superset-frontend/packages/superset-ui-core/src/chart/types/matrixify.ts
+++ b/superset-frontend/packages/superset-ui-core/src/chart/types/matrixify.ts
@@ -276,28 +276,24 @@ export function getMatrixifyValidationErrors(
   }
 
   // Must have at least one valid axis
-  if (hasRowMode || hasColumnMode) {
-    const hasRowData =
-      config.rows.mode === 'metrics'
-        ? config.rows.metrics && config.rows.metrics.length > 0
-        : config.rows.dimension?.dimension &&
-          (config.rows.selectionMode === 'topn' ||
-            (config.rows.dimension.values &&
-              config.rows.dimension.values.length > 0));
+  const hasAnyRowData =
+    config.rows.mode === 'metrics'
+      ? config.rows.metrics && config.rows.metrics.length > 0
+      : config.rows.dimension?.dimension &&
+        (config.rows.selectionMode === 'topn' ||
+          (config.rows.dimension.values &&
+            config.rows.dimension.values.length > 0));
 
-    const hasColumnData =
-      config.columns.mode === 'metrics'
-        ? config.columns.metrics && config.columns.metrics.length > 0
-        : config.columns.dimension?.dimension &&
-          (config.columns.selectionMode === 'topn' ||
-            (config.columns.dimension.values &&
-              config.columns.dimension.values.length > 0));
+  const hasAnyColumnData =
+    config.columns.mode === 'metrics'
+      ? config.columns.metrics && config.columns.metrics.length > 0
+      : config.columns.dimension?.dimension &&
+        (config.columns.selectionMode === 'topn' ||
+          (config.columns.dimension.values &&
+            config.columns.dimension.values.length > 0));
 
-    if (!hasRowData && !hasColumnData) {
-      errors.push('Configure at least one complete row or column axis');
-    }
-  } else {
-    errors.push('Please configure at least one row or column axis');
+  if (!hasAnyRowData && !hasAnyColumnData) {
+    errors.push('Configure at least one complete row or column axis');
   }
 
   return errors;
diff --git 
a/superset-frontend/packages/superset-ui-core/src/components/AsyncAceEditor/useJsonValidation.test.ts
 
b/superset-frontend/packages/superset-ui-core/src/components/AsyncAceEditor/useJsonValidation.test.ts
index bab4cc313d..e9179b4ce7 100644
--- 
a/superset-frontend/packages/superset-ui-core/src/components/AsyncAceEditor/useJsonValidation.test.ts
+++ 
b/superset-frontend/packages/superset-ui-core/src/components/AsyncAceEditor/useJsonValidation.test.ts
@@ -72,4 +72,29 @@ describe('useJsonValidation', () => {
 
     expect(result.current[0].text).toContain('Custom error');
   });
+
+  test('falls back to "syntax error" when thrown error has no message (line 59 
|| branch)', () => {
+    const spy = jest.spyOn(JSON, 'parse').mockImplementationOnce(() => {
+      throw {}; // no .message property → error.message is undefined → falsy
+    });
+
+    const { result } = renderHook(() => useJsonValidation('some invalid 
json'));
+    spy.mockRestore();
+
+    expect(result.current).toHaveLength(1);
+    expect(result.current[0].text).toContain('syntax error');
+  });
+
+  test('extracts row and column from error when message contains (line X 
column Y)', () => {
+    const spy = jest.spyOn(JSON, 'parse').mockImplementationOnce(() => {
+      throw new SyntaxError('Unexpected token (line 3 column 5)');
+    });
+
+    const { result } = renderHook(() => useJsonValidation('some invalid 
json'));
+    spy.mockRestore();
+
+    expect(result.current).toHaveLength(1);
+    expect(result.current[0].row).toBe(2); // 3 - 1 = 2 (0-based)
+    expect(result.current[0].column).toBe(4); // 5 - 1 = 4 (0-based)
+  });
 });
diff --git 
a/superset-frontend/packages/superset-ui-core/src/components/List/List.test.tsx 
b/superset-frontend/packages/superset-ui-core/src/components/List/List.test.tsx
index 2423bc3a00..3c3c53dad4 100644
--- 
a/superset-frontend/packages/superset-ui-core/src/components/List/List.test.tsx
+++ 
b/superset-frontend/packages/superset-ui-core/src/components/List/List.test.tsx
@@ -40,3 +40,13 @@ test('should render the correct number of items', () => {
     expect(item).toHaveTextContent(`Item ${index + 1}`);
   });
 });
+
+test('should render List.Item with compact prop', () => {
+  const { container } = render(<List.Item compact>Compact content</List.Item>);
+  expect(container).toBeInTheDocument();
+});
+
+test('should render List.Item without compact prop', () => {
+  const { container } = render(<List.Item>Regular content</List.Item>);
+  expect(container).toBeInTheDocument();
+});
diff --git 
a/superset-frontend/packages/superset-ui-core/src/components/Select/constants.test.ts
 
b/superset-frontend/packages/superset-ui-core/src/components/Select/constants.test.ts
new file mode 100644
index 0000000000..78882c8215
--- /dev/null
+++ 
b/superset-frontend/packages/superset-ui-core/src/components/Select/constants.test.ts
@@ -0,0 +1,49 @@
+/**
+ * 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 type { LabeledValue as AntdLabeledValue } from 'antd/es/select';
+import { DEFAULT_SORT_COMPARATOR } from './constants';
+
+test('DEFAULT_SORT_COMPARATOR sorts by label text when both labels are 
strings', () => {
+  const a = { value: 'b', label: 'banana' } as AntdLabeledValue;
+  const b = { value: 'a', label: 'apple' } as AntdLabeledValue;
+  expect(DEFAULT_SORT_COMPARATOR(a, b)).toBeGreaterThan(0);
+  expect(DEFAULT_SORT_COMPARATOR(b, a)).toBeLessThan(0);
+});
+
+test('DEFAULT_SORT_COMPARATOR sorts by value text when labels are not 
strings', () => {
+  const a = { value: 'b' } as AntdLabeledValue;
+  const b = { value: 'a' } as AntdLabeledValue;
+  expect(DEFAULT_SORT_COMPARATOR(a, b)).toBeGreaterThan(0);
+  expect(DEFAULT_SORT_COMPARATOR(b, a)).toBeLessThan(0);
+});
+
+test('DEFAULT_SORT_COMPARATOR returns numeric difference when values are 
numbers', () => {
+  const a = { value: 3 } as unknown as AntdLabeledValue;
+  const b = { value: 1 } as unknown as AntdLabeledValue;
+  expect(DEFAULT_SORT_COMPARATOR(a, b)).toBe(2);
+  expect(DEFAULT_SORT_COMPARATOR(b, a)).toBe(-2);
+});
+
+test('DEFAULT_SORT_COMPARATOR uses rankedSearchCompare when search is 
provided', () => {
+  const a = { value: 'abc', label: 'abc' } as AntdLabeledValue;
+  const b = { value: 'bc', label: 'bc' } as AntdLabeledValue;
+  // 'bc' is an exact match to search 'bc', so it should sort first (lower 
index = negative diff)
+  expect(DEFAULT_SORT_COMPARATOR(a, b, 'bc')).toBeGreaterThan(0);
+});
diff --git 
a/superset-frontend/packages/superset-ui-core/src/components/Table/utils/InteractiveTableUtils.test.ts
 
b/superset-frontend/packages/superset-ui-core/src/components/Table/utils/InteractiveTableUtils.test.ts
new file mode 100644
index 0000000000..827a87a600
--- /dev/null
+++ 
b/superset-frontend/packages/superset-ui-core/src/components/Table/utils/InteractiveTableUtils.test.ts
@@ -0,0 +1,574 @@
+/**
+ * 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 { SUPERSET_TABLE_COLUMN } from '..';
+import InteractiveTableUtils from './InteractiveTableUtils';
+
+const mockColumns = [
+  { key: 'name', dataIndex: 'name', title: 'Name' },
+  { key: 'age', dataIndex: 'age', title: 'Age' },
+];
+
+const createMockTable = (numCols = 2): HTMLTableElement => {
+  const table = document.createElement('table');
+  const thead = document.createElement('thead');
+  const tr = document.createElement('tr');
+  for (let i = 0; i < numCols; i += 1) {
+    const th = document.createElement('th');
+    tr.appendChild(th);
+  }
+  thead.appendChild(tr);
+  table.appendChild(thead);
+  document.body.appendChild(table);
+  return table;
+};
+
+afterEach(() => {
+  document.body.innerHTML = '';
+});
+
+test('constructor initializes with correct defaults', () => {
+  const table = createMockTable();
+  const setDerivedColumns = jest.fn();
+  const utils = new InteractiveTableUtils(
+    table,
+    mockColumns,
+    setDerivedColumns,
+  );
+
+  expect(utils.tableRef).toBe(table);
+  expect(utils.isDragging).toBe(false);
+  expect(utils.resizable).toBe(false);
+  expect(utils.reorderable).toBe(false);
+  expect(utils.derivedColumns).toEqual(mockColumns);
+  expect(utils.RESIZE_INDICATOR_THRESHOLD).toBe(8);
+});
+
+test('setTableRef updates tableRef', () => {
+  const table = createMockTable();
+  const utils = new InteractiveTableUtils(table, mockColumns, jest.fn());
+  const newTable = createMockTable();
+  utils.setTableRef(newTable);
+  expect(utils.tableRef).toBe(newTable);
+});
+
+test('getColumnIndex returns -1 when columnRef has no parent', () => {
+  const table = createMockTable();
+  const utils = new InteractiveTableUtils(table, mockColumns, jest.fn());
+  utils.columnRef = null;
+  expect(utils.getColumnIndex()).toBe(-1);
+});
+
+test('getColumnIndex returns correct index when columnRef is in a row', () => {
+  const table = createMockTable(3);
+  const utils = new InteractiveTableUtils(table, mockColumns, jest.fn());
+  const row = table.rows[0];
+  utils.columnRef = row.cells[1] as unknown as typeof utils.columnRef;
+  expect(utils.getColumnIndex()).toBe(1);
+});
+
+test('allowDrop calls preventDefault on the event', () => {
+  const table = createMockTable();
+  const utils = new InteractiveTableUtils(table, mockColumns, jest.fn());
+  const event = { preventDefault: jest.fn() } as unknown as DragEvent;
+  utils.allowDrop(event);
+  expect(event.preventDefault).toHaveBeenCalledTimes(1);
+});
+
+test('handleMouseup clears mouseDown and resets dragging state', () => {
+  const table = createMockTable();
+  const utils = new InteractiveTableUtils(table, mockColumns, jest.fn());
+  const th = document.createElement('th') as unknown as typeof utils.columnRef;
+  utils.columnRef = th;
+  (th as any).mouseDown = true;
+  utils.isDragging = true;
+
+  utils.handleMouseup();
+
+  expect((th as any).mouseDown).toBe(false);
+  expect(utils.isDragging).toBe(false);
+});
+
+test('handleMouseup works when columnRef is null', () => {
+  const table = createMockTable();
+  const utils = new InteractiveTableUtils(table, mockColumns, jest.fn());
+  utils.columnRef = null;
+  utils.isDragging = true;
+
+  utils.handleMouseup();
+
+  expect(utils.isDragging).toBe(false);
+});
+
+test('handleMouseDown sets mouseDown and oldX when within resize range', () => 
{
+  const table = createMockTable();
+  const utils = new InteractiveTableUtils(table, mockColumns, jest.fn());
+  const target = document.createElement('th') as any;
+  Object.defineProperty(target, 'offsetWidth', {
+    value: 100,
+    configurable: true,
+  });
+
+  const event = {
+    currentTarget: target,
+    offsetX: 95, // 100 - 95 = 5, within threshold of 8
+    x: 95,
+  } as unknown as MouseEvent;
+
+  utils.handleMouseDown(event);
+
+  expect(target.mouseDown).toBe(true);
+  expect(target.oldX).toBe(95);
+  expect(target.oldWidth).toBe(100);
+  expect(target.draggable).toBe(false);
+});
+
+test('handleMouseDown sets draggable when outside resize range and 
reorderable', () => {
+  const table = createMockTable();
+  const utils = new InteractiveTableUtils(table, mockColumns, jest.fn());
+  utils.reorderable = true;
+
+  const target = document.createElement('th') as any;
+  Object.defineProperty(target, 'offsetWidth', {
+    value: 100,
+    configurable: true,
+  });
+
+  const event = {
+    currentTarget: target,
+    offsetX: 50, // 100 - 50 = 50, outside threshold of 8
+    x: 50,
+  } as unknown as MouseEvent;
+
+  utils.handleMouseDown(event);
+
+  expect(target.draggable).toBe(true);
+});
+
+test('initializeResizableColumns adds event listeners when resizable is true', 
() => {
+  const table = createMockTable(2);
+  const utils = new InteractiveTableUtils(table, mockColumns, jest.fn());
+  const cell = table.rows[0].cells[0];
+  const addEventSpy = jest.spyOn(cell, 'addEventListener');
+
+  utils.initializeResizableColumns(true, table);
+
+  expect(utils.resizable).toBe(true);
+  expect(addEventSpy).toHaveBeenCalledWith('mousedown', utils.handleMouseDown);
+  expect(addEventSpy).toHaveBeenCalledWith(
+    'mousemove',
+    utils.handleMouseMove,
+    true,
+  );
+});
+
+test('initializeResizableColumns removes event listeners when resizable is 
false', () => {
+  const table = createMockTable(2);
+  const utils = new InteractiveTableUtils(table, mockColumns, jest.fn());
+  const cell = table.rows[0].cells[0];
+  const removeEventSpy = jest.spyOn(cell, 'removeEventListener');
+
+  utils.initializeResizableColumns(false, table);
+
+  expect(utils.resizable).toBe(false);
+  expect(removeEventSpy).toHaveBeenCalledWith(
+    'mousedown',
+    utils.handleMouseDown,
+  );
+  expect(removeEventSpy).toHaveBeenCalledWith(
+    'mousemove',
+    utils.handleMouseMove,
+    true,
+  );
+});
+
+test('initializeDragDropColumns adds event listeners when reorderable is 
true', () => {
+  const table = createMockTable(2);
+  const utils = new InteractiveTableUtils(table, mockColumns, jest.fn());
+  const cell = table.rows[0].cells[0];
+  const addEventSpy = jest.spyOn(cell, 'addEventListener');
+
+  utils.initializeDragDropColumns(true, table);
+
+  expect(utils.reorderable).toBe(true);
+  expect(addEventSpy).toHaveBeenCalledWith(
+    'dragstart',
+    utils.handleColumnDragStart,
+  );
+  expect(addEventSpy).toHaveBeenCalledWith('drop', utils.handleDragDrop);
+});
+
+test('initializeDragDropColumns removes event listeners when reorderable is 
false', () => {
+  const table = createMockTable(2);
+  const utils = new InteractiveTableUtils(table, mockColumns, jest.fn());
+  const cell = table.rows[0].cells[0];
+  const removeEventSpy = jest.spyOn(cell, 'removeEventListener');
+
+  utils.initializeDragDropColumns(false, table);
+
+  expect(utils.reorderable).toBe(false);
+  expect(removeEventSpy).toHaveBeenCalledWith(
+    'dragstart',
+    utils.handleColumnDragStart,
+  );
+  expect(removeEventSpy).toHaveBeenCalledWith('drop', utils.handleDragDrop);
+});
+
+test('handleColumnDragStart sets isDragging and calls setData', () => {
+  const table = createMockTable(2);
+  const utils = new InteractiveTableUtils(table, mockColumns, jest.fn());
+
+  const row = table.rows[0];
+  const target = row.cells[0] as any;
+  const setDataMock = jest.fn();
+  const event = {
+    currentTarget: target,
+    dataTransfer: { setData: setDataMock },
+  } as unknown as DragEvent;
+
+  utils.handleColumnDragStart(event);
+
+  expect(utils.isDragging).toBe(true);
+  expect(setDataMock).toHaveBeenCalledWith(
+    SUPERSET_TABLE_COLUMN,
+    expect.any(String),
+  );
+});
+
+test('handleDragDrop reorders columns when valid drag data exists', () => {
+  const table = createMockTable(2);
+  const setDerivedColumns = jest.fn();
+  const utils = new InteractiveTableUtils(
+    table,
+    mockColumns,
+    setDerivedColumns,
+  );
+
+  const row = table.rows[0];
+  // Set columnRef to first column (drag source)
+  utils.columnRef = row.cells[0] as unknown as typeof utils.columnRef;
+
+  const dragData = JSON.stringify({ index: 0, columnData: mockColumns[0] });
+  const dropTarget = row.cells[1];
+  const event = {
+    currentTarget: dropTarget,
+    dataTransfer: { getData: jest.fn().mockReturnValue(dragData) },
+    preventDefault: jest.fn(),
+  } as unknown as DragEvent;
+
+  utils.handleDragDrop(event);
+
+  expect(event.preventDefault).toHaveBeenCalledTimes(1);
+  expect(setDerivedColumns).toHaveBeenCalledTimes(1);
+});
+
+test('handleDragDrop does nothing when no drag data', () => {
+  const table = createMockTable(2);
+  const setDerivedColumns = jest.fn();
+  const utils = new InteractiveTableUtils(
+    table,
+    mockColumns,
+    setDerivedColumns,
+  );
+
+  const row = table.rows[0];
+  const event = {
+    currentTarget: row.cells[0],
+    dataTransfer: { getData: jest.fn().mockReturnValue('') },
+    preventDefault: jest.fn(),
+  } as unknown as DragEvent;
+
+  utils.handleDragDrop(event);
+
+  expect(event.preventDefault).not.toHaveBeenCalled();
+  expect(setDerivedColumns).not.toHaveBeenCalled();
+});
+
+test('handleMouseMove updates cursor to col-resize when within resize range', 
() => {
+  const table = createMockTable(2);
+  const utils = new InteractiveTableUtils(table, mockColumns, jest.fn());
+  utils.resizable = true;
+
+  const target = document.createElement('th') as any;
+  Object.defineProperty(target, 'offsetWidth', {
+    value: 100,
+    configurable: true,
+  });
+  target.style = { cursor: '' };
+
+  const event = {
+    currentTarget: target,
+    offsetX: 95,
+    x: 0,
+  } as unknown as MouseEvent;
+
+  utils.handleMouseMove(event);
+
+  expect(target.style.cursor).toBe('col-resize');
+});
+
+test('handleMouseMove sets default cursor when outside resize range', () => {
+  const table = createMockTable(2);
+  const utils = new InteractiveTableUtils(table, mockColumns, jest.fn());
+  utils.resizable = true;
+
+  const target = document.createElement('th') as any;
+  Object.defineProperty(target, 'offsetWidth', {
+    value: 100,
+    configurable: true,
+  });
+  target.style = { cursor: '' };
+
+  const event = {
+    currentTarget: target,
+    offsetX: 50,
+    x: 0,
+  } as unknown as MouseEvent;
+
+  utils.handleMouseMove(event);
+
+  expect(target.style.cursor).toBe('default');
+});
+
+test('handleMouseMove resizes column when mouseDown and within bounds', () => {
+  const table = createMockTable(2);
+  const setDerivedColumns = jest.fn();
+  const utils = new InteractiveTableUtils(
+    table,
+    mockColumns,
+    setDerivedColumns,
+  );
+  utils.resizable = true;
+
+  const row = table.rows[0];
+  const col = row.cells[0] as any;
+  col.mouseDown = true;
+  col.oldWidth = 100;
+  col.oldX = 50;
+  utils.columnRef = col;
+
+  const target = document.createElement('th') as any;
+  Object.defineProperty(target, 'offsetWidth', {
+    value: 100,
+    configurable: true,
+  });
+  target.style = { cursor: '' };
+
+  const event = {
+    currentTarget: target,
+    offsetX: 50,
+    x: 70, // diff = 70 - 50 = 20, width = 100 + 20 = 120
+  } as unknown as MouseEvent;
+
+  utils.handleMouseMove(event);
+
+  expect(setDerivedColumns).toHaveBeenCalledTimes(1);
+  expect(utils.derivedColumns[0].width).toBe(120);
+});
+
+test('handleMouseMove skips resize when not resizable', () => {
+  const table = createMockTable(2);
+  const setDerivedColumns = jest.fn();
+  const utils = new InteractiveTableUtils(
+    table,
+    mockColumns,
+    setDerivedColumns,
+  );
+  utils.resizable = false;
+
+  const target = document.createElement('th') as any;
+  const event = {
+    currentTarget: target,
+    offsetX: 50,
+    x: 70,
+  } as unknown as MouseEvent;
+
+  utils.handleMouseMove(event);
+
+  expect(setDerivedColumns).not.toHaveBeenCalled();
+});
+
+test('handleMouseMove handles negative diff by keeping original width', () => {
+  const table = createMockTable(2);
+  const setDerivedColumns = jest.fn();
+  const utils = new InteractiveTableUtils(
+    table,
+    mockColumns,
+    setDerivedColumns,
+  );
+  utils.resizable = true;
+
+  const row = table.rows[0];
+  const col = row.cells[0] as any;
+  col.mouseDown = true;
+  col.oldWidth = 50;
+  col.oldX = 200;
+  utils.columnRef = col;
+
+  const target = document.createElement('th') as any;
+  Object.defineProperty(target, 'offsetWidth', {
+    value: 50,
+    configurable: true,
+  });
+  target.style = { cursor: '' };
+
+  const event = {
+    currentTarget: target,
+    offsetX: 45,
+    x: 0, // diff = 0 - 200 = -200, width would be 50 + (-200) = -150 < 0 → 
keep 50
+  } as unknown as MouseEvent;
+
+  utils.handleMouseMove(event);
+
+  expect(setDerivedColumns).toHaveBeenCalledTimes(1);
+  expect(utils.derivedColumns[0].width).toBe(50); // unchanged because 
negative would result
+});
+
+test('handleColumnDragStart does not set columnRef when currentTarget is null 
(line 82 false)', () => {
+  const table = createMockTable(2);
+  const utils = new InteractiveTableUtils(table, mockColumns, jest.fn());
+
+  const event = {
+    currentTarget: null,
+    dataTransfer: { setData: jest.fn() },
+  } as unknown as DragEvent;
+
+  utils.handleColumnDragStart(event);
+
+  expect(utils.isDragging).toBe(true);
+  expect(utils.columnRef).toBeFalsy();
+});
+
+test('handleMouseDown does nothing when currentTarget is null (line 118 
false)', () => {
+  const table = createMockTable();
+  const utils = new InteractiveTableUtils(table, mockColumns, jest.fn());
+
+  const event = {
+    currentTarget: null,
+    offsetX: 50,
+    x: 50,
+  } as unknown as MouseEvent;
+
+  utils.handleMouseDown(event);
+
+  expect(utils.columnRef).toBeFalsy();
+});
+
+test('handleMouseDown does nothing to draggable when outside resize range and 
not reorderable (line 132 false)', () => {
+  const table = createMockTable();
+  const utils = new InteractiveTableUtils(table, mockColumns, jest.fn());
+  utils.reorderable = false;
+
+  const target = document.createElement('th') as any;
+  Object.defineProperty(target, 'offsetWidth', {
+    value: 100,
+    configurable: true,
+  });
+
+  const event = {
+    currentTarget: target,
+    offsetX: 50, // 100 - 50 = 50, outside threshold of 8
+    x: 50,
+  } as unknown as MouseEvent;
+
+  utils.handleMouseDown(event);
+
+  expect(target.draggable).toBe(false);
+});
+
+test('handleMouseMove skips column update when getColumnIndex returns NaN 
(line 162 false)', () => {
+  const table = createMockTable(2);
+  const setDerivedColumns = jest.fn();
+  const utils = new InteractiveTableUtils(
+    table,
+    mockColumns,
+    setDerivedColumns,
+  );
+  utils.resizable = true;
+
+  const row = table.rows[0];
+  const col = row.cells[0] as any;
+  col.mouseDown = true;
+  col.oldWidth = 100;
+  col.oldX = 50;
+  utils.columnRef = col;
+
+  jest.spyOn(utils, 'getColumnIndex').mockReturnValueOnce(NaN);
+
+  const target = document.createElement('th') as any;
+  Object.defineProperty(target, 'offsetWidth', {
+    value: 100,
+    configurable: true,
+  });
+  target.style = { cursor: '' };
+
+  const event = {
+    currentTarget: target,
+    offsetX: 50,
+    x: 70,
+  } as unknown as MouseEvent;
+
+  utils.handleMouseMove(event);
+
+  expect(setDerivedColumns).not.toHaveBeenCalled();
+});
+
+test('initializeResizableColumns does nothing when table is null (lines 
182-187 false)', () => {
+  const table = createMockTable();
+  const utils = new InteractiveTableUtils(table, mockColumns, jest.fn());
+
+  expect(() => utils.initializeResizableColumns(true, null)).not.toThrow();
+  expect(utils.tableRef).toBeNull();
+});
+
+test('initializeResizableColumns uses default resizable=false when first arg 
is undefined (line 182 default branch)', () => {
+  const table = createMockTable(2);
+  const utils = new InteractiveTableUtils(table, mockColumns, jest.fn());
+
+  utils.initializeResizableColumns(undefined, table);
+
+  expect(utils.resizable).toBe(false);
+});
+
+test('initializeDragDropColumns does nothing when table is null (lines 206-211 
false)', () => {
+  const table = createMockTable();
+  const utils = new InteractiveTableUtils(table, mockColumns, jest.fn());
+
+  expect(() => utils.initializeDragDropColumns(true, null)).not.toThrow();
+  expect(utils.tableRef).toBeNull();
+});
+
+test('initializeDragDropColumns uses default reorderable=false when first arg 
is undefined (line 206 default branch)', () => {
+  const table = createMockTable(2);
+  const utils = new InteractiveTableUtils(table, mockColumns, jest.fn());
+
+  utils.initializeDragDropColumns(undefined, table);
+
+  expect(utils.reorderable).toBe(false);
+});
+
+test('clearListeners removes document mouseup listener', () => {
+  const table = createMockTable();
+  const utils = new InteractiveTableUtils(table, mockColumns, jest.fn());
+  const removeEventSpy = jest.spyOn(document, 'removeEventListener');
+
+  utils.clearListeners();
+
+  expect(removeEventSpy).toHaveBeenCalledWith('mouseup', utils.handleMouseup);
+});
diff --git 
a/superset-frontend/packages/superset-ui-core/src/types/react-syntax-highlighter.d.ts
 
b/superset-frontend/packages/superset-ui-core/src/types/react-syntax-highlighter.d.ts
index f0860387dd..ad0705a20b 100644
--- 
a/superset-frontend/packages/superset-ui-core/src/types/react-syntax-highlighter.d.ts
+++ 
b/superset-frontend/packages/superset-ui-core/src/types/react-syntax-highlighter.d.ts
@@ -25,10 +25,3 @@ declare module 
'react-syntax-highlighter/dist/cjs/styles/hljs/github' {
   const style: any;
   export default style;
 }
-
-type SupportedLanguages = 'markdown' | 'htmlbars' | 'sql' | 'json';
-
-// For type checking when importing languages
-function importLanguage<T extends SupportedLanguages>(language: T) {
-  return 
import(`react-syntax-highlighter/dist/cjs/languages/hljs/${language}`);
-}
diff --git 
a/superset-frontend/packages/superset-ui-core/src/utils/rankedSearchCompare.test.ts
 
b/superset-frontend/packages/superset-ui-core/src/utils/rankedSearchCompare.test.ts
index 268511a5cb..a72f3e2502 100644
--- 
a/superset-frontend/packages/superset-ui-core/src/utils/rankedSearchCompare.test.ts
+++ 
b/superset-frontend/packages/superset-ui-core/src/utils/rankedSearchCompare.test.ts
@@ -46,3 +46,23 @@ test('Sort starts with first', async () => {
 test('Sort same case first', async () => {
   expect(['%f %B', '%F %b'].sort(searchSort('%F'))).toEqual(['%F %b', '%f 
%B']);
 });
+
+test('returns localeCompare result when no search term provided', () => {
+  expect(rankedSearchCompare('banana', 'apple', '')).toBeGreaterThan(0);
+  expect(rankedSearchCompare('apple', 'banana', '')).toBeLessThan(0);
+});
+
+test('handles empty string a', () => {
+  const result = rankedSearchCompare('', 'hello', 'hello');
+  expect(typeof result).toBe('number');
+});
+
+test('handles empty string b', () => {
+  const result = rankedSearchCompare('hello', '', 'hello');
+  expect(typeof result).toBe('number');
+});
+
+test('falls back to localeCompare when strings have no match relationship to 
search', () => {
+  expect(rankedSearchCompare('abc', 'def', 'xyz')).toBeLessThan(0);
+  expect(rankedSearchCompare('def', 'abc', 'xyz')).toBeGreaterThan(0);
+});
diff --git 
a/superset-frontend/packages/superset-ui-core/src/components/List/List.test.tsx 
b/superset-frontend/packages/superset-ui-core/src/utils/withLabel.test.ts
similarity index 52%
copy from 
superset-frontend/packages/superset-ui-core/src/components/List/List.test.tsx
copy to superset-frontend/packages/superset-ui-core/src/utils/withLabel.test.ts
index 2423bc3a00..67e51eb2c9 100644
--- 
a/superset-frontend/packages/superset-ui-core/src/components/List/List.test.tsx
+++ b/superset-frontend/packages/superset-ui-core/src/utils/withLabel.test.ts
@@ -16,27 +16,24 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import { render, screen } from '@superset-ui/core/spec';
-import { List } from '.';
-import type { ListProps } from './types';
 
-const mockedProps: ListProps<any> = {
-  dataSource: ['Item 1', 'Item 2', 'Item 3'],
-  renderItem: item => <div>{item}</div>,
-};
+import withLabel from './withLabel';
 
-test('should render', () => {
-  const { container } = render(<List {...mockedProps} />);
-  expect(container).toBeInTheDocument();
+test('withLabel returns false when validator passes', () => {
+  const validator = () => false as false;
+  const labeled = withLabel(validator, 'Field');
+  expect(labeled('any value')).toBe(false);
 });
 
-test('should render the correct number of items', () => {
-  render(<List {...mockedProps} />);
-
-  const listItemElements = screen.getAllByText(/Item \d/);
+test('withLabel prepends label to validator error message', () => {
+  const validator = () => 'is required';
+  const labeled = withLabel(validator, 'Name');
+  expect(labeled('')).toBe('Name is required');
+});
 
-  expect(listItemElements.length).toBe(3);
-  listItemElements.forEach((item, index) => {
-    expect(item).toHaveTextContent(`Item ${index + 1}`);
-  });
+test('withLabel passes value and state to underlying validator', () => {
+  const validator = jest.fn(() => false as false);
+  const labeled = withLabel(validator, 'Field');
+  labeled('value', { someState: true });
+  expect(validator).toHaveBeenCalledWith('value', { someState: true });
 });
diff --git 
a/superset-frontend/packages/superset-ui-core/test/connection/SupersetClient.test.ts
 
b/superset-frontend/packages/superset-ui-core/test/connection/SupersetClient.test.ts
index 92efac6089..cdfe2dacd9 100644
--- 
a/superset-frontend/packages/superset-ui-core/test/connection/SupersetClient.test.ts
+++ 
b/superset-frontend/packages/superset-ui-core/test/connection/SupersetClient.test.ts
@@ -144,4 +144,10 @@ describe('SupersetClient', () => {
 
     fetchMock.clearHistory().removeRoutes();
   });
+
+  test('getCSRFToken() returns existing token when already configured', async 
() => {
+    SupersetClient.configure({ csrfToken: 'my_token' });
+    const token = await SupersetClient.getCSRFToken();
+    expect(token).toBe('my_token');
+  });
 });
diff --git 
a/superset-frontend/packages/superset-ui-core/test/connection/SupersetClientClass.test.ts
 
b/superset-frontend/packages/superset-ui-core/test/connection/SupersetClientClass.test.ts
index e5020b2081..bc9448be4e 100644
--- 
a/superset-frontend/packages/superset-ui-core/test/connection/SupersetClientClass.test.ts
+++ 
b/superset-frontend/packages/superset-ui-core/test/connection/SupersetClientClass.test.ts
@@ -108,6 +108,20 @@ describe('SupersetClientClass', () => {
       expect(fetchMock.callHistory.calls(LOGIN_GLOB)).toHaveLength(0);
     });
 
+    test('getCSRFToken() returns existing csrfToken without fetching when 
already set', async () => {
+      const client = new SupersetClientClass({ csrfToken: 'existing_token' });
+      const token = await client.getCSRFToken();
+      expect(token).toBe('existing_token');
+      expect(fetchMock.callHistory.calls(LOGIN_GLOB)).toHaveLength(0);
+    });
+
+    test('getCSRFToken() calls fetchCSRFToken when csrfToken is not set (line 
261 || branch)', async () => {
+      const client = new SupersetClientClass({});
+      const token = await client.getCSRFToken();
+      expect(fetchMock.callHistory.calls(LOGIN_GLOB)).toHaveLength(1);
+      expect(token).toBe(1234);
+    });
+
     test('calls api/v1/security/csrf_token/ when init(force=true) is called 
even if a CSRF token is passed', async () => {
       expect.assertions(4);
       const initialToken = 'initial_token';
@@ -156,6 +170,25 @@ describe('SupersetClientClass', () => {
       }
     });
 
+    test('does not set csrfToken when json response is a non-object primitive 
(line 245 false branch)', async () => {
+      expect.assertions(1);
+      fetchMock.removeRoute(LOGIN_GLOB);
+      // String '123' is used as raw body text; response.json() parses it to 
the
+      // number 123, so typeof json === 'object' is false
+      fetchMock.get(LOGIN_GLOB, '123', { name: LOGIN_GLOB });
+
+      let error;
+      try {
+        await new SupersetClientClass({}).init();
+      } catch (err) {
+        error = err;
+      } finally {
+        expect(error as typeof invalidCsrfTokenError).toEqual(
+          invalidCsrfTokenError,
+        );
+      }
+    });
+
     test('does not set csrfToken if response is not json', async () => {
       expect.assertions(1);
       fetchMock.removeRoute(LOGIN_GLOB);
diff --git 
a/superset-frontend/packages/superset-ui-core/test/currency-format/CurrencyFormatter.test.ts
 
b/superset-frontend/packages/superset-ui-core/test/currency-format/CurrencyFormatter.test.ts
index 251ecdded0..1b27d0d0d7 100644
--- 
a/superset-frontend/packages/superset-ui-core/test/currency-format/CurrencyFormatter.test.ts
+++ 
b/superset-frontend/packages/superset-ui-core/test/currency-format/CurrencyFormatter.test.ts
@@ -187,3 +187,81 @@ test('CurrencyFormatter gracefully handles invalid 
currency code', () => {
   // Should not throw, should return formatted value without currency symbol
   expect(formatter.format(1000)).toBe('1,000.00');
 });
+
+test('CurrencyFormatter AUTO mode uses suffix position from row context', () 
=> {
+  const formatter = new CurrencyFormatter({
+    currency: { symbol: 'AUTO', symbolPosition: 'suffix' },
+    d3Format: ',.2f',
+  });
+
+  const row = { currency: 'EUR' };
+  const result = formatter.format(1000, row, 'currency');
+  expect(result).toContain('€');
+  expect(result).toMatch(/1,000\.00.*€/);
+});
+
+test('CurrencyFormatter AUTO mode uses default suffix when symbolPosition is 
unknown', () => {
+  const formatter = new CurrencyFormatter({
+    // @ts-expect-error
+    currency: { symbol: 'AUTO' },
+    d3Format: ',.2f',
+  });
+
+  const row = { currency: 'EUR' };
+  const result = formatter.format(1000, row, 'currency');
+  expect(result).toContain('€');
+  expect(result).toMatch(/1,000\.00.*€/);
+});
+
+test('CurrencyFormatter AUTO mode returns plain value when row currency is not 
a string (line 52)', () => {
+  const formatter = new CurrencyFormatter({
+    currency: { symbol: 'AUTO', symbolPosition: 'prefix' },
+    d3Format: ',.2f',
+  });
+
+  // Passing a numeric currency value causes normalizeCurrency to hit
+  // `typeof value !== 'string'` → return null, so no symbol is appended
+  const row = { currency: 123 };
+  expect(formatter.format(1000, row as any, 'currency')).toBe('1,000.00');
+});
+
+test('CurrencyFormatter AUTO mode returns plain value when getCurrencySymbol 
returns undefined (line 126 false branch)', () => {
+  const formatter = new CurrencyFormatter({
+    currency: { symbol: 'AUTO', symbolPosition: 'prefix' },
+    d3Format: ',.2f',
+  });
+
+  const OrigNumberFormat = Intl.NumberFormat;
+  // Return formatToParts without a 'currency' entry so getCurrencySymbol → 
undefined
+  Intl.NumberFormat = jest.fn().mockImplementation(() => ({
+    formatToParts: () => [{ type: 'integer', value: '1' }],
+  })) as unknown as typeof Intl.NumberFormat;
+
+  const row = { currency: 'EUR' };
+  const result = formatter.format(1000, row, 'currency');
+
+  Intl.NumberFormat = OrigNumberFormat;
+
+  expect(result).toBe('1,000.00');
+});
+
+test('CurrencyFormatter AUTO mode falls back to plain value when 
getCurrencySymbol throws', () => {
+  const formatter = new CurrencyFormatter({
+    currency: { symbol: 'AUTO', symbolPosition: 'prefix' },
+    d3Format: ',.2f',
+  });
+
+  // Mock Intl.NumberFormat to throw to simulate an environment where the
+  // currency code is rejected, triggering the catch block in format()
+  const OrigNumberFormat = Intl.NumberFormat;
+  Intl.NumberFormat = jest.fn().mockImplementation(() => {
+    throw new RangeError('Invalid currency code');
+  }) as unknown as typeof Intl.NumberFormat;
+
+  const row = { currency: 'ZZZ' };
+  const result = formatter.format(1000, row, 'currency');
+
+  Intl.NumberFormat = OrigNumberFormat;
+
+  expect(result).toBe('1,000.00');
+});
diff --git 
a/superset-frontend/packages/superset-ui-core/test/currency-format/utils.test.ts
 
b/superset-frontend/packages/superset-ui-core/test/currency-format/utils.test.ts
index ef8f0ee3d1..facf718380 100644
--- 
a/superset-frontend/packages/superset-ui-core/test/currency-format/utils.test.ts
+++ 
b/superset-frontend/packages/superset-ui-core/test/currency-format/utils.test.ts
@@ -27,6 +27,10 @@ import {
   NumberFormatter,
   ValueFormatter,
 } from '@superset-ui/core';
+import {
+  analyzeCurrencyInData,
+  resolveAutoCurrency,
+} from '../../src/currency-format/utils';
 
 test('buildCustomFormatters without saved metrics returns empty object', () => 
{
   expect(
@@ -219,3 +223,192 @@ test('getValueFormatter return NumberFormatter when no 
currency formatters', ()
   );
   expect(formatter).toBeInstanceOf(NumberFormatter);
 });
+
+test('analyzeCurrencyInData returns null when all currency values are 
null/undefined', () => {
+  const data = [
+    { value: 100, currency: null },
+    { value: 200, currency: undefined },
+  ];
+  expect(analyzeCurrencyInData(data as any, 'currency')).toBeNull();
+});
+
+test('analyzeCurrencyInData returns null when currencyColumn is not provided', 
() => {
+  expect(analyzeCurrencyInData([{ value: 100 }], undefined)).toBeNull();
+});
+
+test('analyzeCurrencyInData returns detected currency for consistent values', 
() => {
+  const data = [
+    { value: 100, currency: 'USD' },
+    { value: 200, currency: 'USD' },
+  ];
+  expect(analyzeCurrencyInData(data, 'currency')).toBe('USD');
+});
+
+test('resolveAutoCurrency returns currencyFormat unchanged when not AUTO', () 
=> {
+  const currency: Currency = { symbol: 'USD', symbolPosition: 'prefix' };
+  expect(resolveAutoCurrency(currency, null)).toEqual(currency);
+});
+
+test('resolveAutoCurrency returns currency from backendDetected when AUTO', () 
=> {
+  const currency: Currency = { symbol: 'AUTO', symbolPosition: 'prefix' };
+  const result = resolveAutoCurrency(currency, 'EUR');
+  expect(result).toEqual({ symbol: 'EUR', symbolPosition: 'prefix' });
+});
+
+test('resolveAutoCurrency returns null when AUTO and no detection source', () 
=> {
+  const currency: Currency = { symbol: 'AUTO', symbolPosition: 'prefix' };
+  expect(resolveAutoCurrency(currency, null)).toBeNull();
+});
+
+test('resolveAutoCurrency detects currency from data when backendDetected is 
undefined', () => {
+  const currency: Currency = { symbol: 'AUTO', symbolPosition: 'suffix' };
+  const data = [
+    { value: 100, cur: 'JPY' },
+    { value: 200, cur: 'JPY' },
+  ];
+  const result = resolveAutoCurrency(currency, undefined, data, 'cur');
+  expect(result).toEqual({ symbol: 'JPY', symbolPosition: 'suffix' });
+});
+
+test('resolveAutoCurrency returns null when data analysis finds mixed 
currencies', () => {
+  const currency: Currency = { symbol: 'AUTO', symbolPosition: 'prefix' };
+  const data = [{ cur: 'USD' }, { cur: 'EUR' }];
+  const result = resolveAutoCurrency(currency, undefined, data, 'cur');
+  expect(result).toBeNull();
+});
+
+test('buildCustomFormatters with AUTO currency and data resolves currency', () 
=> {
+  const data = [{ metric: 1, currency: 'EUR' }];
+  const result = buildCustomFormatters(
+    ['metric'],
+    {},
+    {},
+    ',.2f',
+    { symbol: 'AUTO', symbolPosition: 'prefix' },
+    data,
+    'currency',
+  ) as Record<string, ValueFormatter>;
+  expect(result).toHaveProperty('metric');
+  expect(result.metric).toBeInstanceOf(CurrencyFormatter);
+});
+
+test('buildCustomFormatters with AUTO currency and no detected currency 
returns NumberFormatter', () => {
+  // Mixed currencies → null resolved format → NumberFormatter
+  const data = [
+    { metric: 1, currency: 'USD' },
+    { metric: 2, currency: 'EUR' },
+  ];
+  const result = buildCustomFormatters(
+    ['metric'],
+    {},
+    {},
+    ',.2f',
+    { symbol: 'AUTO', symbolPosition: 'prefix' },
+    data,
+    'currency',
+  ) as Record<string, ValueFormatter>;
+  expect(result).toHaveProperty('metric');
+  expect(result.metric).toBeInstanceOf(NumberFormatter);
+});
+
+test('getValueFormatter with AUTO currency and detectedCurrency provided', () 
=> {
+  const formatter = getValueFormatter(
+    ['count'],
+    {},
+    {},
+    ',.1f',
+    { symbol: 'AUTO', symbolPosition: 'prefix' },
+    'count',
+    undefined,
+    undefined,
+    'USD',
+  );
+  expect(formatter).toBeInstanceOf(CurrencyFormatter);
+});
+
+test('getValueFormatter with AUTO currency and null detectedCurrency returns 
NumberFormatter', () => {
+  const formatter = getValueFormatter(
+    ['count'],
+    {},
+    {},
+    ',.1f',
+    { symbol: 'AUTO', symbolPosition: 'prefix' },
+    'count',
+    undefined,
+    undefined,
+    null,
+  );
+  expect(formatter).toBeInstanceOf(NumberFormatter);
+});
+
+test('getValueFormatter with AUTO currency and data + currencyCodeColumn', () 
=> {
+  const data = [
+    { count: 100, currency: 'GBP' },
+    { count: 200, currency: 'GBP' },
+  ];
+  const formatter = getValueFormatter(
+    ['count'],
+    {},
+    {},
+    ',.1f',
+    { symbol: 'AUTO', symbolPosition: 'suffix' },
+    'count',
+    data,
+    'currency',
+  );
+  expect(formatter).toBeInstanceOf(CurrencyFormatter);
+});
+
+test('getValueFormatter with AUTO currency, data+column but mixed currencies 
falls back to NumberFormatter (line 178 false branch)', () => {
+  // Mixed currencies → analyzeCurrencyInData returns null → frontendDetected 
falsy
+  // → resolvedCurrencyFormat = null (the ternary false branch at line 178)
+  const data = [
+    { count: 100, currency: 'USD' },
+    { count: 200, currency: 'EUR' },
+  ];
+  const formatter = getValueFormatter(
+    ['count'],
+    {},
+    {},
+    ',.1f',
+    { symbol: 'AUTO', symbolPosition: 'prefix' },
+    'count',
+    data,
+    'currency',
+  );
+  expect(formatter).toBeInstanceOf(NumberFormatter);
+});
+
+test('getValueFormatter with AUTO currency and no data falls back to 
NumberFormatter', () => {
+  const formatter = getValueFormatter(
+    ['count'],
+    {},
+    {},
+    ',.1f',
+    { symbol: 'AUTO', symbolPosition: 'prefix' },
+    'count',
+  );
+  expect(formatter).toBeInstanceOf(NumberFormatter);
+});
+
+test('getValueFormatter returns NumberFormatter via line 205 when AUTO 
resolves to null and metrics are all adhoc', () => {
+  // String metrics produce a NumberFormatter entry in buildCustomFormatters,
+  // making customFormatter truthy and bypassing line 205. Adhoc metric objects
+  // are skipped by buildCustomFormatters, so customFormatter stays undefined,
+  // and the resolvedCurrencyFormat === null branch at line 205 is reached.
+  const adhocMetric = {
+    expressionType: 'SIMPLE' as const,
+    aggregate: 'COUNT' as const,
+    column: { column_name: 'test' },
+  };
+  const formatter = getValueFormatter(
+    [adhocMetric],
+    {},
+    {},
+    ',.1f',
+    { symbol: 'AUTO', symbolPosition: 'prefix' },
+    'some_key',
+    undefined, // no data → else branch → resolvedCurrencyFormat = null
+  );
+  expect(formatter).toBeInstanceOf(NumberFormatter);
+});
diff --git 
a/superset-frontend/packages/superset-ui-core/test/query/types/Column.test.ts 
b/superset-frontend/packages/superset-ui-core/test/query/types/Column.test.ts
index d4391cfd01..e940802197 100644
--- 
a/superset-frontend/packages/superset-ui-core/test/query/types/Column.test.ts
+++ 
b/superset-frontend/packages/superset-ui-core/test/query/types/Column.test.ts
@@ -18,6 +18,7 @@
  */
 import {
   isAdhocColumn,
+  isAdhocColumnReference,
   isPhysicalColumn,
   isQueryFormColumn,
 } from '@superset-ui/core';
@@ -61,3 +62,16 @@ test('isQueryFormColumn returns true', () => {
 test('isQueryFormColumn returns false', () => {
   expect(isQueryFormColumn({})).toEqual(false);
 });
+
+test('isAdhocColumnReference returns true for adhoc column with 
isColumnReference', () => {
+  const ref = { ...adhocColumn, isColumnReference: true };
+  expect(isAdhocColumnReference(ref)).toEqual(true);
+});
+
+test('isAdhocColumnReference returns false for non-reference adhoc column', () 
=> {
+  expect(isAdhocColumnReference(adhocColumn)).toEqual(false);
+});
+
+test('isAdhocColumnReference returns false for non-adhoc column', () => {
+  expect(isAdhocColumnReference('gender')).toEqual(false);
+});
diff --git 
a/superset-frontend/packages/superset-ui-core/test/query/types/Dashboard.test.ts
 
b/superset-frontend/packages/superset-ui-core/test/query/types/Dashboard.test.ts
index c1c7143957..b34a417420 100644
--- 
a/superset-frontend/packages/superset-ui-core/test/query/types/Dashboard.test.ts
+++ 
b/superset-frontend/packages/superset-ui-core/test/query/types/Dashboard.test.ts
@@ -28,6 +28,11 @@ import {
   isAppliedNativeFilterType,
   AppliedCrossFilterType,
   AppliedNativeFilterType,
+  isChartCustomization,
+  isChartCustomizationDivider,
+  ChartCustomization,
+  ChartCustomizationDivider,
+  ChartCustomizationType,
 } from '@superset-ui/core';
 
 const filter: Filter = {
@@ -96,3 +101,31 @@ test('applied native filter type guard', () => {
   expect(isAppliedNativeFilterType(appliedNativeFilter)).toBeTruthy();
   expect(isAppliedNativeFilterType(appliedCrossFilter)).toBeFalsy();
 });
+
+const chartCustomization: ChartCustomization = {
+  id: 'custom_id',
+  type: ChartCustomizationType.ChartCustomization,
+  name: 'My Customization',
+  filterType: 'chart_customization',
+  targets: [],
+  scope: { rootPath: [], excluded: [] },
+  defaultDataMask: {},
+  controlValues: {},
+};
+
+const chartCustomizationDivider: ChartCustomizationDivider = {
+  id: 'divider_id',
+  type: ChartCustomizationType.Divider,
+  title: 'Divider',
+  description: 'A divider',
+};
+
+test('isChartCustomization type guard', () => {
+  expect(isChartCustomization(chartCustomization)).toBeTruthy();
+  expect(isChartCustomization(filter)).toBeFalsy();
+});
+
+test('isChartCustomizationDivider type guard', () => {
+  expect(isChartCustomizationDivider(chartCustomizationDivider)).toBeTruthy();
+  expect(isChartCustomizationDivider(chartCustomization)).toBeFalsy();
+});

Reply via email to