diff --git a/apps/web/src/components/settings/calendar-settings-panel.test.tsx b/apps/web/src/components/settings/calendar-settings-panel.test.tsx
index 8ca7c8a..cbaa822 100644
--- a/apps/web/src/components/settings/calendar-settings-panel.test.tsx
+++ b/apps/web/src/components/settings/calendar-settings-panel.test.tsx
@@ -13,6 +13,9 @@ vi.mock('next-intl', () => ({
'calendar.deleteDialogLabel': 'Löschen bestätigen',
'calendar.saveError': 'Fehler beim Speichern',
'calendar.saveSuccess': 'Gespeichert',
+ 'calendar.connectionSuccess': 'Verbindung erfolgreich',
+ 'calendar.syncErrorLabel': 'Synchronisierungsfehler',
+ 'calendar.connectionFailedLabel': 'Verbindung fehlgeschlagen',
},
settings: {
sourceDeleteCta: 'Quelle löschen',
@@ -129,3 +132,15 @@ describe('CalendarSettingsPanel — delete confirmation dialog (D-01, T-JT4-04)'
expect(screen.getByRole('alertdialog')).toBeInTheDocument();
});
});
+
+describe('CalendarSettingsPanel — Statussymbole tragen role="img" (D-03)', () => {
+ it('der Sync-Fehler-Indikator ist per Rolle+Name ansprechbar, statt sein aria-label an einem rollenlosen zu verschwenden', async () => {
+ vi.mocked(fetchSources).mockResolvedValue([
+ { ...baseSource, lastSyncError: 'Verbindung abgelehnt' },
+ ]);
+ render();
+ await screen.findByText('Firmenkalender');
+
+ expect(screen.getByRole('img', { name: 'Synchronisierungsfehler' })).toBeInTheDocument();
+ });
+});
diff --git a/apps/web/src/components/settings/calendar-settings-panel.tsx b/apps/web/src/components/settings/calendar-settings-panel.tsx
index 42d0e98..1b7daff 100644
--- a/apps/web/src/components/settings/calendar-settings-panel.tsx
+++ b/apps/web/src/components/settings/calendar-settings-panel.tsx
@@ -154,12 +154,17 @@ export function CalendarSettingsPanel() {
{TYPE_LABELS[source.type] || source.type}
- {/* Connection status indicator */}
+ {/* Connection status indicator. role="img" (D-03): die
+ Beschriftung ist der EINZIGE Text dieser Symbole (das
+