import { describe, expect, it } from 'vitest'; import worker from '../worker/index'; import { AUTH_SESSION_COOKIE_NAME, hashSessionToken } from '../worker/auth'; type LinkScope = 'public' | 'private'; type LinkStatus = 'active' | 'archived' | 'deleted'; type LinkType = 'redirect' | 'custom'; type LinkRow = { id: string; scope: LinkScope; owner_user_id: string | null; alias: string; link_type: LinkType; target_url: string | null; content_markdown: string | null; description: string | null; status: LinkStatus; click_count: number; created_at: string; updated_at: string; }; type SessionRow = { id: string; email: string | null; name: string | null; image_url: string | null; role: 'user' | 'admin'; expires_at: string; session_token_hash: string; }; type RunCall = { sql: string; params: unknown[]; }; type AllResult = { results: T[]; success: true; meta: Record; }; type FakeD1Options = { throwOnInsert?: Error; throwOnUpdate?: Error; }; class FakeD1Database { readonly preparedSql: string[] = []; readonly runCalls: RunCall[] = []; constructor( readonly links: LinkRow[] = [], private readonly sessions: SessionRow[] = [], private readonly options: FakeD1Options = {}, ) {} prepare(sql: string): FakeD1PreparedStatement { this.preparedSql.push(sql); return new FakeD1PreparedStatement(this, sql); } findSession(hash: string): SessionRow | null { return this.sessions.find((candidate) => candidate.session_token_hash === hash) ?? null; } listLinks(scope: LinkScope, ownerUserId?: string, search?: string): LinkRow[] { const term = search?.toLowerCase(); return this.links .filter((link) => { if (link.scope !== scope || link.status !== 'active') { return false; } if (scope === 'private' && link.owner_user_id !== ownerUserId) { return false; } if (term && !link.alias.toLowerCase().includes(term)) { return false; } return true; }) .sort((a, b) => { if (term) { const aExact = a.alias.toLowerCase() === term ? 0 : 1; const bExact = b.alias.toLowerCase() === term ? 0 : 1; if (aExact !== bExact) return aExact - bExact; } if (a.click_count !== b.click_count) return b.click_count - a.click_count; return b.updated_at.localeCompare(a.updated_at); }); } findDuplicate( scope: LinkScope, alias: string, ownerUserId: string | null, statusFilter: 'active' | 'not-deleted', excludeId?: string, ): LinkRow | null { return ( this.links.find((link) => { const statusMatches = statusFilter === 'active' ? link.status === 'active' : link.status !== 'deleted'; if (link.scope !== scope || !statusMatches || link.alias !== alias || link.id === excludeId) { return false; } return scope === 'public' ? true : link.owner_user_id === ownerUserId; }) ?? null ); } maybeThrowOnInsert(): void { if (this.options.throwOnInsert) { throw this.options.throwOnInsert; } } maybeThrowOnUpdate(): void { if (this.options.throwOnUpdate) { throw this.options.throwOnUpdate; } } findEditableLink(scope: LinkScope, id: string, ownerUserId?: string): LinkRow | null { return ( this.links.find((link) => { if (link.id !== id || link.scope !== scope || link.status !== 'active') { return false; } return scope === 'public' ? true : link.owner_user_id === ownerUserId; }) ?? null ); } insertLink(params: unknown[]): void { const [id, scope, ownerUserId, alias, linkType, targetUrl, contentMarkdown, description] = params; this.links.push({ id: String(id), scope: scope as LinkScope, owner_user_id: ownerUserId == null ? null : String(ownerUserId), alias: String(alias), link_type: linkType as LinkType, target_url: targetUrl == null ? null : String(targetUrl), content_markdown: contentMarkdown == null ? null : String(contentMarkdown), description: description == null ? null : String(description), status: 'active', click_count: 0, created_at: '2026-06-20T00:00:00.000Z', updated_at: '2026-06-20T00:00:00.000Z', }); } } class FakeD1PreparedStatement { constructor( private readonly db: FakeD1Database, private readonly sql: string, private readonly params: unknown[] = [], ) {} bind(...params: unknown[]): FakeD1PreparedStatement { return new FakeD1PreparedStatement(this.db, this.sql, params); } async first(): Promise { if (this.sql.includes('session_token_hash')) { const row = this.db.findSession(String(this.params[0])); if (!row) { return null; } return { id: row.id, email: row.email, name: row.name, image_url: row.image_url, role: row.role, expires_at: row.expires_at, } as T; } if ( this.sql.includes('alias=?') && (this.sql.includes('status=\'active\'') || this.sql.includes("status!='deleted'") || this.sql.includes("status != 'deleted'")) ) { const scope = this.sql.includes("scope='public'") ? 'public' : 'private'; const hasOwner = this.sql.includes('owner_user_id=?'); const ownerUserId = hasOwner ? String(this.params[0]) : null; const alias = String(this.params[hasOwner ? 1 : 0]); const excludeId = this.sql.includes('id!=?') ? String(this.params[hasOwner ? 2 : 1]) : undefined; const statusFilter = this.sql.includes("status!='deleted'") || this.sql.includes("status != 'deleted'") ? 'not-deleted' : 'active'; const row = this.db.findDuplicate(scope, alias, ownerUserId, statusFilter, excludeId); return (row ? rowToDbResult(row) : null) as T | null; } if (this.sql.includes('id=?') && this.sql.includes('status=\'active\'')) { const scope = this.sql.includes("scope='public'") ? 'public' : 'private'; const hasOwner = this.sql.includes('owner_user_id=?'); const id = String(this.params[0]); const ownerUserId = hasOwner ? String(this.params[1]) : undefined; const row = this.db.findEditableLink(scope, id, ownerUserId); return (row ? rowToDbResult(row) : null) as T | null; } return null; } async all(): Promise> { const isSearch = this.sql.includes(' LIKE '); let searchTerm: string | undefined; if (isSearch) { if (this.sql.includes("scope='public'")) { searchTerm = String(this.params[1]); } else { searchTerm = String(this.params[2]); } } if (this.sql.includes("scope='public'")) { return { results: this.db.listLinks('public', undefined, searchTerm).map(rowToDbResult) as T[], success: true, meta: {} }; } if (this.sql.includes("scope='private'")) { return { results: this.db.listLinks('private', String(this.params[0]), searchTerm).map(rowToDbResult) as T[], success: true, meta: {}, }; } return { results: [], success: true, meta: {} }; } async run(): Promise { this.db.runCalls.push({ sql: this.sql, params: this.params }); if (this.sql.startsWith('INSERT INTO links')) { this.db.maybeThrowOnInsert(); this.db.insertLink(this.params); } if (this.sql.startsWith('UPDATE links SET') && this.sql.includes('status=\'deleted\'')) { const id = String(this.params[0]); const hasOwner = this.sql.includes('owner_user_id=?'); const ownerUserId = hasOwner ? String(this.params[1]) : undefined; const scope = this.sql.includes("scope='public'") ? 'public' : 'private'; const row = this.db.findEditableLink(scope, id, ownerUserId); if (row) { row.status = 'deleted'; row.updated_at = '2026-06-20T00:00:01.000Z'; } } if (this.sql.startsWith('UPDATE links SET') && !this.sql.includes('status=\'deleted\'')) { this.db.maybeThrowOnUpdate(); const [alias, linkType, targetUrl, contentMarkdown, description, id] = this.params; const row = this.db.links.find((candidate) => candidate.id === id); if (row) { row.alias = String(alias); row.link_type = linkType as LinkType; row.target_url = targetUrl == null ? null : String(targetUrl); row.content_markdown = contentMarkdown == null ? null : String(contentMarkdown); row.description = description == null ? null : String(description); row.updated_at = '2026-06-20T00:00:01.000Z'; } } return { success: true, meta: { changes: 1 } } as unknown as D1Result; } } class FakeExecutionContext { waitUntil(): void {} passThroughOnException(): void {} } function rowToDbResult(row: LinkRow) { return { id: row.id, alias: row.alias, scope: row.scope, link_type: row.link_type, target_url: row.target_url, content_markdown: row.content_markdown, description: row.description, owner_user_id: row.owner_user_id, click_count: row.click_count, status: row.status, created_at: row.created_at, updated_at: row.updated_at, }; } function link(overrides: Partial = {}): LinkRow { return { id: 'link_1', scope: 'private', owner_user_id: 'user_1', alias: 'docs', link_type: 'redirect', target_url: 'https://example.com/docs', content_markdown: null, description: null, status: 'active', click_count: 0, created_at: '2026-06-20T00:00:00.000Z', updated_at: '2026-06-20T00:00:00.000Z', ...overrides, }; } function futureIso(): string { return new Date(Date.now() + 60 * 60 * 1000).toISOString(); } async function userSession(token: string, userId: string, role: 'user' | 'admin' = 'user'): Promise { return { id: userId, email: `${userId}@heygo.cc`, name: userId, image_url: null, role, expires_at: futureIso(), session_token_hash: await hashSessionToken(token), }; } function cookie(token: string): string { return `${AUTH_SESSION_COOKIE_NAME}=${token}`; } function makeEnv(links: LinkRow[] = [], sessions: SessionRow[] = [], dbOptions: FakeD1Options = {}) { const db = new FakeD1Database(links, sessions, dbOptions); return { env: { DB: db as unknown as D1Database, PUBLIC_HOST: 'heygo.cc', PRIVATE_HOST: 'my.heygo.cc', APP_BASE_URL: 'https://heygo.cc', COOKIE_DOMAIN: '.heygo.cc', }, db, ctx: new FakeExecutionContext(), }; } async function fetchWorker( path: string, opts: { method?: string; body?: unknown; links?: LinkRow[]; sessions?: SessionRow[]; cookie?: string; dbOptions?: FakeD1Options; } = {}, ) { const { env, db, ctx } = makeEnv(opts.links ?? [], opts.sessions ?? [], opts.dbOptions); const headers = new Headers(); if (opts.cookie) { headers.set('cookie', opts.cookie); } if (opts.body !== undefined) { headers.set('content-type', 'application/json'); } const response = await worker.fetch( new Request(`https://heygo.cc${path}`, { method: opts.method ?? 'GET', headers, body: opts.body === undefined ? undefined : JSON.stringify(opts.body), }) as unknown as Parameters[0], env as unknown as Parameters[1], ctx as unknown as Parameters[2], ); return { response, db }; } async function expectJson(response: Response): Promise { expect(response.headers.get('content-type')).toContain('application/json'); return response.json() as Promise; } function uniqueConstraintError(): Error { return new Error('D1_ERROR: UNIQUE constraint failed: links.alias'); } describe('link CRUD API', () => { it('creates a private link and lowercases the alias', async () => { const session = await userSession('token-a', 'user_1'); const { response } = await fetchWorker('/api/links/private', { method: 'POST', cookie: cookie('token-a'), sessions: [session], body: { alias: 'My_Link', linkType: 'redirect', targetUrl: 'https://example.com/a', description: 'A' }, }); expect(response.status).toBe(201); const body = await expectJson(response); expect(body.link).toMatchObject({ alias: 'my_link', scope: 'private', ownerUserId: 'user_1', linkType: 'redirect', targetUrl: 'https://example.com/a', status: 'active', }); }); it('records a clone-from-public history event when copying a public link into private links', async () => { const session = await userSession('token-clone-public', 'user_1'); const { response, db } = await fetchWorker('/api/links/private', { method: 'POST', cookie: cookie('token-clone-public'), sessions: [session], links: [link({ id: 'public_src', scope: 'public', owner_user_id: null, alias: 'opencode' })], body: { alias: 'opencode-copy', linkType: 'redirect', targetUrl: 'https://example.com/opencode', sourcePublicLinkId: 'public_src', }, }); expect(response.status).toBe(201); const cloneLogCall = db.runCalls.find((call) => call.sql.startsWith('INSERT INTO link_change_logs') && call.params[2] === 'cloned_from_public', ); expect(cloneLogCall?.params[3]).toBe('public_src'); expect(cloneLogCall?.params[4]).toBe('opencode'); }); it('rejects custom links without contentMarkdown', async () => { const session = await userSession('token-custom-missing-content', 'user_1'); const { response } = await fetchWorker('/api/links/private', { method: 'POST', cookie: cookie('token-custom-missing-content'), sessions: [session], body: { alias: 'custom-page', linkType: 'custom' }, }); expect(response.status).toBe(400); await expect(expectJson(response)).resolves.toHaveProperty('error'); }); it('creates custom links with explicit null targetUrl', async () => { const session = await userSession('token-custom-null-target', 'user_1'); const { response } = await fetchWorker('/api/links/private', { method: 'POST', cookie: cookie('token-custom-null-target'), sessions: [session], body: { alias: 'custom-page', linkType: 'custom', targetUrl: null, contentMarkdown: '# Hello' }, }); expect(response.status).toBe(201); const body = await expectJson(response); expect(body.link).toMatchObject({ alias: 'custom-page', linkType: 'custom', targetUrl: null, contentMarkdown: '# Hello', }); }); it('rejects redirect links with non-http targetUrl schemes', async () => { const session = await userSession('token-js-url', 'user_1'); const { response } = await fetchWorker('/api/links/private', { method: 'POST', cookie: cookie('token-js-url'), sessions: [session], body: { alias: 'bad-url', linkType: 'redirect', targetUrl: 'javascript:alert(1)' }, }); expect(response.status).toBe(400); await expect(expectJson(response)).resolves.toHaveProperty('error'); }); it('rejects duplicate private aliases for the same user with 409', async () => { const session = await userSession('token-a', 'user_1'); const { response } = await fetchWorker('/api/links/private', { method: 'POST', cookie: cookie('token-a'), sessions: [session], links: [link({ alias: 'docs', owner_user_id: 'user_1' })], body: { alias: 'Docs', linkType: 'redirect', targetUrl: 'https://example.com/new' }, }); expect(response.status).toBe(409); await expect(expectJson(response)).resolves.toEqual({ error: 'Alias already exists' }); }); it('rejects archived duplicate private aliases for the same user with 409', async () => { const session = await userSession('token-archived-private', 'user_1'); const { response } = await fetchWorker('/api/links/private', { method: 'POST', cookie: cookie('token-archived-private'), sessions: [session], links: [link({ alias: 'docs', owner_user_id: 'user_1', status: 'archived' })], body: { alias: 'Docs', linkType: 'redirect', targetUrl: 'https://example.com/new' }, }); expect(response.status).toBe(409); await expect(expectJson(response)).resolves.toEqual({ error: 'Alias already exists' }); }); it('allows deleted private aliases to be reused by the same user', async () => { const session = await userSession('token-deleted-private', 'user_1'); const { response } = await fetchWorker('/api/links/private', { method: 'POST', cookie: cookie('token-deleted-private'), sessions: [session], links: [link({ alias: 'docs', owner_user_id: 'user_1', status: 'deleted' })], body: { alias: 'Docs', linkType: 'redirect', targetUrl: 'https://example.com/new' }, }); expect(response.status).toBe(201); const body = await expectJson(response); expect(body.link).toMatchObject({ alias: 'docs', ownerUserId: 'user_1' }); }); it('returns 409 JSON when a private link insert hits a unique constraint race', async () => { const session = await userSession('token-insert-race', 'user_1'); const { response } = await fetchWorker('/api/links/private', { method: 'POST', cookie: cookie('token-insert-race'), sessions: [session], body: { alias: 'race', linkType: 'redirect', targetUrl: 'https://example.com/race' }, dbOptions: { throwOnInsert: uniqueConstraintError() }, }); expect(response.status).toBe(409); await expect(expectJson(response)).resolves.toEqual({ error: 'Alias already exists' }); }); it('allows the same private alias for different users', async () => { const session = await userSession('token-b', 'user_2'); const { response } = await fetchWorker('/api/links/private', { method: 'POST', cookie: cookie('token-b'), sessions: [session], links: [link({ id: 'link_a', alias: 'shared', owner_user_id: 'user_1' })], body: { alias: 'shared', linkType: 'redirect', targetUrl: 'https://example.com/user-b' }, }); expect(response.status).toBe(201); const body = await expectJson(response); expect(body.link).toMatchObject({ alias: 'shared', ownerUserId: 'user_2' }); }); it('returns 401 JSON for unauthenticated private API requests', async () => { const { response } = await fetchWorker('/api/links/private'); expect(response.status).toBe(401); await expect(expectJson(response)).resolves.toEqual({ error: 'Authentication required' }); }); it('only lets a private link owner PATCH their link', async () => { const owner = await userSession('owner-token', 'owner'); const other = await userSession('other-token', 'other'); const links = [link({ id: 'private_link', alias: 'old', owner_user_id: 'owner' })]; const denied = await fetchWorker('/api/links/private/private_link', { method: 'PATCH', cookie: cookie('other-token'), sessions: [owner, other], links, body: { alias: 'new', linkType: 'redirect', targetUrl: 'https://example.com/new' }, }); expect([403, 404]).toContain(denied.response.status); expect(links[0].alias).toBe('old'); const allowed = await fetchWorker('/api/links/private/private_link', { method: 'PATCH', cookie: cookie('owner-token'), sessions: [owner, other], links, body: { alias: 'New', linkType: 'redirect', targetUrl: 'https://example.com/new', description: 'updated' }, }); expect(allowed.response.status).toBe(200); const body = await expectJson(allowed.response); expect(body.link).toMatchObject({ id: 'private_link', alias: 'old', targetUrl: 'https://example.com/new', description: 'updated', ownerUserId: 'owner', }); }); it('ignores alias changes on private link PATCH (alias is immutable)', async () => { const owner = await userSession('owner-token', 'owner'); const links = [link({ id: 'private_link', alias: 'keepme', owner_user_id: 'owner' })]; const res = await fetchWorker('/api/links/private/private_link', { method: 'PATCH', cookie: cookie('owner-token'), sessions: [owner], links, body: { alias: 'changed', linkType: 'redirect', targetUrl: 'https://example.com/x' }, }); expect(res.response.status).toBe(200); const body = await expectJson(res.response); expect(body.link.alias).toBe('keepme'); expect(links[0].alias).toBe('keepme'); }); it('soft-deletes an owner private link', async () => { const session = await userSession('token-a', 'user_1'); const links = [link({ id: 'delete_me', owner_user_id: 'user_1' })]; const { response } = await fetchWorker('/api/links/private/delete_me', { method: 'DELETE', cookie: cookie('token-a'), sessions: [session], links, }); expect(response.status).toBe(200); await expect(expectJson(response)).resolves.toEqual({ ok: true }); expect(links[0].status).toBe('deleted'); }); it('lists only the current user active private links', async () => { const session = await userSession('token-a', 'user_1'); const { response } = await fetchWorker('/api/links/private', { cookie: cookie('token-a'), sessions: [session], links: [ link({ id: 'own_active', alias: 'own', owner_user_id: 'user_1', status: 'active' }), link({ id: 'own_deleted', alias: 'deleted', owner_user_id: 'user_1', status: 'deleted' }), link({ id: 'other_active', alias: 'other', owner_user_id: 'user_2', status: 'active' }), ], }); expect(response.status).toBe(200); const body = await expectJson(response); expect(body.links.map((item: { id: string }) => item.id)).toEqual(['own_active']); }); it('lists active public links without login', async () => { const { response } = await fetchWorker('/api/links/public', { links: [ link({ id: 'public_active', scope: 'public', owner_user_id: null, alias: 'pub', status: 'active' }), link({ id: 'public_deleted', scope: 'public', owner_user_id: null, alias: 'gone', status: 'deleted' }), link({ id: 'private_active', scope: 'private', owner_user_id: 'user_1', alias: 'priv', status: 'active' }), ], }); expect(response.status).toBe(200); const body = await expectJson(response); expect(body.links.map((item: { id: string }) => item.id)).toEqual(['public_active']); }); it('returns a public link detail without login', async () => { const { response } = await fetchWorker('/api/links/public/public_active', { links: [ link({ id: 'public_active', scope: 'public', owner_user_id: null, alias: 'pub', status: 'active' }), ], }); expect(response.status).toBe(200); const body = await expectJson(response); expect(body.link).toMatchObject({ id: 'public_active', alias: 'pub', scope: 'public', ownerUserId: null, }); }); it('returns public link stats and history without admin access', async () => { const links = [link({ id: 'public_active', scope: 'public', owner_user_id: null, alias: 'pub', status: 'active' })]; const stats = await fetchWorker('/api/links/public/public_active/stats?period=3m', { links }); expect(stats.response.status).toBe(200); await expect(expectJson(stats.response)).resolves.toEqual({ stats: [], period: '3m' }); const history = await fetchWorker('/api/links/public/public_active/history', { links }); expect(history.response.status).toBe(200); await expect(expectJson(history.response)).resolves.toEqual({ history: [] }); }); it('rejects non-admin public link creation with 403', async () => { const session = await userSession('token-a', 'user_1', 'user'); const { response } = await fetchWorker('/api/admin/public-links', { method: 'POST', cookie: cookie('token-a'), sessions: [session], body: { alias: 'pub', linkType: 'redirect', targetUrl: 'https://example.com/pub' }, }); expect(response.status).toBe(403); await expect(expectJson(response)).resolves.toEqual({ error: 'Admin access required' }); }); it('lets an admin create a public link', async () => { const session = await userSession('admin-token', 'admin_1', 'admin'); const { response } = await fetchWorker('/api/admin/public-links', { method: 'POST', cookie: cookie('admin-token'), sessions: [session], body: { alias: 'Public', linkType: 'redirect', targetUrl: 'https://example.com/pub' }, }); expect(response.status).toBe(201); const body = await expectJson(response); expect(body.link).toMatchObject({ alias: 'public', scope: 'public', ownerUserId: null, linkType: 'redirect', targetUrl: 'https://example.com/pub', }); }); it('rejects duplicate public aliases with 409', async () => { const session = await userSession('admin-token', 'admin_1', 'admin'); const { response } = await fetchWorker('/api/admin/public-links', { method: 'POST', cookie: cookie('admin-token'), sessions: [session], links: [link({ id: 'public_existing', scope: 'public', owner_user_id: null, alias: 'pub' })], body: { alias: 'Pub', linkType: 'redirect', targetUrl: 'https://example.com/new' }, }); expect(response.status).toBe(409); await expect(expectJson(response)).resolves.toEqual({ error: 'Alias already exists' }); }); it('rejects archived public aliases with 409', async () => { const session = await userSession('admin-token-archived', 'admin_1', 'admin'); const { response } = await fetchWorker('/api/admin/public-links', { method: 'POST', cookie: cookie('admin-token-archived'), sessions: [session], links: [link({ id: 'public_archived', scope: 'public', owner_user_id: null, alias: 'pub', status: 'archived' })], body: { alias: 'Pub', linkType: 'redirect', targetUrl: 'https://example.com/new' }, }); expect(response.status).toBe(409); await expect(expectJson(response)).resolves.toEqual({ error: 'Alias already exists' }); }); it('lets an admin PATCH a public link target and content but keeps alias immutable', async () => { const session = await userSession('admin-token', 'admin_1', 'admin'); const links = [link({ id: 'public_link', scope: 'public', owner_user_id: null, alias: 'old' })]; const { response } = await fetchWorker('/api/admin/public-links/public_link', { method: 'PATCH', cookie: cookie('admin-token'), sessions: [session], links, body: { alias: 'Updated', linkType: 'custom', contentMarkdown: '# Hello', description: 'Custom' }, }); expect(response.status).toBe(200); const body = await expectJson(response); expect(body.link).toMatchObject({ id: 'public_link', alias: 'old', scope: 'public', linkType: 'custom', targetUrl: null, contentMarkdown: '# Hello', description: 'Custom', }); }); it('lets an admin soft-delete a public link', async () => { const session = await userSession('admin-token', 'admin_1', 'admin'); const links = [link({ id: 'public_link', scope: 'public', owner_user_id: null, alias: 'public' })]; const { response } = await fetchWorker('/api/admin/public-links/public_link', { method: 'DELETE', cookie: cookie('admin-token'), sessions: [session], links, }); expect(response.status).toBe(200); await expect(expectJson(response)).resolves.toEqual({ ok: true }); expect(links[0].status).toBe('deleted'); }); it('returns 400 for invalid aliases and invalid bodies', async () => { const session = await userSession('token-a', 'user_1'); const badAlias = await fetchWorker('/api/links/private', { method: 'POST', cookie: cookie('token-a'), sessions: [session], body: { alias: '../bad', linkType: 'redirect', targetUrl: 'https://example.com' }, }); expect(badAlias.response.status).toBe(400); await expect(expectJson(badAlias.response)).resolves.toHaveProperty('error'); const missingTarget = await fetchWorker('/api/links/private', { method: 'POST', cookie: cookie('token-a'), sessions: [session], body: { alias: 'badbody', linkType: 'redirect' }, }); expect(missingTarget.response.status).toBe(400); await expect(expectJson(missingTarget.response)).resolves.toHaveProperty('error'); }); }); describe('link list ordering and search', () => { it('lists public links sorted by click_count desc then updated_at desc', async () => { const { response } = await fetchWorker('/api/links/public', { links: [ link({ id: 'low', scope: 'public', owner_user_id: null, alias: 'low', click_count: 5, updated_at: '2026-06-20T00:00:03.000Z' }), link({ id: 'high', scope: 'public', owner_user_id: null, alias: 'high', click_count: 100, updated_at: '2026-06-20T00:00:01.000Z' }), link({ id: 'mid', scope: 'public', owner_user_id: null, alias: 'mid', click_count: 50, updated_at: '2026-06-20T00:00:02.000Z' }), ], }); expect(response.status).toBe(200); const body = await expectJson(response); expect(body.links.map((item: { id: string }) => item.id)).toEqual(['high', 'mid', 'low']); }); it('lists private links sorted by click_count desc', async () => { const session = await userSession('token-a', 'user_1'); const { response } = await fetchWorker('/api/links/private', { cookie: cookie('token-a'), sessions: [session], links: [ link({ id: 'few', scope: 'private', owner_user_id: 'user_1', alias: 'few', click_count: 2 }), link({ id: 'many', scope: 'private', owner_user_id: 'user_1', alias: 'many', click_count: 80 }), ], }); expect(response.status).toBe(200); const body = await expectJson(response); expect(body.links.map((item: { id: string }) => item.id)).toEqual(['many', 'few']); }); it('searches public links by alias contains and pins exact match at top', async () => { const { response } = await fetchWorker('/api/links/public?q=op', { links: [ link({ id: 'popular_contains', scope: 'public', owner_user_id: null, alias: 'opencode', click_count: 500 }), link({ id: 'exact_op', scope: 'public', owner_user_id: null, alias: 'op', click_count: 10 }), link({ id: 'other_contains', scope: 'public', owner_user_id: null, alias: 'open-shop', click_count: 200 }), link({ id: 'unrelated', scope: 'public', owner_user_id: null, alias: 'docs', click_count: 999 }), ], }); expect(response.status).toBe(200); const body = await expectJson(response); const ids = body.links.map((item: { id: string }) => item.id); expect(ids).toEqual(['exact_op', 'popular_contains', 'other_contains']); expect(ids).not.toContain('unrelated'); }); it('search is case-insensitive on the query parameter', async () => { const { response } = await fetchWorker('/api/links/public?q=OPEN', { links: [ link({ id: 'exact', scope: 'public', owner_user_id: null, alias: 'open', click_count: 1 }), link({ id: 'contains', scope: 'public', owner_user_id: null, alias: 'opencode', click_count: 100 }), ], }); expect(response.status).toBe(200); const body = await expectJson(response); const ids = body.links.map((item: { id: string }) => item.id); expect(ids).toEqual(['exact', 'contains']); }); it('searches private links by alias contains for the current user only', async () => { const session = await userSession('token-a', 'user_1'); const { response } = await fetchWorker('/api/links/private?q=doc', { cookie: cookie('token-a'), sessions: [session], links: [ link({ id: 'mine_exact', scope: 'private', owner_user_id: 'user_1', alias: 'doc', click_count: 3 }), link({ id: 'mine_contains', scope: 'private', owner_user_id: 'user_1', alias: 'docs', click_count: 30 }), link({ id: 'theirs', scope: 'private', owner_user_id: 'user_2', alias: 'docs', click_count: 999 }), link({ id: 'unrelated', scope: 'private', owner_user_id: 'user_1', alias: 'blog', click_count: 50 }), ], }); expect(response.status).toBe(200); const body = await expectJson(response); const ids = body.links.map((item: { id: string }) => item.id); expect(ids).toEqual(['mine_exact', 'mine_contains']); expect(ids).not.toContain('theirs'); expect(ids).not.toContain('unrelated'); }); it('returns empty results for a query matching no aliases', async () => { const { response } = await fetchWorker('/api/links/public?q=nonexistent', { links: [ link({ id: 'pub', scope: 'public', owner_user_id: null, alias: 'docs' }), ], }); expect(response.status).toBe(200); const body = await expectJson(response); expect(body.links).toEqual([]); }); it('treats a blank query as no search (returns all links sorted by clicks)', async () => { const { response } = await fetchWorker('/api/links/public?q=%20%20', { links: [ link({ id: 'few', scope: 'public', owner_user_id: null, alias: 'few', click_count: 1 }), link({ id: 'many', scope: 'public', owner_user_id: null, alias: 'many', click_count: 99 }), ], }); expect(response.status).toBe(200); const body = await expectJson(response); expect(body.links.map((item: { id: string }) => item.id)).toEqual(['many', 'few']); }); });