import { Component, ViewChild } from '@angular/core'; import { TestBed } from '@angular/core/testing'; import { UiButtonComponent, UiConfirmDialogComponent, UiEmptyStateComponent, UiFormFieldComponent, UiIconButtonComponent, UiPaginationComponent, UiStatusBadgeComponent, UiToastHostComponent, ToastService, } from './index'; import { isDesignSystemRouteEnabled } from '../../core/dev-only.guard'; import { devRoutes } from '../../core/dev-routes.prod'; @Component({ standalone: true, imports: [ UiButtonComponent, UiConfirmDialogComponent, UiEmptyStateComponent, UiFormFieldComponent, UiIconButtonComponent, UiPaginationComponent, UiStatusBadgeComponent, UiToastHostComponent, ], template: ` `, }) class UiTestHostComponent { @ViewChild(UiConfirmDialogComponent) dialog?: UiConfirmDialogComponent; page = 2; emptyActionCount = 0; } describe('shared UI components', () => { it('renders button loading and disabled state', async () => { await TestBed.configureTestingModule({ imports: [UiTestHostComponent] }).compileComponents(); const fixture = TestBed.createComponent(UiTestHostComponent); fixture.detectChanges(); const button = (fixture.nativeElement as HTMLElement).querySelector('ui-button button'); expect(button?.hasAttribute('disabled')).toBe(true); expect(button?.getAttribute('aria-busy')).toBe('true'); }); it('requires accessible labels for icon buttons', async () => { await TestBed.configureTestingModule({ imports: [UiTestHostComponent] }).compileComponents(); const fixture = TestBed.createComponent(UiTestHostComponent); fixture.detectChanges(); const button = (fixture.nativeElement as HTMLElement).querySelector('ui-icon-button button'); expect(button?.getAttribute('aria-label')).toBe('Eintrag loeschen'); }); it('shows form field errors and status text', async () => { await TestBed.configureTestingModule({ imports: [UiTestHostComponent] }).compileComponents(); const fixture = TestBed.createComponent(UiTestHostComponent); fixture.detectChanges(); const element = fixture.nativeElement as HTMLElement; expect(element.textContent).toContain('Name ist erforderlich'); expect(element.textContent).toContain('Deaktiviert'); }); it('opens and closes confirm dialog and restores focus', async () => { await TestBed.configureTestingModule({ imports: [UiTestHostComponent] }).compileComponents(); const fixture = TestBed.createComponent(UiTestHostComponent); fixture.detectChanges(); const trigger = (fixture.nativeElement as HTMLElement).querySelector( '#trigger', ); trigger?.focus(); const promise = fixture.componentInstance.dialog?.open({ title: 'Loeschen', description: 'Wirklich loeschen?', confirmLabel: 'Loeschen', danger: true, }); fixture.detectChanges(); await fixture.whenStable(); expect((fixture.nativeElement as HTMLElement).querySelector('[role="dialog"]')).not.toBeNull(); fixture.componentInstance.dialog?.close(true); fixture.detectChanges(); await expect(promise).resolves.toBe(true); expect(document.activeElement).toBe(trigger); }); it('shows and closes toasts', async () => { await TestBed.configureTestingModule({ imports: [UiTestHostComponent] }).compileComponents(); const fixture = TestBed.createComponent(UiTestHostComponent); const service = TestBed.inject(ToastService); const id = service.show({ tone: 'success', title: 'Gespeichert' }); fixture.detectChanges(); expect((fixture.nativeElement as HTMLElement).textContent).toContain('Gespeichert'); service.close(id); fixture.detectChanges(); expect((fixture.nativeElement as HTMLElement).textContent).not.toContain('Gespeichert'); }); it('emits empty state and pagination actions', async () => { await TestBed.configureTestingModule({ imports: [UiTestHostComponent] }).compileComponents(); const fixture = TestBed.createComponent(UiTestHostComponent); fixture.detectChanges(); const element = fixture.nativeElement as HTMLElement; element.querySelector('ui-empty-state button')?.click(); element.querySelectorAll('ui-pagination button')[0]?.click(); expect(fixture.componentInstance.emptyActionCount).toBe(1); expect(fixture.componentInstance.page).toBe(1); }); it('keeps the design system route disabled outside development mode', () => { expect(isDesignSystemRouteEnabled(false)).toBe(false); expect(devRoutes).toHaveLength(0); }); });