import { describe, it, expect } from 'vitest' import router, { FRONT_DOOR, scrollBehavior } from '../src/router.js' describe('router', () => { it('FRONT_DOOR is the post feed', () => { // Moved from /showcase in #387 B1. Asserted on the constant rather than on // a navigation so the intent is pinned: the door is the feed, and moving it // again should be a deliberate edit to a failing test, not a quiet change. expect(FRONT_DOOR).toBe('/latest') }) it('/latest is the feed, mounted outside the Browse tab strip', () => { const r = router.resolve('/latest') expect(r.name).toBe('latest') // A nav entry in its own right (meta.title is what TopNav lists on), and // first in the order. expect(r.meta.title).toBe('Latest') expect(r.meta.navOrder).toBe(5) // Deliberately NOT stickyChrome — it has no sticky sub-header for the nav // to butt against, unlike Browse/Gallery/Settings. expect(r.meta.stickyChrome).toBeUndefined() }) it('showcase is demoted, not removed — still reachable and still in the nav', () => { const r = router.resolve('/showcase') expect(r.name).toBe('showcase') expect(r.meta.title).toBe('Showcase') }) it('/ redirects to FRONT_DOOR', async () => { // resolve() does not follow redirects (they apply on navigation), so // actually navigate and assert the resulting route. await router.push('/') expect(router.currentRoute.value.path).toBe(FRONT_DOOR) }) it('gallery is reachable at /gallery', () => { expect(router.resolve('/gallery').name).toBe('gallery') }) it('showcase, artist resolve to named routes', () => { expect(router.resolve('/showcase').name).toBe('showcase') expect(router.resolve('/artist/some-slug').name).toBe('artist') expect(router.resolve('/artist/some-slug').params.slug).toBe('some-slug') }) it('browse hub is reachable and old axis paths redirect into its tabs', async () => { expect(router.resolve('/browse').name).toBe('browse') await router.push('/tags') expect(router.currentRoute.value.name).toBe('browse') expect(router.currentRoute.value.query.tab).toBe('tags') await router.push('/artists') expect(router.currentRoute.value.query.tab).toBe('artists') // A posts deep link survives the redirect into the hub tab. await router.push({ path: '/posts', query: { post_id: '7' } }) expect(router.currentRoute.value.name).toBe('browse') expect(router.currentRoute.value.query.tab).toBe('posts') expect(router.currentRoute.value.query.post_id).toBe('7') }) it('/system redirects into the Settings System tab', async () => { // It shipped as a standalone page for one build; the health dot and any // bookmark from it must still land on the surface, which is now a tab. await router.push('/system') expect(router.currentRoute.value.name).toBe('settings') expect(router.currentRoute.value.query.tab).toBe('system') }) it('series-read is an immersive route', () => { const r = router.resolve('/series/5/read') expect(r.name).toBe('series-read') expect(r.meta.immersive).toBe(true) }) describe('scrollBehavior', () => { const at = (path) => ({ path, hash: '', matched: [{}] }) it('opens a new view at its top, not at the last view\'s offset', () => { expect(scrollBehavior(at('/settings'), at('/latest'), null)).toEqual({ top: 0 }) }) it('back and forward return to where the entry was left', () => { const saved = { left: 0, top: 1234 } expect(scrollBehavior(at('/latest'), at('/settings'), saved)).toBe(saved) }) it('a new query on the same view keeps its place', () => { expect(scrollBehavior(at('/gallery'), at('/gallery'), null)).toBe(false) }) it('the first navigation of a page load opens at the top', () => { const initial = { path: '/', hash: '', matched: [] } expect(scrollBehavior(at('/latest'), initial, null)).toEqual({ top: 0 }) }) }) })