release: v0.13.0 (#535)
Twenty-nine commits since v0.12.0. See CHANGELOG.md for the full list and the upgrade notes. Ten additions — the SEO package (site URL, robots.txt, sitemap.xml, JSON-LD), slideshow mode, opt-in original downloads, copy-link, previous/next album navigation, alt text from the Immich description, per-album location precision, the update notice, a Help tab, and a subpage cover grid separate from its photo grid. Two fixes: CJK album slugs, and the lightbox control bar. Photo of the Day (#476) was built on `dev` and reverted as not planned; it never appears in a release. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01DmsHVRL9yQvckUB1ZpVWre --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: ralksta <ralksta@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -17,6 +17,7 @@ import {
|
||||
assetPlaceholder,
|
||||
assetExifSummary,
|
||||
assetAspectRatio,
|
||||
assetCaption,
|
||||
} from '@/lib/urls';
|
||||
|
||||
describe('imageUrl', () => {
|
||||
@@ -168,3 +169,58 @@ describe('assetAspectRatio', () => {
|
||||
).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('assetCaption', () => {
|
||||
/** An asset carrying nothing but the description under test. */
|
||||
const withDescription = (description: string | null) => ({
|
||||
exifInfo: {
|
||||
make: null,
|
||||
model: null,
|
||||
lensModel: null,
|
||||
focalLength: null,
|
||||
fNumber: null,
|
||||
exposureTime: null,
|
||||
iso: null,
|
||||
exifImageWidth: null,
|
||||
exifImageHeight: null,
|
||||
latitude: null,
|
||||
longitude: null,
|
||||
city: null,
|
||||
state: null,
|
||||
country: null,
|
||||
dateTimeOriginal: null,
|
||||
description,
|
||||
},
|
||||
});
|
||||
|
||||
it('returns the description when captions are shown', () => {
|
||||
expect(assetCaption(withDescription('A gull over the harbour'), true)).toBe(
|
||||
'A gull over the harbour',
|
||||
);
|
||||
});
|
||||
|
||||
it('trims surrounding whitespace', () => {
|
||||
expect(assetCaption(withDescription(' Low tide\n'), true)).toBe('Low tide');
|
||||
});
|
||||
|
||||
it.each([
|
||||
['null', null],
|
||||
['empty', ''],
|
||||
['whitespace only', ' \n\t '],
|
||||
])('returns undefined for a %s description, leaving alt=""', (_label, value) => {
|
||||
expect(assetCaption(withDescription(value), true)).toBeUndefined();
|
||||
});
|
||||
|
||||
it('returns undefined when the asset has no exifInfo at all', () => {
|
||||
expect(assetCaption({ exifInfo: undefined }, true)).toBeUndefined();
|
||||
});
|
||||
|
||||
/**
|
||||
* The point of #506: the description is the one field that can hold private
|
||||
* notes. Alt text publishes it as surely as a visible caption does, so the
|
||||
* caption switch has to gate it too.
|
||||
*/
|
||||
it('withholds the description when captions are switched off', () => {
|
||||
expect(assetCaption(withDescription('Client hates this crop'), false)).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user