Skip to content

Commit 7821f41

Browse files
Refactor: Remove explicit 'any' in dataset.test.tsx
I replaced 'any' type annotations with more specific types in `ui/src/components/dialog/dataset/dataset.test.tsx` to improve type safety and address linting errors. Key changes: - I updated `MockDatasetInfo` to align with `DatasetInfo` by adding the `columns` property. - I correctly typed the `dataset` prop in `CreateDatasetDialog` component calls within tests. - I improved typings for various mocked browser APIs like FileReader, Image, and CanvasRenderingContext2D. - I addressed typings for DND event objects. - I replaced a `ts-ignore` comment with `ts-expect-error` as per linter recommendation. These changes ensure that `pnpm lint` passes without errors in the modified file.
1 parent 6c5a2a4 commit 7821f41

2 files changed

Lines changed: 40 additions & 22 deletions

File tree

ui/src/components/dataset-list-page.test.tsx

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import userEvent from '@testing-library/user-event';
33
import { describe, it, expect, vi, beforeEach, Mock } from 'vitest';
44
import { DatasetListPage } from './dataset-list-page';
55
import * as actions from '@/actions';
6+
import { DatasetInfo, DatasetType } from '@/actions'; // Add this line
67
import { MemoryRouter, useLocation, useNavigate } from 'react-router-dom';
78
import { TestProvider } from '@/test/helpers/test-provider';
89

@@ -16,6 +17,22 @@ vi.mock('react-router-dom', async () => {
1617
};
1718
});
1819

20+
// ... other imports
21+
22+
interface MockCreateDatasetDialogProps {
23+
isOpen: boolean;
24+
onClose: () => void;
25+
onCreate: (payload: {
26+
name: string;
27+
description: string;
28+
type: DatasetType; // Use DatasetType here
29+
files?: File[];
30+
options?: string[];
31+
}) => void;
32+
dataset?: DatasetInfo; // Use DatasetInfo here
33+
}
34+
35+
// ... rest of the file
1936
import * as ActualToastHook from '@/hooks/use-toast';
2037
vi.mock('@/hooks/use-toast', async (importOriginal) => {
2138
const actual = await importOriginal<typeof ActualToastHook>();
@@ -128,7 +145,7 @@ describe('DatasetListPage Search Functionality', () => {
128145
});
129146

130147
vi.mock('@/components/dialog/dataset/dataset', () => ({
131-
CreateDatasetDialog: vi.fn(({ isOpen, onClose, onCreate, dataset }: any) => { // eslint-disable-line @typescript-eslint/no-explicit-any
148+
CreateDatasetDialog: vi.fn(({ isOpen, onClose, onCreate, dataset }: MockCreateDatasetDialogProps) => {
132149
if (!isOpen) return null;
133150
return (
134151
<div data-testid="mock-create-dataset-dialog">

ui/src/components/dialog/dataset/dataset.test.tsx

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { vi, describe, test, expect, beforeEach, Mock, afterEach } from 'vitest'
33
import { ReactNode } from 'react';
44
import { CreateDatasetDialog, CreateDatasetDialogProps } from './dataset';
55
import { DatasetInfo } from '@/actions';
6-
import { DragEndEvent } from '@dnd-kit/core';
6+
import { DragEndEvent, Active, Over, UniqueIdentifier } from '@dnd-kit/core';
77

88
vi.mock('@/actions', () => ({}));
99
vi.mock('@/urls', () => ({
@@ -16,6 +16,7 @@ type MockDatasetInfo = {
1616
description: string;
1717
type: "list" | "csv" | "image";
1818
data: string[];
19+
columns: string[];
1920
};
2021

2122
let dndOnDragEnd: ((event: DragEndEvent) => void) | undefined = undefined;
@@ -90,7 +91,7 @@ describe('CreateDatasetDialog Management', () => {
9091
HTMLCanvasElement.prototype.getContext = vi.fn(() => ({
9192
drawImage: vi.fn(),
9293
toDataURL: vi.fn(() => 'mock-data-url-canvas'),
93-
})) as any;
94+
})) as unknown as () => Partial<CanvasRenderingContext2D> | null;
9495

9596
const MockedFileReader = vi.fn((): FileReader => {
9697
const self = {
@@ -100,27 +101,27 @@ describe('CreateDatasetDialog Management', () => {
100101
result: null as string | ArrayBuffer | null,
101102

102103
// Event handlers
103-
onabort: null as (((this: FileReader, ev: ProgressEvent<FileReader>) => any) | null),
104-
onerror: null as (((this: FileReader, ev: ProgressEvent<FileReader>) => any) | null),
105-
onload: null as (((this: FileReader, ev: ProgressEvent<FileReader>) => any) | null),
106-
onloadend: null as (((this: FileReader, ev: ProgressEvent<FileReader>) => any) | null),
107-
onloadstart: null as (((this: FileReader, ev: ProgressEvent<FileReader>) => any) | null),
108-
onprogress: null as (((this: FileReader, ev: ProgressEvent<FileReader>) => any) | null),
104+
onabort: null as (((this: FileReader, ev: ProgressEvent<FileReader>) => void) | null),
105+
onerror: null as (((this: FileReader, ev: ProgressEvent<FileReader>) => void) | null),
106+
onload: null as (((this: FileReader, ev: ProgressEvent<FileReader>) => void) | null),
107+
onloadend: null as (((this: FileReader, ev: ProgressEvent<FileReader>) => void) | null),
108+
onloadstart: null as (((this: FileReader, ev: ProgressEvent<FileReader>) => void) | null),
109+
onprogress: null as (((this: FileReader, ev: ProgressEvent<FileReader>) => void) | null),
109110

110111
// Methods
111112
abort: vi.fn<() => void>(),
112113
readAsArrayBuffer: vi.fn<(blob: Blob) => void>(),
113114
readAsBinaryString: vi.fn<(blob: Blob) => void>(),
114115
readAsDataURL: vi.fn((_blob: Blob): void => { // Ensure explicit void return for readAsDataURL
115-
const useFake = vi.isMockFunction(setTimeout) && (setTimeout as any).clock;
116+
const useFake = vi.isMockFunction(setTimeout) && (setTimeout as unknown as { clock: unknown }).clock;
116117
const delayFn = useFake ? setTimeout : (fn: () => void) => Promise.resolve().then(fn);
117118

118119
self.readyState = 1; // LOADING
119120
delayFn(() => {
120121
self.result = 'mock-data-url-filereader';
121122
self.readyState = 2; // DONE
122123
if (self.onload) {
123-
self.onload.call(self as any, { target: self } as unknown as ProgressEvent<FileReader>);
124+
self.onload.call(self as FileReader, { target: self } as unknown as ProgressEvent<FileReader>);
124125
}
125126
}, 0);
126127
}),
@@ -138,9 +139,9 @@ describe('CreateDatasetDialog Management', () => {
138139
Object.defineProperty(MockedFileReader, 'LOADING', { value: 1, writable: false });
139140
Object.defineProperty(MockedFileReader, 'DONE', { value: 2, writable: false });
140141

141-
vi.spyOn(window, 'FileReader').mockImplementation(MockedFileReader as any);
142+
vi.spyOn(window, 'FileReader').mockImplementation(MockedFileReader as unknown as typeof FileReader);
142143

143-
// @ts-ignore
144+
// @ts-expect-error window.Image is not available in a test environment
144145
window.Image = vi.fn(function() {
145146
const img = new OriginalImage();
146147
let _src = '';
@@ -150,7 +151,7 @@ describe('CreateDatasetDialog Management', () => {
150151
_src = value;
151152
img.width = 100;
152153
img.height = 100;
153-
const useFake = vi.isMockFunction(setTimeout) && (setTimeout as any).clock;
154+
const useFake = vi.isMockFunction(setTimeout) && (setTimeout as unknown as { clock: unknown }).clock;
154155
const delayFn = useFake ? setTimeout : (fn: () => void) => Promise.resolve().then(fn);
155156
delayFn(() => {
156157
if (img.onload) { // Null check before calling
@@ -167,7 +168,7 @@ describe('CreateDatasetDialog Management', () => {
167168
window.Image = OriginalImage;
168169
// Ensure fake timers are restored if a test block used them
169170
// Check if clock exists on setTimeout to determine if it's a Vitest fake timer
170-
if (vi.isMockFunction(setTimeout) && (setTimeout as any).clock) {
171+
if (vi.isMockFunction(setTimeout) && (setTimeout as unknown as { clock: unknown }).clock) {
171172
vi.useRealTimers();
172173
}
173174
});
@@ -248,17 +249,17 @@ describe('CreateDatasetDialog Management', () => {
248249
});
249250

250251
describe('Dataset Update', () => {
251-
const existingListDataset: MockDatasetInfo = { id: 'list1', name: 'Existing List', description: 'Old list description', type: 'list', data: ['Old Option 1']};
252+
const existingListDataset: MockDatasetInfo = { id: 'list1', name: 'Existing List', description: 'Old list description', type: 'list', data: ['Old Option 1'], columns: []};
252253
test('should update a "list" type dataset', async () => {
253-
render(<CreateDatasetDialog {...initialProps} dataset={existingListDataset as any} onClose={mockOnClose} onCreate={mockOnCreate} onUpdate={mockOnUpdate} />);
254+
render(<CreateDatasetDialog {...initialProps} dataset={existingListDataset} onClose={mockOnClose} onCreate={mockOnCreate} onUpdate={mockOnUpdate} />);
254255
await act(async () => { fireEvent.change(screen.getByLabelText('Name'), { target: { value: 'Updated List Name' } });});
255256
await act(async () => { fireEvent.click(screen.getByRole('button', { name: 'Update' }))});
256257
expect(mockOnUpdate).toHaveBeenCalledWith(existingListDataset.id, expect.objectContaining({ name: 'Updated List Name' }));
257258
});
258259

259-
const existingCsvDataset: MockDatasetInfo = { id: 'csv1', name: 'Existing CSV', description: 'Old CSV file', type: 'csv', data: ['file1.csv', 'file2.csv', 'file3.csv']};
260+
const existingCsvDataset: MockDatasetInfo = { id: 'csv1', name: 'Existing CSV', description: 'Old CSV file', type: 'csv', data: ['file1.csv', 'file2.csv', 'file3.csv'], columns: []};
260261
test('should update a "csv" type dataset by adding a new file', async () => {
261-
render(<CreateDatasetDialog {...initialProps} dataset={existingCsvDataset as any} onClose={mockOnClose} onCreate={mockOnCreate} onUpdate={mockOnUpdate} />);
262+
render(<CreateDatasetDialog {...initialProps} dataset={existingCsvDataset} onClose={mockOnClose} onCreate={mockOnCreate} onUpdate={mockOnUpdate} />);
262263
await findFileItemByName(existingCsvDataset.data[0]);
263264
const newCsvFile = mockFile('new_upload.csv', 'text/csv');
264265
const fileInput = screen.getByLabelText('CSV Files') as HTMLInputElement;
@@ -274,7 +275,7 @@ describe('CreateDatasetDialog Management', () => {
274275
test.skip('should update an "image" type dataset by adding a new image', async () => { /* Kept skipped */ });
275276

276277
describe('DND Reordering', () => {
277-
const existingCsvDatasetForDND: MockDatasetInfo = { id: 'csvDND', name: 'CSV DND', description: 'CSV DND test', type: 'csv', data: ['fileA.csv', 'fileB.csv', 'fileC.csv']};
278+
const existingCsvDatasetForDND: MockDatasetInfo = { id: 'csvDND', name: 'CSV DND', description: 'CSV DND test', type: 'csv', data: ['fileA.csv', 'fileB.csv', 'fileC.csv'], columns: []};
278279
test('should reorder files for a "csv" dataset via DND and call onUpdate', async () => {
279280
// This test does not need fake timers as CSV file item rendering is synchronous after initial load
280281
render(
@@ -298,8 +299,8 @@ describe('CreateDatasetDialog Management', () => {
298299
expect(dndOnDragEnd).toBeDefined();
299300
if (dndOnDragEnd) {
300301
const dragEndEvent: DragEndEvent = {
301-
active: { id: activeItemId } as any,
302-
over: { id: overItemId } as any,
302+
active: { id: activeItemId as UniqueIdentifier } as Active,
303+
over: { id: overItemId as UniqueIdentifier } as Over,
303304
} as DragEndEvent;
304305

305306
await act(async () => { // Wrap state update in act

0 commit comments

Comments
 (0)