import { describe, expect, it } from 'vitest'; import { describeOrigin, parseUserAgent } from './origin'; /** * origin.spec.ts — NEU (quick-260918-gza, Herkunft einer Fehlermeldung). * * Zehn Tests fuer die beiden reinen Funktionen aus origin.ts: * 1-5 `parseUserAgent` fuer Desktop- und Mobil-Browser (Reihenfolge der * Muster: Edge/Opera vor Chrome, Safari nur ohne Chrome-Token, * Android/iOS vor Linux/macOS); * 6-8 `describeOrigin` im Desktop-Fall (mit/ohne Commit, ganz ohne * Details — alter Client); * 9 Rueckfall auf den Browser-Pfad, wenn alle vier Client-Felder * fehlen (alter Web-Bau); * 10 Bereinigung: kein Zeilenumbruch, kein Markup, hoechstens 40 * Zeichen je Wert (T-GZA-01). */ const EDGE_WINDOWS_UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.2792.52'; const CHROME_WINDOWS_UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36'; const FIREFOX_LINUX_UA = 'Mozilla/5.0 (X11; Linux x86_64; rv:130.0) Gecko/20100101 Firefox/130.0'; const SAFARI_MACOS_UA = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Safari/605.1.15'; const ANDROID_CHROME_UA = 'Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Mobile Safari/537.36'; const IPAD_SAFARI_UA = 'Mozilla/5.0 (iPad; CPU OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1'; const OPERA_UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 OPR/114.0.0.0'; const WEBKITGTK_LINUX_UA = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15'; describe('origin (quick-260918-gza)', () => { it('Test 1: Edge auf Windows — Edge gewinnt vor Chrome', () => { expect(parseUserAgent(EDGE_WINDOWS_UA)).toEqual({ browser: 'Edge 129', os: 'Windows' }); expect(describeOrigin({ clientKind: 'browser', userAgent: EDGE_WINDOWS_UA })).toEqual({ tag: '[Browser]', line: 'Browser — Edge 129 auf Windows', }); }); it('Test 2: derselbe UA ohne Edg/ — Chrome auf Windows', () => { expect(parseUserAgent(CHROME_WINDOWS_UA)).toEqual({ browser: 'Chrome 129', os: 'Windows' }); }); it('Test 3: Firefox auf Linux', () => { expect(parseUserAgent(FIREFOX_LINUX_UA)).toEqual({ browser: 'Firefox 130', os: 'Linux' }); expect(describeOrigin({ userAgent: FIREFOX_LINUX_UA }).line).toBe('Browser — Firefox 130 auf Linux'); }); it('Test 4: Safari auf macOS — Version aus Version/, nur ohne Chrome-Token', () => { expect(parseUserAgent(SAFARI_MACOS_UA)).toEqual({ browser: 'Safari 17', os: 'macOS' }); }); it('Test 5: Mobil — Android statt Linux, iOS statt macOS, Opera erkannt', () => { expect(parseUserAgent(ANDROID_CHROME_UA).os).toBe('Android'); const ipad = parseUserAgent(IPAD_SAFARI_UA); expect(ipad.os).toBe('iOS'); expect(ipad.browser).toBe('Safari 17'); expect(parseUserAgent(OPERA_UA).browser).toBe('Opera 114'); }); it('Test 6: WebKitGTK-Client als Desktop — der User-Agent spielt keine Rolle', () => { expect( describeOrigin({ userAgent: WEBKITGTK_LINUX_UA, clientKind: 'desktop', clientOs: 'linux', clientVersion: '1.2.0', clientCommit: 'a6d1a64', }), ).toEqual({ tag: '[Desktop/Linux]', line: 'Desktop-App (Linux), Tessera-App 1.2.0 · Stand a6d1a64', }); }); it('Test 7: Desktop ohne Commit — kein "· Stand"; Leerraum wird wie ein leerer Commit behandelt', () => { expect( describeOrigin({ clientKind: 'desktop', clientOs: 'windows', clientVersion: '1.2.0', clientCommit: '' }), ).toEqual({ tag: '[Desktop/Windows]', line: 'Desktop-App (Windows), Tessera-App 1.2.0' }); expect( describeOrigin({ clientKind: 'desktop', clientOs: 'windows', clientVersion: '1.2.0', clientCommit: ' ' }), ).toEqual({ tag: '[Desktop/Windows]', line: 'Desktop-App (Windows), Tessera-App 1.2.0' }); }); it('Test 8: Desktop ohne Details (alter Client, Cookie fehlt) — unbekanntes Betriebssystem ebenfalls', () => { expect( describeOrigin({ clientKind: 'desktop', clientOs: '', clientVersion: '', clientCommit: '' }), ).toEqual({ tag: '[Desktop]', line: 'Desktop-App (unbekannt)' }); expect( describeOrigin({ clientKind: 'desktop', clientOs: 'freebsd', clientVersion: '', clientCommit: '' }), ).toEqual({ tag: '[Desktop]', line: 'Desktop-App (unbekannt)' }); }); it('Test 9: Rueckfall auf den Browser-Pfad, wenn alle vier Client-Felder fehlen (alter Web-Bau)', () => { expect(describeOrigin({ userAgent: 'UA' })).toEqual({ tag: '[Browser]', line: 'Browser — unbekannt auf unbekannt', }); expect(describeOrigin({ clientKind: 'browser', userAgent: '' })).toEqual({ tag: '[Browser]', line: 'Browser — unbekannt auf unbekannt', }); }); it('Test 10: Bereinigung — kein Zeilenumbruch, kein Markup, hoechstens 40 Zeichen je Wert (T-GZA-01)', () => { const origin = describeOrigin({ clientKind: 'desktop', clientOs: 'windows', clientVersion: '1.2.0\nBenutzer: admin', clientCommit: 'a6d1a64', }); expect(origin.line).not.toMatch(/[\n\r<>]/); expect(origin.line).toBe('Desktop-App (Windows), Tessera-App 1.2.0Benutzeradmin · Stand a6d1a64b'); const longValue = 'x'.repeat(60); const truncated = describeOrigin({ clientKind: 'desktop', clientOs: 'linux', clientVersion: longValue, clientCommit: longValue, }); expect(truncated.line).toBe(`Desktop-App (Linux), Tessera-App ${'x'.repeat(40)} · Stand ${'x'.repeat(40)}`); }); });