release: v0.19.0
Release v0.19.0. See the `## [0.19.0] — 2026-09-29` section of [CHANGELOG.md](https://github.com/ralksta/immich-folio/blob/dev/CHANGELOG.md) for the full list. Highlights: client proofing links (#683), custom content pages (#738), asset picker search (#740), concurrent-edit detection (#742), env-locked settings (#739), an accessibility baseline (#741), three security fixes with advisories (#737, #755, #759), and a pre-release quality pass (#780–#797). --------- 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> Co-authored-by: Ralf <rohlenbo79@gmail.com> Co-authored-by: Paul Thies <110185070+ImScheinox@users.noreply.github.com> Co-authored-by: lancetm714 <108419425+lancetm714@users.noreply.github.com> Co-authored-by: Lance Martin <lancetaylor95@gmail.com>
This commit is contained in:
53
lib/__tests__/asset-selection.test.ts
Normal file
53
lib/__tests__/asset-selection.test.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { canSelectMore, matchesQuery, toggleSelection } from '../admin/assetSelection';
|
||||
|
||||
describe('toggleSelection (#602)', () => {
|
||||
it('appends in click order and removes on a second toggle', () => {
|
||||
let s = toggleSelection([], 'a');
|
||||
s = toggleSelection(s, 'b');
|
||||
s = toggleSelection(s, 'c');
|
||||
expect(s).toEqual(['a', 'b', 'c']);
|
||||
expect(toggleSelection(s, 'b')).toEqual(['a', 'c']);
|
||||
});
|
||||
|
||||
it('refuses assets the caller already uses', () => {
|
||||
expect(toggleSelection(['a'], 'x', { disabled: new Set(['x']) })).toEqual(['a']);
|
||||
});
|
||||
|
||||
it('stops at max but still lets you deselect', () => {
|
||||
const full = ['a', 'b'];
|
||||
expect(toggleSelection(full, 'c', { max: 2 })).toEqual(['a', 'b']);
|
||||
expect(toggleSelection(full, 'a', { max: 2 })).toEqual(['b']);
|
||||
});
|
||||
|
||||
it('replaces the pick when max is 1', () => {
|
||||
expect(toggleSelection(['a'], 'b', { max: 1 })).toEqual(['b']);
|
||||
});
|
||||
|
||||
it('does not mutate its input', () => {
|
||||
const s = ['a'];
|
||||
toggleSelection(s, 'b');
|
||||
expect(s).toEqual(['a']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('canSelectMore', () => {
|
||||
it('is unlimited without max, bounded with it, and always open for a single slot', () => {
|
||||
expect(canSelectMore(['a', 'b', 'c'])).toBe(true);
|
||||
expect(canSelectMore(['a'], 2)).toBe(true);
|
||||
expect(canSelectMore(['a', 'b'], 2)).toBe(false);
|
||||
expect(canSelectMore(['a'], 1)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('matchesQuery', () => {
|
||||
const asset = { originalFileName: 'IMG_4021.HEIC' };
|
||||
it('matches a case-insensitive filename fragment', () => {
|
||||
expect(matchesQuery(asset, 'img_40')).toBe(true);
|
||||
expect(matchesQuery(asset, ' 4021 ')).toBe(true);
|
||||
expect(matchesQuery(asset, 'DSC')).toBe(false);
|
||||
});
|
||||
it('matches everything for an empty query', () => {
|
||||
expect(matchesQuery(asset, ' ')).toBe(true);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user