CI and images / lint (push) Successful in 2s
CI and images / extension-version (push) Successful in 2s
CI and images / frontend-build (push) Successful in 21s
CI and images / backend-lint-and-test (push) Successful in 31s
CI and images / integration (push) Successful in 2m17s
CI and images / sign-extension (push) Successful in 3s
CI and images / build-agent (push) Successful in 6s
CI and images / build-web (push) Successful in 1m39s
CI and images / smoke-web (push) Successful in 55s
CI and images / promote (push) Skipped
The router had no scrollBehavior, so Settings entered from a scrolled feed opened scrolled too, its heading and tab strip under the nav. Back/forward restores the saved position, and a new query on the same view keeps its place. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LVjrnpQjRgHdvq95rASoiR
100 lines
3.9 KiB
JavaScript
100 lines
3.9 KiB
JavaScript
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 })
|
|
})
|
|
})
|
|
})
|