From ab8a73d7c3e1886d387cabff3ac9c27b84b9115d Mon Sep 17 00:00:00 2001 From: Scrum4Me Agent <30029041+madhura68@users.noreply.github.com> Date: Thu, 14 May 2026 21:36:57 +0200 Subject: [PATCH] feat(PBI-ll): voeg lib/product-switch-path.ts toe met resolveProductSwitchTarget Pure helper die doel-URL bij product-wissel bepaalt; unit-tests dekken alle pad-gevallen. Co-Authored-By: Claude Sonnet 4.6 --- __tests__/lib/product-switch-path.test.ts | 55 +++++++++++++++++++++++ lib/product-switch-path.ts | 14 ++++++ 2 files changed, 69 insertions(+) create mode 100644 __tests__/lib/product-switch-path.test.ts create mode 100644 lib/product-switch-path.ts diff --git a/__tests__/lib/product-switch-path.test.ts b/__tests__/lib/product-switch-path.test.ts new file mode 100644 index 0000000..13d407a --- /dev/null +++ b/__tests__/lib/product-switch-path.test.ts @@ -0,0 +1,55 @@ +import { describe, it, expect } from 'vitest' +import { resolveProductSwitchTarget } from '@/lib/product-switch-path' + +describe('resolveProductSwitchTarget', () => { + it('returns null for non-product pages', () => { + expect(resolveProductSwitchTarget('/dashboard', 'new-id')).toBeNull() + expect(resolveProductSwitchTarget('/insights', 'new-id')).toBeNull() + expect(resolveProductSwitchTarget('/ideas', 'new-id')).toBeNull() + expect(resolveProductSwitchTarget('/jobs', 'new-id')).toBeNull() + }) + + it('maps /products/ to /products/', () => { + expect(resolveProductSwitchTarget('/products/old-id', 'new-id')).toBe('/products/new-id') + }) + + it('maps /products// to /products/', () => { + expect(resolveProductSwitchTarget('/products/old-id/', 'new-id')).toBe('/products/new-id') + }) + + it('maps /products//sprint to /products//sprint', () => { + expect(resolveProductSwitchTarget('/products/old-id/sprint', 'new-id')).toBe( + '/products/new-id/sprint', + ) + }) + + it('maps /products//sprint/ to /products//sprint', () => { + expect(resolveProductSwitchTarget('/products/old-id/sprint/abc123', 'new-id')).toBe( + '/products/new-id/sprint', + ) + }) + + it('maps /products//sprint/.../planning to /products//sprint', () => { + expect(resolveProductSwitchTarget('/products/old-id/sprint/abc123/planning', 'new-id')).toBe( + '/products/new-id/sprint', + ) + }) + + it('maps /products//solo to /products//solo', () => { + expect(resolveProductSwitchTarget('/products/old-id/solo', 'new-id')).toBe( + '/products/new-id/solo', + ) + }) + + it('falls back to /products/ for /products//settings', () => { + expect(resolveProductSwitchTarget('/products/old-id/settings', 'new-id')).toBe( + '/products/new-id', + ) + }) + + it('falls back to /products/ for unknown sub-segments', () => { + expect(resolveProductSwitchTarget('/products/old-id/unknown/deep', 'new-id')).toBe( + '/products/new-id', + ) + }) +}) diff --git a/lib/product-switch-path.ts b/lib/product-switch-path.ts new file mode 100644 index 0000000..ce79ab9 --- /dev/null +++ b/lib/product-switch-path.ts @@ -0,0 +1,14 @@ +export function resolveProductSwitchTarget( + pathname: string, + newProductId: string, +): string | null { + const match = pathname.match(/^\/products\/([^/]+)(\/.*)?$/) + if (!match) return null + + const rest = match[2] ?? '' + + if (!rest || rest === '/') return `/products/${newProductId}` + if (rest.startsWith('/sprint')) return `/products/${newProductId}/sprint` + if (rest.startsWith('/solo')) return `/products/${newProductId}/solo` + return `/products/${newProductId}` +}