1
import type { File } from '@directus/types';
2
import { describe, expect, test } from 'vitest';
3
import type { Transformation, TransformationParams } from '../types/assets.js';
4
import { maybeExtractFormat, resolvePreset } from './transformations.js';
7
id: '43a15f67-84a7-4e07-880d-e46a9f33c542',
10
filename_download: 'test',
15
uploaded_on: '2023-12-19T16:12:53.149Z',
32
describe('resolvePreset', () => {
33
test('Prevent input mutation #18301', () => {
34
const transformationParams: TransformationParams = {
35
key: 'system-small-cover',
49
resolvePreset({ transformationParams }, inputFile);
51
expect(transformationParams.transforms).toStrictEqual([
63
test('Add toFormat transformation', () => {
64
const transformationParams: TransformationParams = {
65
key: 'system-small-cover',
80
const output = resolvePreset({ transformationParams }, inputFile);
82
expect(output).toStrictEqual([
91
['toFormat', 'jpg', { quality: 80 }],
95
test('Add resize transformation: cover without focal point', () => {
96
const transformationParams: TransformationParams = {
97
key: 'system-small-cover',
103
const output = resolvePreset({ transformationParams }, inputFile);
105
expect(output).toStrictEqual([
112
withoutEnlargement: undefined,
118
test('Add resize transformation: cover with centered focal point', () => {
119
const transformationParams: TransformationParams = {
120
key: 'system-small-cover',
126
const output = resolvePreset(
127
{ transformationParams },
128
{ ...inputFile, focal_point_x: inputFile.width / 2, focal_point_y: inputFile.height / 2 },
132
* The following is relevant for a centered focal point
133
* The initial aspect ratio is 16:9 so we have to resize the image to an intermediate size
134
* that fully covers our desired 1:1 aspect ratio and then crop out the final dimensions
135
* This results in: 1080/64 == 16.875 --> 1920/16.875 == 113.77 (round up) == 114 width
136
* Next we need the inner padding to get the centered crop: (114 - 64) / 2 == 25
137
* That results in the following
138
* <──────────114───────────>
139
* <──25──><───64───><──25──>
140
* ┌──────┬──────────┬──────┐
145
* └──────┴──────────┴──────┘
147
expect(output).toStrictEqual([
154
withoutEnlargement: undefined,
157
['extract', { left: 25, top: 0, width: 64, height: 64 }],
161
test('Add resize transformation: cover with negative focal point', () => {
162
const transformationParams: TransformationParams = {
163
key: 'system-small-cover',
169
const output = resolvePreset({ transformationParams }, { ...inputFile, focal_point_x: -999, focal_point_y: -999 });
172
* That should result in the following
173
* <──────────114────────────>
174
* <─────64──────><────50────>
175
* ┌─────────────┬───────────┐
179
* └─────────────┴───────────┘
181
expect(output).toStrictEqual([
188
withoutEnlargement: undefined,
191
['extract', { left: 0, top: 0, width: 64, height: 64 }],
195
test('Add resize transformation: cover with out of bounds focal point', () => {
196
const transformationParams: TransformationParams = {
197
key: 'system-small-cover',
203
const output = resolvePreset({ transformationParams }, { ...inputFile, focal_point_x: 9999, focal_point_y: -999 });
206
* That should result in the following
207
* <──────────114────────────>
208
* <────50────><─────64──────>
209
* ┌───────────┬─────────────┐
213
* └───────────┴─────────────┘
215
expect(output).toStrictEqual([
222
withoutEnlargement: undefined,
225
['extract', { left: 50, top: 0, width: 64, height: 64 }],
229
test('Add resize transformation: contain', () => {
230
const transformationParams: TransformationParams = {
231
key: 'system-small-cover',
237
const output = resolvePreset({ transformationParams }, inputFile);
239
expect(output).toStrictEqual([
246
withoutEnlargement: undefined,
252
test('Resolve auto format (fallback)', () => {
253
const transformationParams: TransformationParams = {
257
const output = resolvePreset({ transformationParams }, inputFile);
259
expect(output).toStrictEqual([['toFormat', 'jpg', { quality: undefined }]]);
262
test('Resolve auto format (with accept header)', () => {
263
const transformationParams: TransformationParams = {
267
const output = resolvePreset({ transformationParams, acceptFormat: 'avif' }, inputFile);
269
expect(output).toStrictEqual([['toFormat', 'avif', { quality: undefined }]]);
272
test('Resolve auto format (format with transparency support)', () => {
273
const transformationParams: TransformationParams = {
277
const inputFileAvif = { ...inputFile, type: 'image/avif' };
279
const output = resolvePreset({ transformationParams }, inputFileAvif);
281
expect(output).toStrictEqual([['toFormat', 'png', { quality: undefined }]]);
284
test('Resolve auto format (original type)', () => {
285
const transformationParams: TransformationParams = {
289
const inputFilePng = { ...inputFile, type: 'image/png' };
291
const output = resolvePreset({ transformationParams }, inputFilePng);
293
expect(output).toStrictEqual([['toFormat', 'png', { quality: undefined }]]);
297
describe('maybeExtractFormat', () => {
298
test('get last format', () => {
299
const inputTransformations: Transformation[] = [
300
['toFormat', 'jpg', { quality: 80 }],
301
['toFormat', 'webp', { quality: 80 }],
304
const output = maybeExtractFormat(inputTransformations);
306
expect(output).toBe('webp');
309
test('get undefined', () => {
310
const inputTransformations: Transformation[] = [];
312
const output = maybeExtractFormat(inputTransformations);
314
expect(output).toBe(undefined);