diff --git a/frontend/src/lib/components/DistributionBar.svelte b/frontend/src/lib/components/DistributionBar.svelte new file mode 100644 index 00000000..d0e52292 --- /dev/null +++ b/frontend/src/lib/components/DistributionBar.svelte @@ -0,0 +1,54 @@ + + + diff --git a/frontend/src/lib/components/DistributionBar.svelte.spec.ts b/frontend/src/lib/components/DistributionBar.svelte.spec.ts new file mode 100644 index 00000000..3af8bca0 --- /dev/null +++ b/frontend/src/lib/components/DistributionBar.svelte.spec.ts @@ -0,0 +1,58 @@ +import { describe, it, expect, afterEach } from 'vitest'; +import { cleanup, render } from 'vitest-browser-svelte'; + +import DistributionBar from './DistributionBar.svelte'; + +afterEach(() => { + cleanup(); +}); + +describe('DistributionBar', () => { + it('renders both counts and short names, and the two-tone fill bar', async () => { + render(DistributionBar, { + outCount: 3, + inCount: 7, + senderName: 'Hans Müller', + receiverName: 'Anna Schmidt' + }); + + const container = document.querySelector('[role="img"]') as HTMLElement; + expect(container).toBeTruthy(); + expect(container.getAttribute('aria-label')).toContain('3 von Hans Müller'); + expect(container.getAttribute('aria-label')).toContain('7 von Anna Schmidt'); + + expect(container.textContent).toContain('3 von Hans'); + expect(container.textContent).toContain('7 von Anna'); + + // 3/10 → 30% / 70% split on the two segments + const segments = container.querySelectorAll('[data-testid="dist-bar-segment"]'); + expect(segments).toHaveLength(2); + expect((segments[0] as HTMLElement).style.width).toBe('30%'); + expect((segments[1] as HTMLElement).style.width).toBe('70%'); + }); + + it('falls back to the full name when it has no space to split', async () => { + render(DistributionBar, { + outCount: 1, + inCount: 0, + senderName: 'SingleWord', + receiverName: 'Another' + }); + + const container = document.querySelector('[role="img"]') as HTMLElement; + expect(container.textContent).toContain('1 von SingleWord'); + }); + + it('renders a zero-percent left segment when outCount is zero', async () => { + render(DistributionBar, { + outCount: 0, + inCount: 4, + senderName: 'Hans', + receiverName: 'Anna' + }); + + const segments = document.querySelectorAll('[data-testid="dist-bar-segment"]'); + expect((segments[0] as HTMLElement).style.width).toBe('0%'); + expect((segments[1] as HTMLElement).style.width).toBe('100%'); + }); +});