fix(quick-261005-d5d): Kalender-Test bricht bei unerreichbarem Exchange nach 15 s ab
EWS-Aufrufe ueber httpntlm bekommen eine eigene 15-s-Zeitgrenze; httpreqs timeout greift waehrend des Verbindungsaufbaus nicht (gemessen 134 s). Netzfehler liefern im Test den Schluessel 'unreachable', das Formular meldet 'nicht erreichbar' statt 'Zugangsdaten pruefen'. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { cleanup, fireEvent, render, screen } from '@testing-library/react';
|
||||
import { testSourceConfig } from '@/lib/calendar-api';
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||
import de from '@/messages/de.json';
|
||||
import { CalendarSourceForm } from './calendar-source-form';
|
||||
@@ -111,3 +112,29 @@ describe('CalendarSourceForm — URL-Platzhalter je Typ + EWS-Hinweis (quick-260
|
||||
expect(fehler.compareDocumentPosition(hinweis) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('CalendarSourceForm — Verbindungstest: nicht erreichbar (quick-261005)', () => {
|
||||
function fillAndTest() {
|
||||
const { urlInput, typeSelect } = renderForm();
|
||||
fireEvent.change(screen.getByLabelText(/^Name/), { target: { value: 'Firma' } });
|
||||
fireEvent.change(typeSelect, { target: { value: 'exchange' } });
|
||||
fireEvent.change(urlInput, { target: { value: 'https://owa.example.invalid/EWS/Exchange.asmx' } });
|
||||
fireEvent.click(screen.getByTestId('source-form-test'));
|
||||
}
|
||||
|
||||
it('Schluessel "unreachable" zeigt die Nicht-erreichbar-Meldung statt „Zugangsdaten pruefen“', async () => {
|
||||
vi.mocked(testSourceConfig).mockResolvedValueOnce({ success: false, error: 'unreachable' });
|
||||
fillAndTest();
|
||||
|
||||
expect(await screen.findByText(t.formTestUnreachable)).toBeInTheDocument();
|
||||
expect(screen.queryByText(t.formTestFailed)).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('sonstiger Fehlschlag zeigt weiter die bisherige Meldung', async () => {
|
||||
vi.mocked(testSourceConfig).mockResolvedValueOnce({ success: false, error: 'Connection failed' });
|
||||
fillAndTest();
|
||||
|
||||
expect(await screen.findByText(t.formTestFailed)).toBeInTheDocument();
|
||||
expect(screen.queryByText(t.formTestUnreachable)).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -58,6 +58,16 @@ interface CalendarSourceFormProps {
|
||||
* (CalDAV / ICS / Exchange Graph / Exchange EWS), and Exchange EWS shows a
|
||||
* hint below the field explaining that the full EWS address is required.
|
||||
*/
|
||||
/**
|
||||
* quick-261005: „nicht erreichbar“ (Schluessel `unreachable` vom Server)
|
||||
* getrennt von „Anmeldung fehlgeschlagen“ — sonst schickt die Meldung den
|
||||
* Benutzer zu den Zugangsdaten, obwohl das Netz fehlt.
|
||||
*/
|
||||
function testOutcome(result: { success: boolean; error?: string }): 'success' | 'error' | 'unreachable' {
|
||||
if (result.success) return 'success';
|
||||
return result.error === 'unreachable' ? 'unreachable' : 'error';
|
||||
}
|
||||
|
||||
export function CalendarSourceForm({
|
||||
onSave,
|
||||
onCancel,
|
||||
@@ -75,7 +85,9 @@ export function CalendarSourceForm({
|
||||
initialValues?.exchangeMode ?? 'graph',
|
||||
);
|
||||
const [domain, setDomain] = useState(initialValues?.domain ?? '');
|
||||
const [testStatus, setTestStatus] = useState<'idle' | 'loading' | 'success' | 'error'>('idle');
|
||||
const [testStatus, setTestStatus] = useState<
|
||||
'idle' | 'loading' | 'success' | 'error' | 'unreachable'
|
||||
>('idle');
|
||||
const [color, setColor] = useState(
|
||||
initialValues?.color ?? SOURCE_COLOR_PALETTE[0].value,
|
||||
);
|
||||
@@ -127,7 +139,7 @@ export function CalendarSourceForm({
|
||||
// In edit mode with no new password entered, use saved credentials via the source endpoint
|
||||
if (initialValues?.id && !password) {
|
||||
const result = await testSource(initialValues.id);
|
||||
setTestStatus(result.success ? 'success' : 'error');
|
||||
setTestStatus(testOutcome(result));
|
||||
return;
|
||||
}
|
||||
const result = await testSourceConfig({
|
||||
@@ -138,7 +150,7 @@ export function CalendarSourceForm({
|
||||
exchangeMode: isExchange ? exchangeMode : undefined,
|
||||
domain: isExchange && domain.trim() ? domain.trim() : undefined,
|
||||
});
|
||||
setTestStatus(result.success ? 'success' : 'error');
|
||||
setTestStatus(testOutcome(result));
|
||||
} catch {
|
||||
setTestStatus('error');
|
||||
}
|
||||
@@ -382,6 +394,9 @@ export function CalendarSourceForm({
|
||||
{testStatus === 'error' && (
|
||||
<p className="text-sm text-destructive">{t('calendar.formTestFailed')}</p>
|
||||
)}
|
||||
{testStatus === 'unreachable' && (
|
||||
<p className="text-sm text-destructive">{t('calendar.formTestUnreachable')}</p>
|
||||
)}
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ export async function testSourceConfig(config: {
|
||||
*/
|
||||
export async function testSource(
|
||||
id: string,
|
||||
): Promise<{ success: boolean }> {
|
||||
): Promise<{ success: boolean; error?: string }> {
|
||||
const res = await fetch(`${API_URL}/calendar/sources/${id}/test`, {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
|
||||
@@ -332,6 +332,7 @@
|
||||
"formTesting": "Verbindung wird geprüft …",
|
||||
"formTestSuccess": "Verbindung erfolgreich.",
|
||||
"formTestFailed": "Verbindung fehlgeschlagen. Bitte prüfen Sie Adresse und Zugangsdaten.",
|
||||
"formTestUnreachable": "Der Kalender-Server ist nicht erreichbar. Bitte prüfen Sie die Adresse und ob der Server vom Tessera-Server aus erreichbar ist.",
|
||||
"formCancel": "Abbrechen",
|
||||
"formUrlErrorHttps": "Die Adresse muss mit https:// beginnen.",
|
||||
"formUrlErrorInvalid": "Bitte geben Sie eine gültige Adresse ein.",
|
||||
|
||||
@@ -332,6 +332,7 @@
|
||||
"formTesting": "Checking connection …",
|
||||
"formTestSuccess": "Connection successful.",
|
||||
"formTestFailed": "Connection failed. Please check the address and credentials.",
|
||||
"formTestUnreachable": "The calendar server is not reachable. Please check the address and whether the server can be reached from the Tessera server.",
|
||||
"formCancel": "Cancel",
|
||||
"formUrlErrorHttps": "The address must start with https://.",
|
||||
"formUrlErrorInvalid": "Please enter a valid address.",
|
||||
|
||||
Reference in New Issue
Block a user