import { describe, it, expect } from 'vitest'; import { normalizeUrl } from '../normalize-url'; describe('normalizeUrl', () => { it('удаляет page=1', () => { const result = normalizeUrl({ path: '/videos', query: { page: '1' } }); expect(result.query.page).toBeUndefined(); }); it('сохраняет page=2', () => { const result = normalizeUrl({ path: '/videos', query: { page: '2' } }); expect(result.query.page).toBe('2'); }); it('удаляет sort=trending', () => { const result = normalizeUrl({ path: '/videos', query: { sort: 'trending' } }); expect(result.query.sort).toBeUndefined(); }); it('сохраняет sort=popular', () => { const result = normalizeUrl({ path: '/videos', query: { sort: 'popular' } }); expect(result.query.sort).toBe('popular'); }); it('удаляет пустые значения', () => { const result = normalizeUrl({ path: '/', query: { a: '', b: null as any, c: 'ok' } }); expect(result.query).toEqual({ c: 'ok' }); }); it('сортирует категории — перестановка даёт один адрес', () => { const direct = normalizeUrl({ path: '/', query: { categories: 'cat_teen,cat_bear' } }); const reversed = normalizeUrl({ path: '/', query: { categories: 'cat_bear,cat_teen' } }); expect(direct.query.categories).toBe('cat_bear,cat_teen'); expect(direct.query.categories).toBe(reversed.query.categories); }); it('отсортированные категории идемпотентны — нет петли редиректов', () => { const result = normalizeUrl({ path: '/', query: { categories: 'cat_bear,cat_teen' } }); expect(result.query.categories).toBe('cat_bear,cat_teen'); }); it('lowercase путь', () => { const result = normalizeUrl({ path: '/Videos/BIG', query: {} }); expect(result.path).toBe('/videos/big'); }); it('lowercase query', () => { const result = normalizeUrl({ path: '/', query: { Sort: 'Popular' } }); expect(result.query).toEqual({ sort: 'popular' }); }); it('%20 и пробелы → дефисы', () => { const result = normalizeUrl({ path: '/big%20tits videos', query: {} }); expect(result.path).toBe('/big-tits-videos'); }); it('убирает двойные дефисы', () => { const result = normalizeUrl({ path: '/big--tits', query: {} }); expect(result.path).toBe('/big-tits'); }); it('убирает trailing slash', () => { const result = normalizeUrl({ path: '/videos/', query: {} }); expect(result.path).toBe('/videos'); }); it('не убирает /', () => { const result = normalizeUrl({ path: '/', query: {} }); expect(result.path).toBe('/'); }); it('кириллический slug (lowercase) идемпотентен — нет петли редиректов', () => { const result = normalizeUrl({ path: '/ru/categories/letter/%D0%B6', query: {} }); expect(result.path).toBe('/ru/categories/letter/%D0%B6'); }); it('кириллический slug в верхнем регистре → нижний', () => { const result = normalizeUrl({ path: '/ru/categories/letter/%D0%96', query: {} }); expect(result.path).toBe('/ru/categories/letter/%D0%B6'); }); });