166 lines
5.0 KiB
TypeScript
166 lines
5.0 KiB
TypeScript
import React from 'react';
|
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
import { fireEvent, render, screen } from '@testing-library/react';
|
|
import TrackInfoItem from './TrackInfoItem';
|
|
import { KGAudioTrack } from '../../core/track/KGAudioTrack';
|
|
import { showConfirm } from '../../util/dialogUtil';
|
|
import { translate } from '../../i18n/translate';
|
|
|
|
const storeState = {
|
|
selectedTrackId: null as string | null,
|
|
setSelectedTrack: vi.fn(),
|
|
removeTrack: vi.fn(),
|
|
toggleInstrumentSelectionForTrack: vi.fn(),
|
|
importAudioToTrack: vi.fn(),
|
|
updateTrackProperties: vi.fn(),
|
|
tracks: [] as KGAudioTrack[],
|
|
activeTrackAutomationTrackId: null as string | null,
|
|
activeTrackAutomationType: null as string | null,
|
|
setTrackAutomationView: vi.fn(),
|
|
};
|
|
|
|
let fileImportModalProps: Record<string, unknown> | null = null;
|
|
|
|
vi.mock('../../stores/projectStore', () => ({
|
|
useProjectStore: Object.assign(
|
|
(selector?: (state: typeof storeState) => unknown) => (
|
|
selector ? selector(storeState) : storeState
|
|
),
|
|
{
|
|
getState: () => storeState,
|
|
},
|
|
),
|
|
}));
|
|
|
|
vi.mock('../../i18n/useI18n', async () => {
|
|
const { translate } = await import('../../i18n/translate');
|
|
return {
|
|
useI18n: () => ({
|
|
t: (key: string, params?: Record<string, string | number>) => translate(key, params, 'zh_cn'),
|
|
}),
|
|
};
|
|
});
|
|
|
|
vi.mock('../common/KGDropdown', () => ({
|
|
default: ({ options, isOpen, onChange }: { options: Array<string | { label: string; value: string }>; isOpen?: boolean; onChange: (value: string) => void }) => (
|
|
isOpen ? (
|
|
<div>
|
|
{options.map((option) => {
|
|
const value = typeof option === 'string' ? option : option.value;
|
|
const label = typeof option === 'string' ? option : option.label;
|
|
return (
|
|
<button key={value} type="button" onClick={() => onChange(value)}>
|
|
{label}
|
|
</button>
|
|
);
|
|
})}
|
|
</div>
|
|
) : null
|
|
),
|
|
}));
|
|
|
|
vi.mock('../common/FileImportModal', () => ({
|
|
default: (props: Record<string, unknown>) => {
|
|
fileImportModalProps = props;
|
|
return null;
|
|
},
|
|
}));
|
|
|
|
vi.mock('../../util/dialogUtil', () => ({
|
|
showAlert: vi.fn(),
|
|
showConfirm: vi.fn(),
|
|
}));
|
|
|
|
describe('TrackInfoItem audio import', () => {
|
|
beforeEach(() => {
|
|
fileImportModalProps = null;
|
|
storeState.selectedTrackId = null;
|
|
storeState.setSelectedTrack.mockReset();
|
|
storeState.removeTrack.mockReset();
|
|
storeState.toggleInstrumentSelectionForTrack.mockReset();
|
|
storeState.importAudioToTrack.mockReset();
|
|
storeState.updateTrackProperties.mockReset();
|
|
storeState.setTrackAutomationView.mockReset();
|
|
vi.mocked(showConfirm).mockReset();
|
|
});
|
|
|
|
it('advertises m4a support in the track audio import modal', () => {
|
|
const audioTrack = new KGAudioTrack('Audio Track', 1);
|
|
audioTrack.setTrackIndex(0);
|
|
storeState.tracks = [audioTrack];
|
|
|
|
render(
|
|
<TrackInfoItem
|
|
track={audioTrack}
|
|
index={0}
|
|
isDragging={false}
|
|
isDragOver={false}
|
|
onTrackNameEdit={vi.fn()}
|
|
onDragStart={vi.fn()}
|
|
onDragOver={vi.fn()}
|
|
onDrop={vi.fn()}
|
|
onDragEnd={vi.fn()}
|
|
/>
|
|
);
|
|
|
|
expect(fileImportModalProps?.acceptedTypes).toEqual(['.wav', '.mp3', '.ogg', '.flac', '.aac', '.m4a']);
|
|
});
|
|
|
|
it('uses the localized delete-track confirmation message', () => {
|
|
const audioTrack = new KGAudioTrack('钢琴', 1);
|
|
audioTrack.setTrackIndex(0);
|
|
storeState.tracks = [audioTrack];
|
|
|
|
vi.mocked(showConfirm).mockResolvedValue(false);
|
|
|
|
render(
|
|
<TrackInfoItem
|
|
track={audioTrack}
|
|
index={0}
|
|
isDragging={false}
|
|
isDragOver={false}
|
|
onTrackNameEdit={vi.fn()}
|
|
onDragStart={vi.fn()}
|
|
onDragOver={vi.fn()}
|
|
onDrop={vi.fn()}
|
|
onDragEnd={vi.fn()}
|
|
/>
|
|
);
|
|
|
|
fireEvent.click(screen.getByRole('button', { name: '更多操作' }));
|
|
fireEvent.click(screen.getByRole('button', { name: '删除轨道' }));
|
|
|
|
expect(showConfirm).toHaveBeenCalledWith(
|
|
translate('track.controls.settings.deleteTrackConfirm', { name: '钢琴' }, 'zh_cn')
|
|
);
|
|
});
|
|
|
|
it('shows the track color entry and clears the color override', async () => {
|
|
const audioTrack = new KGAudioTrack('Audio Track', 1);
|
|
audioTrack.setTrackIndex(0);
|
|
audioTrack.setColor('#3C8AC4');
|
|
storeState.tracks = [audioTrack];
|
|
storeState.updateTrackProperties.mockResolvedValue(undefined);
|
|
|
|
render(
|
|
<TrackInfoItem
|
|
track={audioTrack}
|
|
index={0}
|
|
isDragging={false}
|
|
isDragOver={false}
|
|
onTrackNameEdit={vi.fn()}
|
|
onDragStart={vi.fn()}
|
|
onDragOver={vi.fn()}
|
|
onDrop={vi.fn()}
|
|
onDragEnd={vi.fn()}
|
|
/>
|
|
);
|
|
|
|
fireEvent.click(screen.getByRole('button', { name: '更多操作' }));
|
|
fireEvent.click(screen.getByRole('button', { name: '轨道颜色...' }));
|
|
fireEvent.click(screen.getByRole('button', { name: 'Reset color' }));
|
|
|
|
expect(storeState.updateTrackProperties).toHaveBeenCalledWith(1, { color: null });
|
|
});
|
|
});
|