* refactor(shared-components): move core primitives under core * refactor(shared-components): restore i18n strings path * fix(shared-components): repair typedoc story imports * fix(shared-components): align newer imports with core paths * test(shared-components): add core visual baselines * refactor(shared-components): move virtualized list to core root
84 lines
3.1 KiB
TypeScript
84 lines
3.1 KiB
TypeScript
/*
|
|
* Copyright 2025 New Vector Ltd.
|
|
*
|
|
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
|
* Please see LICENSE files in the repository root for full details.
|
|
*/
|
|
|
|
import { render, screen } from "@test-utils";
|
|
import { composeStories } from "@storybook/react-vite";
|
|
import React from "react";
|
|
import userEvent from "@testing-library/user-event";
|
|
import { fireEvent } from "@testing-library/dom";
|
|
import { describe, it, vi, afterEach, expect } from "vitest";
|
|
|
|
import * as stories from "./AudioPlayerView.stories.tsx";
|
|
import { AudioPlayerView, type AudioPlayerViewActions, type AudioPlayerViewSnapshot } from "./AudioPlayerView";
|
|
import { MockViewModel } from "../../core/viewmodel/MockViewModel.ts";
|
|
import { I18nContext } from "../../core/i18n/i18nContext.ts";
|
|
import { I18nApi } from "../../index.ts";
|
|
|
|
const { Default, NoMediaName, NoSize, HasError } = composeStories(stories);
|
|
|
|
describe("AudioPlayerView", () => {
|
|
afterEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
it("renders the audio player in default state", () => {
|
|
const { container } = render(<Default />);
|
|
expect(container).toMatchSnapshot();
|
|
});
|
|
|
|
it("renders the audio player without media name", () => {
|
|
const { container } = render(<NoMediaName />);
|
|
expect(container).toMatchSnapshot();
|
|
});
|
|
|
|
it("renders the audio player without size", () => {
|
|
const { container } = render(<NoSize />);
|
|
expect(container).toMatchSnapshot();
|
|
});
|
|
|
|
it("renders the audio player in error state", () => {
|
|
const { container } = render(<HasError />);
|
|
expect(container).toMatchSnapshot();
|
|
});
|
|
|
|
const onKeyDown = vi.fn();
|
|
const togglePlay = vi.fn();
|
|
const onSeekbarChange = vi.fn();
|
|
|
|
class AudioPlayerViewModel extends MockViewModel<AudioPlayerViewSnapshot> implements AudioPlayerViewActions {
|
|
public onKeyDown = onKeyDown;
|
|
public togglePlay = togglePlay;
|
|
public onSeekbarChange = onSeekbarChange;
|
|
}
|
|
|
|
it("should attach vm methods", async () => {
|
|
const user = userEvent.setup();
|
|
const vm = new AudioPlayerViewModel({
|
|
playbackState: "stopped",
|
|
mediaName: "Test Audio",
|
|
durationSeconds: 300,
|
|
playedSeconds: 120,
|
|
percentComplete: 30,
|
|
sizeBytes: 3500,
|
|
error: false,
|
|
});
|
|
|
|
render(<AudioPlayerView vm={vm} />, {
|
|
wrapper: ({ children }) => <I18nContext.Provider value={new I18nApi()}>{children}</I18nContext.Provider>,
|
|
});
|
|
await user.click(screen.getByRole("button", { name: "Play" }));
|
|
expect(togglePlay).toHaveBeenCalled();
|
|
|
|
// user event doesn't support change events on sliders, so we use fireEvent
|
|
fireEvent.change(screen.getByRole("slider", { name: "Audio seek bar" }), { target: { value: "50" } });
|
|
expect(onSeekbarChange).toHaveBeenCalled();
|
|
|
|
await user.type(screen.getByLabelText("Audio player"), "{arrowup}");
|
|
expect(onKeyDown).toHaveBeenCalledWith(expect.objectContaining({ key: "ArrowUp" }));
|
|
});
|
|
});
|