Skip to content

Commit

Permalink
feat(asset-config): allow reference field configs & configs by naming…
Browse files Browse the repository at this point in the history
… convention (#51)

* feat(asset-config): allow reference field configs & configs by naming convention

* fix(asset-config): keep backwards compatibility

* refactor(asset-config): better readable tests

* docs(asset-config): updates example

* Update packages/cssg-plugin-assets/README.md

Co-authored-by: Peter Schewe <peter.klostermann@jvm.de>

* Update README.md

* Update README.md

Co-authored-by: Peter Schewe <peter.klostermann@jvm.de>
  • Loading branch information
bezoerb and peterschewe authored Sep 10, 2022
1 parent efb3dd5 commit 9fc0275
Show file tree
Hide file tree
Showing 5 changed files with 328 additions and 56 deletions.
38 changes: 25 additions & 13 deletions packages/cssg-plugin-assets/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,31 @@ You can specify global defaults for ratios and focus areas, defaults per content
// Use center as default focus area
default: 'center',
contentTypes: {
'media-content-type': {
// Use center as default focus area for media-content-type
content_type_id: {
// Use top as default focus area for content_type_id
default: 'top',
// create overwrites per field
// Create overwrites per field
fields: {
// Use the largest face detected as focus area for fieldId in media-content-type
fieldId: 'face',
// Use the largest face detected as focus area for field_id in content_type_id
field_id: 'face',
// Use the value from field custom_focus_area in content_type_id
alt_field_id: 'field:custom_focus_area'
}
}
}
},
ratios: {
// square and landscape derivatives when nothing else is specified. The 'original' ratio is always available.
// Square and landscape derivatives when nothing else is specified. The 'original' ratio is always available.
default: {square: 1/1, landscape: 16/9},
// Define overwrites per content-type
contentTypes: {
'media-content-type': {
// default ratio for media-content-type should be rectangle ()
content_type_id: {
// Default ratio forcontent_type_id should be rectangle ()
default: {rectangle: 4/3},
// create overwrites per field
// Create overwrites per field
fields: {
// fieldId in this contentType is generated with original and square derivatives
fieldId: {square: 1/1},
// field_id in content_type_id is generated with original and square derivatives
field_id: {square: 1/1},
}
}
}
Expand Down Expand Up @@ -111,7 +113,6 @@ plugins: [

## Options


| Name | Type | Default | Description |
| -------------------- | ---------- | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| download | `boolean` | `false` | Download assets to bypass the contentful cdn on your production site. |
Expand Down Expand Up @@ -143,7 +144,18 @@ plugins: [
cacheFolder: '.cache',
extraTypes: ['image/webp'],
ratios: { default: { square: 1 / 1, portrait: 3 / 4, landscape: 16 / 9 } },
focusAreas: { default: 'face' },
focusAreas: {
default: 'face',
contentTypes: {
c_media: {
default: 'center',
fields: {
mobile_src: 'field:mobile_focus_area',
desktop_src: 'field:desktop_focus_area',
},
}
},
},
},
},
];
Expand Down
223 changes: 223 additions & 0 deletions packages/cssg-plugin-assets/src/helper/image.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
import { Asset } from '@jungvonmatt/contentful-ssg';
import { mapAssetLink } from '@jungvonmatt/contentful-ssg/mapper/map-reference-field';
import { localizeEntry } from '@jungvonmatt/contentful-ssg/tasks/localize';
import {
getContent,
getRuntimeContext,
getTransformContext,
} from '@jungvonmatt/contentful-ssg/__test__/mock';

import { EntryConfig, FocusAreaConfig, PluginConfig } from '../types.js';

import { getRatioConfig, getFocusArea } from './image.js';

/**
* Get transformcontext with a mock entry andf fieldId media
* @param fields fields available in entry
* @returns
*/
const getTransformContextMock = async (fields: Record<string, string> = {}) => {
const content = await getContent();
const runtimeContext = getRuntimeContext();
const entry = localizeEntry(content.entry, 'en-US', runtimeContext.data);

entry.sys.contentType.sys.id = 'ct';

const transformContext = getTransformContext({
entry: { ...entry, fields },
fieldId: 'media',
});

return transformContext;
};

const getTestFocusArea = async (
test:
| {
fields?: Record<string, string>;
config?: FocusAreaConfig;
}
| undefined
) => {
const transformContext = await getTransformContextMock(test?.fields ?? {});
return getFocusArea(transformContext, test?.config ?? {});
};

describe('getFocusArea', () => {
test('default', async () => {
const focusArea = await getTestFocusArea({
config: {},
fields: {},
});

expect(focusArea).toEqual('center');
});

test('backwards compatibility', async () => {
const focusArea = await getTestFocusArea({
config: {},
fields: { focus_area: 'face' },
});

expect(focusArea).toEqual('face');
});

test('media_focus_area field', async () => {
const focusArea = await getTestFocusArea({
config: {},
fields: { media_focus_area: 'top' },
});

expect(focusArea).toEqual('top');
});

test('configured field - default', async () => {
const focusArea = await getTestFocusArea({
config: { default: 'field:reference' },
fields: { reference: 'bottom' },
});

expect(focusArea).toEqual('bottom');
});

test('configured field - content-type default', async () => {
const focusArea = await getTestFocusArea({
config: { default: 'field:a', contentTypes: { ct: { default: 'field:b' } } },
fields: { a: 'bottom', b: 'right' },
});

expect(focusArea).toEqual('right');
});

test('configured field - content-type fieldId', async () => {
const focusArea = await getTestFocusArea({
config: {
default: 'field:a',
contentTypes: { ct: { default: 'field:b', fields: { media: 'field:c' } } },
},
fields: { a: 'bottom', b: 'right', c: 'top_right' },
});

expect(focusArea).toEqual('top_right');
});

test('field by naming convention', async () => {
const focusArea = await getTestFocusArea({
config: {
default: 'field:a',
contentTypes: { ct: { default: 'field:b', fields: { media: 'top' } } },
},
fields: { a: 'bottom', b: 'right', media_focus_area: 'top_left' },
});

expect(focusArea).toEqual('top_left');
});

test('config default', async () => {
const focusArea = await getTestFocusArea({
config: { default: 'bottom' },
fields: {},
});

expect(focusArea).toEqual('bottom');
});

test('config content-type default', async () => {
const focusArea = await getTestFocusArea({
config: { default: 'top_left', contentTypes: { ct: { default: 'top_right' } } },
fields: {},
});

expect(focusArea).toEqual('top_right');
});

test('config field', async () => {
const focusArea = await getTestFocusArea({
config: {
default: 'top_left',
contentTypes: { ct: { default: 'top_right', fields: { media: 'top' } } },
},
fields: {},
});

expect(focusArea).toEqual('top');
});

test('config field fallback ct', async () => {
const focusArea = await getTestFocusArea({
config: {
default: 'top_left',
contentTypes: { ct: { default: 'top_right', fields: { media: 'field:b' } } },
},
fields: {},
});

expect(focusArea).toEqual('top_right');
});

test('config field fallback default', async () => {
const focusArea = await getTestFocusArea({
config: {
default: 'top_left',
contentTypes: { ct: { default: 'field:a', fields: { media: 'field:b' } } },
},
fields: {},
});

expect(focusArea).toEqual('top_left');
});

test('config field fallback center', async () => {
const focusArea = await getTestFocusArea({
config: {
contentTypes: { ct: { default: 'field:a', fields: { media: 'field:b' } } },
},
fields: {},
});

expect(focusArea).toEqual('center');
});
});

describe('getRatioConfig', () => {
test('empty', async () => {
const transformContext = await getTransformContextMock();
const c = undefined;
const ratios = getRatioConfig(transformContext, c);

expect(ratios).toEqual({});
});

test('default', async () => {
const transformContext = await getTransformContextMock();
const ratios = getRatioConfig(transformContext, {
default: { square: 1 },
});

expect(ratios).toEqual({ square: 1 });
});

test('ct default', async () => {
const transformContext = await getTransformContextMock();
const ratios = getRatioConfig(transformContext, {
default: { square: 1 },
contentTypes: {
ct: { default: { rect: 4 / 3 } },
},
});

expect(ratios).toEqual({ rect: 4 / 3 });
});

test('field default', async () => {
const transformContext = await getTransformContextMock();
const ratios = getRatioConfig(transformContext, {
default: { square: 1 },
contentTypes: {
ct: { default: { rect: 4 / 3 }, fields: { media: { portrait: 2 / 3 } } },
},
});

expect(ratios).toEqual({ portrait: 2 / 3 });
});
});
Loading

0 comments on commit 9fc0275

Please sign in to comment.