import { flushPromises, mount } from '@vue/test-utils';
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
import { defaultPosition, defaultWatermark } from '../model';
|
import PaperPreview from '../PaperPreview.vue';
|
|
const mocks = vi.hoisted(() => ({ preview: vi.fn() }));
|
vi.mock('#/api/x/dms/watermark', () => ({ getWatermarkPreview: mocks.preview }));
|
|
beforeEach(() => {
|
vi.clearAllMocks();
|
vi.stubGlobal(
|
'Image',
|
class {
|
listeners = new Map<string, () => void>();
|
get src() {
|
return 'blob:preview';
|
}
|
set src(_: string) {
|
queueMicrotask(() => this.listeners.get('load')?.());
|
}
|
addEventListener(event: string, listener: () => void) {
|
this.listeners.set(event, listener);
|
}
|
},
|
);
|
vi.spyOn(URL, 'createObjectURL').mockReturnValue('blob:preview');
|
vi.spyOn(URL, 'revokeObjectURL').mockImplementation(() => {});
|
mocks.preview.mockResolvedValue(new Blob(['preview'], { type: 'image/png' }));
|
});
|
afterEach(() => {
|
vi.restoreAllMocks();
|
vi.unstubAllGlobals();
|
});
|
|
describe('server-rendered watermark preview', () => {
|
it.each([
|
['portrait', 210, 297, 420, 594],
|
['landscape', 297, 210, 594, 420],
|
] as const)('uses the export renderer and configured font in %s', async (orientation, width, height, canvasWidth, canvasHeight) => {
|
const context = { clearRect: vi.fn(), drawImage: vi.fn() };
|
vi.spyOn(HTMLCanvasElement.prototype, 'getContext').mockReturnValue(context as unknown as CanvasRenderingContext2D);
|
const config = {
|
...defaultWatermark(),
|
contentTemplate: '用户:{/CUN}',
|
fontFamily: 'Directory Font',
|
horizontalAlign: 'RIGHT' as const,
|
verticalAlign: 'BOTTOM' as const,
|
};
|
const position = defaultPosition();
|
const wrapper = mount(PaperPreview, { props: { config, position, orientation } });
|
await flushPromises();
|
expect(mocks.preview).toHaveBeenCalledWith(
|
width,
|
height,
|
expect.objectContaining({
|
fontFamily: 'Directory Font',
|
horizontalAlign: 'RIGHT',
|
verticalAlign: 'BOTTOM',
|
positions: [position],
|
}),
|
'用户:张三',
|
);
|
expect(context.drawImage).toHaveBeenCalledWith(expect.anything(), 0, 0, canvasWidth, canvasHeight);
|
expect(URL.revokeObjectURL).toHaveBeenCalledWith('blob:preview');
|
expect(wrapper.find('.render-error').exists()).toBe(false);
|
wrapper.unmount();
|
});
|
|
it('displays font errors from the renderer instead of substituting a browser font', async () => {
|
const context = { clearRect: vi.fn(), drawImage: vi.fn() };
|
vi.spyOn(HTMLCanvasElement.prototype, 'getContext').mockReturnValue(context as unknown as CanvasRenderingContext2D);
|
mocks.preview.mockResolvedValue(new Blob([JSON.stringify({ msg: '配置字体目录中不存在字体:SimHei' })], { type: 'application/json' }));
|
const wrapper = mount(PaperPreview, { props: { config: defaultWatermark(), position: defaultPosition(), orientation: 'portrait' } });
|
await flushPromises();
|
expect(wrapper.get('.render-error').text()).toContain('配置字体目录中不存在字体');
|
expect(context.drawImage).not.toHaveBeenCalled();
|
wrapper.unmount();
|
});
|
|
it('does not draw a request that finishes after the preview is closed', async () => {
|
const context = { clearRect: vi.fn(), drawImage: vi.fn() };
|
vi.spyOn(HTMLCanvasElement.prototype, 'getContext').mockReturnValue(context as unknown as CanvasRenderingContext2D);
|
let finish!: (blob: Blob) => void;
|
mocks.preview.mockReturnValue(
|
new Promise<Blob>((resolve) => {
|
finish = resolve;
|
}),
|
);
|
const wrapper = mount(PaperPreview, { props: { config: defaultWatermark(), position: defaultPosition(), orientation: 'portrait' } });
|
wrapper.unmount();
|
finish(new Blob(['preview'], { type: 'image/png' }));
|
await flushPromises();
|
expect(context.drawImage).not.toHaveBeenCalled();
|
expect(URL.createObjectURL).not.toHaveBeenCalled();
|
});
|
});
|