110 lines
4.9 KiB
TypeScript
110 lines
4.9 KiB
TypeScript
import { describe, expect, it, vi } from 'vitest';
|
|
import { createWatermarkTemplateRequestSchema } from '@atlas/contracts';
|
|
import { WatermarksService } from '../src/watermarks/watermarks.service.js';
|
|
|
|
const templateId = '46ea1f9c-28d0-4b32-92e1-3d4e74ad7757';
|
|
|
|
const templateRow = (x: number, y: number, position: string) => ({
|
|
id: templateId,
|
|
name: '测试水印',
|
|
kind: 'text' as const,
|
|
current_version: 1,
|
|
created_at: new Date('2026-09-25T00:00:00Z'),
|
|
updated_at: new Date('2026-09-25T00:00:00Z'),
|
|
revision: 1,
|
|
text_content: 'Atlas',
|
|
image_asset_id: null,
|
|
font_code: 'NotoSans',
|
|
font_size_px: 15,
|
|
opacity: '0.2600',
|
|
scale_ratio: null,
|
|
position,
|
|
position_x: x.toFixed(4),
|
|
position_y: y.toFixed(4),
|
|
});
|
|
|
|
describe('水印任意位置坐标', () => {
|
|
it('契约接收精确坐标、兼容旧位置,并拒绝创建时只给一个坐标', () => {
|
|
const base = {
|
|
name: '测试水印',
|
|
kind: 'text',
|
|
config: {
|
|
text_content: 'Atlas',
|
|
font_code: 'NotoSans',
|
|
font_size_px: 15,
|
|
opacity: '0.26',
|
|
},
|
|
};
|
|
expect(createWatermarkTemplateRequestSchema.safeParse({
|
|
...base, config: { ...base.config, position_x: 0.3737, position_y: 0.6161 },
|
|
}).success).toBe(true);
|
|
expect(createWatermarkTemplateRequestSchema.safeParse({
|
|
...base, config: { ...base.config, position: 'bottom_right' },
|
|
}).success).toBe(true);
|
|
expect(createWatermarkTemplateRequestSchema.safeParse({
|
|
...base, config: { ...base.config, position_x: 0.3737 },
|
|
}).success).toBe(false);
|
|
});
|
|
|
|
it('创建时保存精确坐标并在读取响应中返回,不吸附九宫格', async () => {
|
|
let insertedVersion: unknown[] = [];
|
|
const query = vi.fn(async (sql: string, args?: unknown[]) => {
|
|
if (sql.includes('SELECT code FROM atlas.watermark_fonts')) return { rows: [{ code: 'NotoSans' }] };
|
|
if (sql.includes('INSERT INTO atlas.watermark_templates')) return { rows: [{ id: templateId }] };
|
|
if (sql.includes('INSERT INTO atlas.watermark_template_versions')) {
|
|
insertedVersion = args ?? [];
|
|
return { rows: [] };
|
|
}
|
|
if (sql.includes('SELECT template.id')) return { rows: [templateRow(
|
|
Number(insertedVersion[9]), Number(insertedVersion[10]), String(insertedVersion[11]),
|
|
)] };
|
|
throw new Error(`未知 SQL: ${sql}`);
|
|
});
|
|
const run = vi.fn(async (_input: unknown, work: (tx: { query: typeof query }) => Promise<unknown>) =>
|
|
work({ query }));
|
|
const service = new WatermarksService(
|
|
{ run } as unknown as ConstructorParameters<typeof WatermarksService>[0],
|
|
{} as ConstructorParameters<typeof WatermarksService>[1],
|
|
);
|
|
const result = await service.create('workspace', 'user', 'key', {
|
|
name: '测试水印', kind: 'text',
|
|
config: {
|
|
text_content: 'Atlas', font_code: 'NotoSans', font_size_px: 15,
|
|
opacity: '0.26', position_x: 0.3737, position_y: 0.6161,
|
|
},
|
|
});
|
|
expect(insertedVersion.slice(9, 12)).toEqual([0.3737, 0.6161, 'center']);
|
|
expect(result).toMatchObject({
|
|
body: { data: { config: { position_x: 0.3737, position_y: 0.6161 } } },
|
|
});
|
|
});
|
|
|
|
it('旧版九宫格输入换算为精确坐标', async () => {
|
|
let insertedVersion: unknown[] = [];
|
|
const query = vi.fn(async (sql: string, args?: unknown[]) => {
|
|
if (sql.includes('SELECT code FROM atlas.watermark_fonts')) return { rows: [{ code: 'NotoSans' }] };
|
|
if (sql.includes('INSERT INTO atlas.watermark_templates')) return { rows: [{ id: templateId }] };
|
|
if (sql.includes('INSERT INTO atlas.watermark_template_versions')) {
|
|
insertedVersion = args ?? [];
|
|
return { rows: [] };
|
|
}
|
|
if (sql.includes('SELECT template.id')) return { rows: [templateRow(1, 0, 'top_right')] };
|
|
throw new Error(`未知 SQL: ${sql}`);
|
|
});
|
|
const run = vi.fn(async (_input: unknown, work: (tx: { query: typeof query }) => Promise<unknown>) =>
|
|
work({ query }));
|
|
const service = new WatermarksService(
|
|
{ run } as unknown as ConstructorParameters<typeof WatermarksService>[0],
|
|
{} as ConstructorParameters<typeof WatermarksService>[1],
|
|
);
|
|
await service.create('workspace', 'user', 'key', {
|
|
name: '测试水印', kind: 'text',
|
|
config: {
|
|
text_content: 'Atlas', font_code: 'NotoSans', font_size_px: 15,
|
|
opacity: '0.26', position: 'top_right',
|
|
},
|
|
});
|
|
expect(insertedVersion.slice(9, 12)).toEqual([1, 0, 'top_right']);
|
|
});
|
|
});
|