154 lines
7.3 KiB
TypeScript
154 lines
7.3 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 assetId = '54799515-028d-4320-80a2-f53fd13fb588';
|
|
|
|
const imageRow = (size: number, radius: number, version = 1) => ({
|
|
id: templateId,
|
|
name: '图片水印',
|
|
kind: 'image' as const,
|
|
current_version: version,
|
|
created_at: new Date('2026-09-26T00:00:00Z'),
|
|
updated_at: new Date('2026-09-26T00:00:00Z'),
|
|
revision: version,
|
|
text_content: null,
|
|
image_asset_id: assetId,
|
|
font_code: null,
|
|
font_size_px: null,
|
|
opacity: '0.2600',
|
|
scale_ratio: '0.5556',
|
|
image_size_px: size,
|
|
border_radius_px: radius,
|
|
position: 'bottom_right',
|
|
position_x: '1.0000',
|
|
position_y: '1.0000',
|
|
});
|
|
|
|
const serviceWith = (query: ReturnType<typeof vi.fn>) => {
|
|
const run = vi.fn(async (_input: unknown, work: (tx: { query: typeof query }) => Promise<unknown>) =>
|
|
work({ query }));
|
|
return new WatermarksService(
|
|
{ run } as unknown as ConstructorParameters<typeof WatermarksService>[0],
|
|
{} as ConstructorParameters<typeof WatermarksService>[1],
|
|
);
|
|
};
|
|
|
|
describe('图片水印像素尺寸和圆角', () => {
|
|
it('创建契约接收像素尺寸并约束尺寸和圆角范围,同时兼容旧比例', () => {
|
|
const base = {
|
|
name: '图片水印', kind: 'image',
|
|
config: { image_asset_id: assetId, opacity: '0.26', position_x: 1, position_y: 1 },
|
|
};
|
|
expect(createWatermarkTemplateRequestSchema.safeParse({
|
|
...base, config: { ...base.config, image_size_px: 80, border_radius_px: 12 },
|
|
}).success).toBe(true);
|
|
expect(createWatermarkTemplateRequestSchema.safeParse({
|
|
...base, config: { ...base.config, image_size_px: 10 },
|
|
}).success).toBe(true);
|
|
expect(createWatermarkTemplateRequestSchema.safeParse({
|
|
...base, config: { ...base.config, scale_ratio: '0.25' },
|
|
}).success).toBe(true);
|
|
expect(createWatermarkTemplateRequestSchema.safeParse(base).success).toBe(false);
|
|
expect(createWatermarkTemplateRequestSchema.safeParse({
|
|
...base, config: { ...base.config, image_size_px: 9 },
|
|
}).success).toBe(false);
|
|
expect(createWatermarkTemplateRequestSchema.safeParse({
|
|
...base, config: { ...base.config, image_size_px: 201 },
|
|
}).success).toBe(false);
|
|
expect(createWatermarkTemplateRequestSchema.safeParse({
|
|
...base, config: { ...base.config, image_size_px: 80, border_radius_px: 101 },
|
|
}).success).toBe(false);
|
|
});
|
|
|
|
it('创建时保存绝对尺寸和圆角,并保留旧比例字段', async () => {
|
|
let inserted: unknown[] = [];
|
|
const query = vi.fn(async (sql: string, args?: unknown[]) => {
|
|
if (sql.includes('SELECT id FROM atlas.media_assets')) return { rows: [{ id: assetId }] };
|
|
if (sql.includes('INSERT INTO atlas.watermark_templates')) return { rows: [{ id: templateId }] };
|
|
if (sql.includes('INSERT INTO atlas.watermark_template_versions')) {
|
|
inserted = args ?? [];
|
|
return { rows: [] };
|
|
}
|
|
if (sql.includes('SELECT template.id')) return { rows: [imageRow(Number(inserted[13]), Number(inserted[14]))] };
|
|
throw new Error(`未知 SQL: ${sql}`);
|
|
});
|
|
const result = await serviceWith(query).create('workspace', 'user', 'key', {
|
|
name: '图片水印', kind: 'image',
|
|
config: { image_asset_id: assetId, image_size_px: 80, border_radius_px: 12,
|
|
opacity: '0.26', position_x: 1, position_y: 1 },
|
|
});
|
|
expect(inserted[8]).toBe('0.5556');
|
|
expect(inserted.slice(13, 15)).toEqual([80, 12]);
|
|
expect(result).toMatchObject({ body: { data: { config: {
|
|
image_size_px: 80, border_radius_px: 12,
|
|
} } } });
|
|
});
|
|
|
|
it('旧版比例输入换算为像素尺寸,圆角默认为零', async () => {
|
|
let inserted: unknown[] = [];
|
|
const query = vi.fn(async (sql: string, args?: unknown[]) => {
|
|
if (sql.includes('SELECT id FROM atlas.media_assets')) return { rows: [{ id: assetId }] };
|
|
if (sql.includes('INSERT INTO atlas.watermark_templates')) return { rows: [{ id: templateId }] };
|
|
if (sql.includes('INSERT INTO atlas.watermark_template_versions')) {
|
|
inserted = args ?? [];
|
|
return { rows: [] };
|
|
}
|
|
if (sql.includes('SELECT template.id')) return { rows: [imageRow(36, 0)] };
|
|
throw new Error(`未知 SQL: ${sql}`);
|
|
});
|
|
await serviceWith(query).create('workspace', 'user', 'key', {
|
|
name: '图片水印', kind: 'image',
|
|
config: { image_asset_id: assetId, scale_ratio: '0.25',
|
|
opacity: '0.26', position_x: 1, position_y: 1 },
|
|
});
|
|
expect(inserted[8]).toBe('0.25');
|
|
expect(inserted.slice(13, 15)).toEqual([36, 0]);
|
|
});
|
|
|
|
it('10px 尺寸原值保存,兼容比例保持旧版允许的最小值', async () => {
|
|
let inserted: unknown[] = [];
|
|
const query = vi.fn(async (sql: string, args?: unknown[]) => {
|
|
if (sql.includes('SELECT id FROM atlas.media_assets')) return { rows: [{ id: assetId }] };
|
|
if (sql.includes('INSERT INTO atlas.watermark_templates')) return { rows: [{ id: templateId }] };
|
|
if (sql.includes('INSERT INTO atlas.watermark_template_versions')) {
|
|
inserted = args ?? [];
|
|
return { rows: [] };
|
|
}
|
|
if (sql.includes('SELECT template.id')) return { rows: [imageRow(10, 0)] };
|
|
throw new Error(`未知 SQL: ${sql}`);
|
|
});
|
|
await serviceWith(query).create('workspace', 'user', 'key', {
|
|
name: '图片水印', kind: 'image',
|
|
config: { image_asset_id: assetId, image_size_px: 10,
|
|
opacity: '0.26', position_x: 1, position_y: 1 },
|
|
});
|
|
expect(inserted[8]).toBe('0.1');
|
|
expect(inserted[13]).toBe(10);
|
|
});
|
|
|
|
it('只修改圆角时保留图片尺寸并创建新版本', async () => {
|
|
let inserted: unknown[] = [];
|
|
const query = vi.fn(async (sql: string, args?: unknown[]) => {
|
|
if (sql.includes('SELECT template.id') && sql.includes('FOR UPDATE')) return { rows: [imageRow(80, 0)] };
|
|
if (sql.includes('SELECT id FROM atlas.media_assets')) return { rows: [{ id: assetId }] };
|
|
if (sql.includes('UPDATE atlas.watermark_templates')) return { rows: [] };
|
|
if (sql.includes('INSERT INTO atlas.watermark_template_versions')) {
|
|
inserted = args ?? [];
|
|
return { rows: [] };
|
|
}
|
|
if (sql.includes('SELECT template.id')) return { rows: [imageRow(80, 16, 2)] };
|
|
throw new Error(`未知 SQL: ${sql}`);
|
|
});
|
|
const result = await serviceWith(query).update(
|
|
'workspace', 'user', templateId, 'key', 1, { config: { border_radius_px: 16 } },
|
|
);
|
|
expect(inserted[13]).toBe(80);
|
|
expect(inserted[14]).toBe(16);
|
|
expect(result).toMatchObject({ body: { data: { current_version: 2, config: {
|
|
image_size_px: 80, border_radius_px: 16,
|
|
} } } });
|
|
});
|
|
});
|