Files
Artemis-Eapil/apps/showcase_ui/src/app/components/task-id-copy/task-id-copy.component.spec.ts
T

84 lines
3.3 KiB
TypeScript

import { Clipboard } from '@angular/cdk/clipboard';
import { TestBed } from '@angular/core/testing';
import { TaskIdCopyComponent } from './task-id-copy.component';
describe('任务 ID 复制', () => {
let clipboard: jasmine.SpyObj<Clipboard>;
beforeEach(() => {
spyOn(navigator.clipboard, 'writeText').and.rejectWith(new Error('blocked'));
clipboard = jasmine.createSpyObj('Clipboard', ['copy']);
TestBed.configureTestingModule({ providers: [{ provide: Clipboard, useValue: clipboard }] });
});
afterEach(() => window.getSelection()?.removeAllRanges());
function setup() {
const fixture = TestBed.createComponent(TaskIdCopyComponent);
fixture.componentRef.setInput('taskId', 'task-123');
fixture.detectChanges();
const target: HTMLElement = fixture.nativeElement.querySelector('[role="button"]');
return { fixture, target };
}
it('点击复制完整 ID,并提示成功,不触发父卡片', async () => {
clipboard.copy.and.returnValue(true);
const { fixture, target } = setup();
const parentClick = jasmine.createSpy('parentClick');
fixture.nativeElement.addEventListener('click', parentClick);
target.click();
await Promise.resolve();
fixture.detectChanges();
expect(clipboard.copy).toHaveBeenCalledOnceWith('task-123');
expect(fixture.nativeElement.querySelector('[role="status"]').textContent).toContain('已复制');
expect(parentClick).not.toHaveBeenCalled();
fixture.destroy();
});
it('优先使用浏览器剪贴板,并在写入完成后提示成功', async () => {
const write = navigator.clipboard.writeText as jasmine.Spy;
let complete!: () => void;
write.and.returnValue(new Promise<void>(resolve => complete = resolve));
const { fixture, target } = setup();
target.click();
expect(fixture.componentInstance.feedback()).toBe('');
complete();
await Promise.resolve();
expect(write).toHaveBeenCalledOnceWith('task-123');
expect(clipboard.copy).not.toHaveBeenCalled();
expect(fixture.componentInstance.feedback()).toBe('任务 ID 已复制');
fixture.destroy();
});
it('复制失败不会提示成功,ID 仍可手动选择', async () => {
clipboard.copy.and.returnValue(false);
const { fixture, target } = setup();
target.click();
await Promise.resolve();
fixture.detectChanges();
expect(fixture.nativeElement.textContent).toContain('复制失败,请选中任务 ID 手动复制');
expect(getComputedStyle(target.querySelector('.value')!).userSelect).toBe('text');
fixture.destroy();
});
it('拖选 ID 后的点击不会覆盖剪贴板或清空选区', () => {
const { fixture, target } = setup();
const range = document.createRange();
range.selectNodeContents(target.querySelector('.value')!);
const selection = window.getSelection()!;
selection.removeAllRanges();
selection.addRange(range);
target.click();
expect(clipboard.copy).not.toHaveBeenCalled();
expect(selection.toString()).toContain('task-123');
fixture.destroy();
});
it('支持键盘 Enter 复制', async () => {
clipboard.copy.and.returnValue(true);
const { fixture, target } = setup();
target.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true }));
await Promise.resolve();
expect(clipboard.copy).toHaveBeenCalledOnceWith('task-123');
fixture.destroy();
});
});