style: format frontend, docs and skills with prettier; add .prettierignore
One-time prettier --write so the new format:check CI gate starts green. .prettierignore excludes generated (api-client.ts, documentation.json), vendored (public/cibg-huisstijl), and backend (dotnet format owns it). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -28,28 +28,50 @@ const stateWith = (categories: DocumentCategory[], over: Partial<UploadState> =
|
||||
reduceUpload({ ...initialUpload, ...over }, { type: 'CategoriesLoaded', categories });
|
||||
|
||||
const select = (s: UploadState, categoryId: string, localId: string): UploadState =>
|
||||
reduceUpload(s, { type: 'FileSelected', categoryId, localId, fileName: `${localId}.pdf`, fileSizeMb: 1 });
|
||||
reduceUpload(s, {
|
||||
type: 'FileSelected',
|
||||
categoryId,
|
||||
localId,
|
||||
fileName: `${localId}.pdf`,
|
||||
fileSizeMb: 1,
|
||||
});
|
||||
|
||||
const get = (s: UploadState, localId: string): Upload | undefined => s.uploads.find((u) => u.localId === localId);
|
||||
const get = (s: UploadState, localId: string): Upload | undefined =>
|
||||
s.uploads.find((u) => u.localId === localId);
|
||||
|
||||
describe('CategoriesLoaded', () => {
|
||||
it('defaults every category to digital without clobbering existing choices', () => {
|
||||
const s0 = stateWith([cat({ categoryId: 'a' })], { deliveryChannel: { a: 'post' } });
|
||||
expect(s0.deliveryChannel['a']).toBe('post');
|
||||
const s1 = reduceUpload(s0, { type: 'CategoriesLoaded', categories: [cat({ categoryId: 'a' }), cat({ categoryId: 'b' })] });
|
||||
const s1 = reduceUpload(s0, {
|
||||
type: 'CategoriesLoaded',
|
||||
categories: [cat({ categoryId: 'a' }), cat({ categoryId: 'b' })],
|
||||
});
|
||||
expect(s1.deliveryChannel).toEqual({ a: 'post', b: 'digital' });
|
||||
});
|
||||
|
||||
it('clears a prior categoriesError', () => {
|
||||
const s = reduceUpload({ ...initialUpload, categoriesError: 'boom' }, { type: 'CategoriesLoaded', categories: [] });
|
||||
const s = reduceUpload(
|
||||
{ ...initialUpload, categoriesError: 'boom' },
|
||||
{ type: 'CategoriesLoaded', categories: [] },
|
||||
);
|
||||
expect(s.categoriesError).toBeUndefined();
|
||||
});
|
||||
|
||||
it('drops uploads + channel choices for categories that disappear', () => {
|
||||
const s0 = select(stateWith([cat({ categoryId: 'diploma' }), cat({ categoryId: 'id' })], { deliveryChannel: { id: 'post' } }), 'diploma', 'u1');
|
||||
const s0 = select(
|
||||
stateWith([cat({ categoryId: 'diploma' }), cat({ categoryId: 'id' })], {
|
||||
deliveryChannel: { id: 'post' },
|
||||
}),
|
||||
'diploma',
|
||||
'u1',
|
||||
);
|
||||
expect(get(s0, 'u1')).toBeDefined();
|
||||
// Reload with the diploma category gone (e.g. DUO chosen).
|
||||
const s1 = reduceUpload(s0, { type: 'CategoriesLoaded', categories: [cat({ categoryId: 'id' })] });
|
||||
const s1 = reduceUpload(s0, {
|
||||
type: 'CategoriesLoaded',
|
||||
categories: [cat({ categoryId: 'id' })],
|
||||
});
|
||||
expect(get(s1, 'u1')).toBeUndefined();
|
||||
expect(s1.deliveryChannel).toEqual({ id: 'post' });
|
||||
});
|
||||
@@ -57,10 +79,15 @@ describe('CategoriesLoaded', () => {
|
||||
|
||||
describe('CategoriesLoadFailed / BackgroundSyncAvailability', () => {
|
||||
it('records the error', () => {
|
||||
expect(reduceUpload(initialUpload, { type: 'CategoriesLoadFailed', reason: 'boom' }).categoriesError).toBe('boom');
|
||||
expect(
|
||||
reduceUpload(initialUpload, { type: 'CategoriesLoadFailed', reason: 'boom' }).categoriesError,
|
||||
).toBe('boom');
|
||||
});
|
||||
it('flips background sync availability', () => {
|
||||
expect(reduceUpload(initialUpload, { type: 'BackgroundSyncAvailability', available: true }).backgroundSyncAvailable).toBe(true);
|
||||
expect(
|
||||
reduceUpload(initialUpload, { type: 'BackgroundSyncAvailability', available: true })
|
||||
.backgroundSyncAvailable,
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -96,7 +123,11 @@ describe('FileSelected', () => {
|
||||
|
||||
describe('FileRejected', () => {
|
||||
it('stores a per-category message', () => {
|
||||
const s = reduceUpload(stateWith([cat()]), { type: 'FileRejected', categoryId: 'diploma', reason: 'size' });
|
||||
const s = reduceUpload(stateWith([cat()]), {
|
||||
type: 'FileRejected',
|
||||
categoryId: 'diploma',
|
||||
reason: 'size',
|
||||
});
|
||||
expect(s.rejections['diploma']).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -134,12 +165,20 @@ describe('delete flow (optimistic, revertible)', () => {
|
||||
};
|
||||
|
||||
it('UploadDeleteRequested keeps the documentId for revert', () => {
|
||||
const s = reduceUpload(completed(), { type: 'UploadDeleteRequested', localId: 'u1', documentId: 'doc1' });
|
||||
const s = reduceUpload(completed(), {
|
||||
type: 'UploadDeleteRequested',
|
||||
localId: 'u1',
|
||||
documentId: 'doc1',
|
||||
});
|
||||
expect(get(s, 'u1')?.status).toEqual({ type: 'deleting', documentId: 'doc1' });
|
||||
});
|
||||
|
||||
it('UploadDeleteComplete removes the upload', () => {
|
||||
let s = reduceUpload(completed(), { type: 'UploadDeleteRequested', localId: 'u1', documentId: 'doc1' });
|
||||
let s = reduceUpload(completed(), {
|
||||
type: 'UploadDeleteRequested',
|
||||
localId: 'u1',
|
||||
documentId: 'doc1',
|
||||
});
|
||||
s = reduceUpload(s, { type: 'UploadDeleteComplete', localId: 'u1' });
|
||||
expect(s.uploads).toHaveLength(0);
|
||||
});
|
||||
@@ -161,13 +200,21 @@ describe('DeliveryChannelChanged', () => {
|
||||
|
||||
it('rejects post for a category that does not allow it', () => {
|
||||
const s = stateWith([cat({ allowPostDelivery: false })]);
|
||||
const next = reduceUpload(s, { type: 'DeliveryChannelChanged', categoryId: 'diploma', channel: 'post' });
|
||||
const next = reduceUpload(s, {
|
||||
type: 'DeliveryChannelChanged',
|
||||
categoryId: 'diploma',
|
||||
channel: 'post',
|
||||
});
|
||||
expect(next.deliveryChannel['diploma']).toBe('digital');
|
||||
});
|
||||
|
||||
it('switching back to digital starts clean', () => {
|
||||
let s = stateWith([cat()], { deliveryChannel: { diploma: 'post' } });
|
||||
s = reduceUpload(s, { type: 'DeliveryChannelChanged', categoryId: 'diploma', channel: 'digital' });
|
||||
s = reduceUpload(s, {
|
||||
type: 'DeliveryChannelChanged',
|
||||
categoryId: 'diploma',
|
||||
channel: 'digital',
|
||||
});
|
||||
expect(s.deliveryChannel['diploma']).toBe('digital');
|
||||
expect(s.uploads).toHaveLength(0);
|
||||
});
|
||||
@@ -203,7 +250,10 @@ describe('satisfaction helpers', () => {
|
||||
});
|
||||
|
||||
it('requiredCategoriesSatisfied ignores optional categories', () => {
|
||||
const s = stateWith([cat({ categoryId: 'req', required: true }), cat({ categoryId: 'opt', required: false })]);
|
||||
const s = stateWith([
|
||||
cat({ categoryId: 'req', required: true }),
|
||||
cat({ categoryId: 'opt', required: false }),
|
||||
]);
|
||||
expect(requiredCategoriesSatisfied(s)).toBe(false);
|
||||
const s2 = select(s, 'req', 'u1');
|
||||
expect(requiredCategoriesSatisfied(s2)).toBe(true);
|
||||
@@ -212,7 +262,9 @@ describe('satisfaction helpers', () => {
|
||||
|
||||
describe('deliveryRefs', () => {
|
||||
it('emits documentId for completed digital uploads and channel for post', () => {
|
||||
let s = stateWith([cat({ categoryId: 'a' }), cat({ categoryId: 'b' })], { deliveryChannel: { b: 'post' } });
|
||||
let s = stateWith([cat({ categoryId: 'a' }), cat({ categoryId: 'b' })], {
|
||||
deliveryChannel: { b: 'post' },
|
||||
});
|
||||
s = select(s, 'a', 'u1');
|
||||
s = reduceUpload(s, { type: 'UploadComplete', localId: 'u1', documentId: 'doc1' });
|
||||
expect(deliveryRefs(s)).toEqual([
|
||||
@@ -229,16 +281,27 @@ describe('deliveryRefs', () => {
|
||||
|
||||
describe('rejectReason', () => {
|
||||
it('rejects a disallowed type', () => {
|
||||
expect(rejectReason(cat({ acceptedTypes: ['application/pdf'] }), { type: 'image/png', sizeMb: 1 })).toBe('type');
|
||||
expect(
|
||||
rejectReason(cat({ acceptedTypes: ['application/pdf'] }), { type: 'image/png', sizeMb: 1 }),
|
||||
).toBe('type');
|
||||
});
|
||||
it('rejects an oversized file', () => {
|
||||
expect(rejectReason(cat({ maxSizeMb: 10 }), { type: 'application/pdf', sizeMb: 11 })).toBe('size');
|
||||
expect(rejectReason(cat({ maxSizeMb: 10 }), { type: 'application/pdf', sizeMb: 11 })).toBe(
|
||||
'size',
|
||||
);
|
||||
});
|
||||
it('accepts a valid file', () => {
|
||||
expect(rejectReason(cat({ acceptedTypes: ['application/pdf'], maxSizeMb: 10 }), { type: 'application/pdf', sizeMb: 1 })).toBeNull();
|
||||
expect(
|
||||
rejectReason(cat({ acceptedTypes: ['application/pdf'], maxSizeMb: 10 }), {
|
||||
type: 'application/pdf',
|
||||
sizeMb: 1,
|
||||
}),
|
||||
).toBeNull();
|
||||
});
|
||||
it('allows any type when the category lists none', () => {
|
||||
expect(rejectReason(cat({ acceptedTypes: [], maxSizeMb: 10 }), { type: 'image/png', sizeMb: 1 })).toBeNull();
|
||||
expect(
|
||||
rejectReason(cat({ acceptedTypes: [], maxSizeMb: 10 }), { type: 'image/png', sizeMb: 1 }),
|
||||
).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -249,6 +312,10 @@ describe('inFlight', () => {
|
||||
s = reduceUpload(s, { type: 'UploadProgress', localId: 'u2', progressPct: 10 });
|
||||
s = select(s, 'diploma', 'u3');
|
||||
s = reduceUpload(s, { type: 'UploadComplete', localId: 'u3', documentId: 'doc3' });
|
||||
expect(inFlight(s).map((u) => u.localId).sort()).toEqual(['u1', 'u2']);
|
||||
expect(
|
||||
inFlight(s)
|
||||
.map((u) => u.localId)
|
||||
.sort(),
|
||||
).toEqual(['u1', 'u2']);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user