Files
photo-live/apps/viewer/src/__tests__/photo-action-bar.spec.ts
T
2026-09-23 09:31:26 +08:00

116 lines
4.6 KiB
TypeScript

import { mount, type VueWrapper } from '@vue/test-utils';
import { nextTick } from 'vue';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import PhotoActionBar from '../components/viewer/PhotoActionBar.vue';
import { createViewerI18n, type ViewerI18n } from '../i18n';
// UI-02 §5.1/§5.4 底部操作栏单测:Like/Share/Download 三键与标签、计数
// Intl 格式化、下载关闭时移除整项(剩余均分)、原图二级菜单(▾ 与长按)、
// 事件上抛(like/share/download(variant))。
let i18n: ViewerI18n;
const mounted: VueWrapper[] = [];
function mountBar(props: {
likeCount: number;
canDownload?: boolean;
canDownloadOriginal?: boolean;
}): VueWrapper {
const wrapper = mount(PhotoActionBar, {
props: {
canDownload: false,
canDownloadOriginal: false,
...props,
},
global: { plugins: [i18n] },
});
mounted.push(wrapper);
return wrapper;
}
describe('photo action bar (UI-02 V04)', () => {
beforeEach(() => {
localStorage.clear();
i18n = createViewerI18n('zh-CN');
});
afterEach(() => {
while (mounted.length > 0) mounted.pop()?.unmount();
vi.useRealTimers();
vi.restoreAllMocks();
});
it('renders like/share/download as evenly distributed slots with formatted count (no tap-more hint)', () => {
const wrapper = mountBar({ likeCount: 1286, canDownload: true });
// 三个 action-slot flex 均分(下载隐藏时由剩余 slot 自然重排,见下例)。
expect(wrapper.findAll('.action-slot')).toHaveLength(3);
const labels = wrapper.findAll('.action-label').map((label) => label.text());
expect(labels).toEqual(['点赞', '分享', '下载']);
// 计数 Intl 分组 + tabular-nums 容器;「连续点击」提示已按用户要求移除。
expect(wrapper.find('.like-count').text()).toBe('1,286');
expect(wrapper.find('.like-hint').exists()).toBe(false);
});
it('removes the download action entirely when downloads are disabled', () => {
const wrapper = mountBar({ likeCount: 0, canDownload: false });
expect(wrapper.find('.download-group').exists()).toBe(false);
expect(wrapper.findAll('.action-slot')).toHaveLength(2); // 剩余两键均分栏宽
expect(wrapper.findAll('.action-label').map((label) => label.text())).toEqual(['点赞', '分享']);
});
it('emits like and share from the large tap targets', async () => {
const wrapper = mountBar({ likeCount: 3 });
const buttons = wrapper.findAll('.action-btn');
expect(buttons).toHaveLength(2);
await buttons[0].trigger('click');
await buttons[1].trigger('click');
expect(wrapper.emitted('like')).toHaveLength(1);
expect(wrapper.emitted('share')).toHaveLength(1);
expect(wrapper.emitted('download')).toBeUndefined();
});
it('downloads the browse variant directly when original download is disabled', async () => {
const wrapper = mountBar({ likeCount: 0, canDownload: true, canDownloadOriginal: false });
expect(wrapper.find('.download-caret').exists()).toBe(false);
await wrapper.find('.download-group .action-btn').trigger('click');
expect(wrapper.emitted('download')).toEqual([['browse']]);
});
it('offers browse/original choices via the caret menu', async () => {
const wrapper = mountBar({ likeCount: 0, canDownload: true, canDownloadOriginal: true });
const caret = wrapper.find('.download-caret');
expect(caret.attributes('aria-haspopup')).toBe('menu');
await caret.trigger('click');
const menu = wrapper.find('.download-menu');
expect(menu.attributes('role')).toBe('menu');
expect(menu.text()).toContain('浏览图');
expect(menu.text()).toContain('原图');
const items = menu.findAll('button');
await items[1].trigger('click');
expect(wrapper.emitted('download')).toEqual([['original']]);
});
it('long-pressing the download button opens the variant menu instead of firing browse', async () => {
vi.useFakeTimers();
const wrapper = mountBar({ likeCount: 0, canDownload: true, canDownloadOriginal: true });
const button = wrapper.find('.download-group .action-btn');
await button.trigger('pointerdown');
vi.advanceTimersByTime(500);
await nextTick(); // 定时器改状态后等一帧再查 DOM
expect(wrapper.find('.download-menu').exists()).toBe(true);
// 长按已展开菜单:紧随的 click 被吞掉,不触发默认浏览图下载。
await button.trigger('click');
expect(wrapper.emitted('download')).toBeUndefined();
await wrapper.find('.download-menu button').trigger('click');
expect(wrapper.emitted('download')).toEqual([['browse']]);
});
});