Files
tessera-ctl/apps/web/src/components/nextcloud-status/cloud-form-errors.test.ts
T
schalli c30a82ec0f feat(nextcloud-status): Cloud-Formular zeigt nur deutsche Meldungen, Bildadresse auch per http (j9f)
- Vorabpruefung im Browser, API-Kennungen werden zu de/en-Texten
- Beschriftung Bildadresse mit neuem Hinweis zu http und https

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 14:08:21 +02:00

86 lines
3.0 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { NextcloudFormError } from '@/lib/nextcloud-status-api';
import {
CLOUD_FORM_ERROR_CODES,
cloudFormErrorKey,
isAllowedLogoFileType,
validateCloudForm,
} from './cloud-form-errors';
const OK = {
customerName: 'Kunde',
baseUrl: 'https://cloud.example.de',
logoMode: 'none' as const,
logoUrl: '',
};
describe('validateCloudForm', () => {
it('gueltige Eingaben -> null', () => {
expect(validateCloudForm(OK)).toBeNull();
});
it('Name: leer und zu lang', () => {
expect(validateCloudForm({ ...OK, customerName: ' ' })).toBe('customerNameRequired');
expect(validateCloudForm({ ...OK, customerName: 'x'.repeat(121) })).toBe('customerNameTooLong');
});
it('Adresse: leer, ohne Schema, falsches Schema', () => {
expect(validateCloudForm({ ...OK, baseUrl: '' })).toBe('baseUrlRequired');
expect(validateCloudForm({ ...OK, baseUrl: 'cloud.example.de' })).toBe('baseUrlInvalid');
expect(validateCloudForm({ ...OK, baseUrl: 'ftp://x' })).toBe('baseUrlInvalid');
});
it('Bildadresse nur im Modus url geprueft', () => {
for (const logoUrl of ['ftp://x', 'kein link', 'http://u:p@a.de/x.png']) {
expect(validateCloudForm({ ...OK, logoMode: 'url', logoUrl })).toBe('logoUrlInvalid');
}
for (const logoUrl of ['http://logo.example.de/a.png', 'https://logo.example.de/a.png', '']) {
expect(validateCloudForm({ ...OK, logoMode: 'url', logoUrl })).toBeNull();
}
expect(validateCloudForm({ ...OK, logoMode: 'none', logoUrl: 'ftp://x' })).toBeNull();
expect(validateCloudForm({ ...OK, logoMode: 'upload', logoUrl: 'ftp://x' })).toBeNull();
});
});
describe('isAllowedLogoFileType', () => {
it('nur PNG, JPEG, GIF, WebP', () => {
for (const t of ['image/png', 'image/jpeg', 'image/gif', 'image/webp']) {
expect(isAllowedLogoFileType(t)).toBe(true);
}
expect(isAllowedLogoFileType('image/svg+xml')).toBe(false);
expect(isAllowedLogoFileType('')).toBe(false);
});
});
describe('cloudFormErrorKey', () => {
it('bekannte Kennungen -> errors.<code>', () => {
for (const code of CLOUD_FORM_ERROR_CODES) {
expect(cloudFormErrorKey(new NextcloudFormError(400, code, 'x'), 'saveError')).toBe(
`errors.${code}`,
);
}
});
it('413 und 404 ohne Kennung', () => {
expect(
cloudFormErrorKey(new NextcloudFormError(413, null, 'File too large'), 'saveError'),
).toBe('errors.logoFileTooLarge');
expect(cloudFormErrorKey(new NextcloudFormError(404, null, 'Not Found'), 'deleteError')).toBe(
'errors.notFound',
);
});
it('unbekannte Kennung, englischer Text oder einfacher Fehler -> allgemeiner Text', () => {
expect(cloudFormErrorKey(new NextcloudFormError(400, 'whatever', 'x'), 'saveError')).toBe(
'saveError',
);
expect(
cloudFormErrorKey(
new NextcloudFormError(400, null, 'logoUrl must be a URL address'),
'saveError',
),
).toBe('saveError');
expect(cloudFormErrorKey(new Error('boom'), 'deleteError')).toBe('deleteError');
});
});