test: add self-verifying coverage for boundaries

This commit is contained in:
Qiuner
2026-08-18 23:51:09 +08:00
parent 03bb3ef705
commit bfe1e357d6
3 changed files with 177 additions and 2 deletions
@@ -26,12 +26,12 @@ const baseItem = {
description: { en: 'A better sidebar.' },
}
async function adapt(installMethods: readonly unknown[]) {
async function adapt(installMethods: readonly unknown[], itemOverrides: Record<string, unknown> = {}) {
const http: CatalogHttpClient = {
getJson: vi.fn(async () => ({
value: {
meta: { revision: 'sha256:fixture' },
packages: [{ ...baseItem, installMethods }],
packages: [{ ...baseItem, ...itemOverrides, installMethods }],
},
finalUrl: 'https://deepseek1024.com/api/v1/plugins',
})),
@@ -109,6 +109,54 @@ describe('1024Store install target normalization', () => {
expect(snapshot.items[0]).not.toHaveProperty('latestVersion')
})
it('accepts duplicate evidence for the same reviewed npm target without treating it as ambiguity', async () => {
const snapshot = await adapt([
{
kind: 'npm',
spec: 'dsh-better-sidebar',
verification: 'verified',
code: 'repository_backlink',
requiresBuildAllowance: false,
revision: '0.12.3',
},
{
kind: 'npm',
spec: 'dsh-better-sidebar',
command: 'still ignored',
verification: 'verified',
code: 'repository_backlink',
requiresBuildAllowance: false,
revision: '0.12.3',
},
])
expect(snapshot.items[0]).toMatchObject({
latestVersion: '0.12.3',
package: { registry: 'npm', name: 'dsh-better-sidebar' },
})
expect(JSON.stringify(snapshot)).not.toContain('still ignored')
})
it.each([
['non-GitHub repository', { url: 'https://gitlab.example/omdsh-dev/DSH-better-sidebar' }],
['repository with extra path segments', { url: 'https://github.com/omdsh-dev/DSH-better-sidebar/releases' }],
['repository with credentials', { url: 'https://[email protected]/omdsh-dev/DSH-better-sidebar' }],
['repository with query text', { url: 'https://github.com/omdsh-dev/DSH-better-sidebar?tab=readme' }],
['control character in item id', { id: 'omdsh-dev/DSH-better-sidebar\u0000hidden' }],
] as const)('drops a catalog item with %s', async (_label, itemOverrides) => {
const snapshot = await adapt([{
kind: 'npm',
spec: 'dsh-better-sidebar',
verification: 'verified',
code: 'repository_backlink',
requiresBuildAllowance: false,
revision: '0.12.3',
}], itemOverrides)
expect(snapshot.items).toEqual([])
expect(snapshot.page).toEqual({ total: 0 })
})
it('scans the full normalized catalog beyond discovery page one with one registry read', async () => {
const packages = Array.from({ length: 205 }, (_, index) => {
const suffix = String(index).padStart(3, '0')
@@ -6,6 +6,8 @@ import {
createRestrictedImageFetcher,
marketMediaAssetUrl,
normalizeMarketImage,
normalizeAllowedHostnames,
validateRemoteImageUrl,
type MarketMediaCandidate,
} from '../src/media/index.js'
@@ -156,6 +158,47 @@ describe('market media service', () => {
})
describe('restricted market image fetcher', () => {
it('normalizes reviewed hostnames without accepting wildcards, ports, paths, or IP literals', () => {
expect(normalizeAllowedHostnames([
'avatars.githubusercontent.com',
'GitHub.com',
'github.com',
])).toEqual(['avatars.githubusercontent.com', 'github.com'])
for (const value of [
'',
'*.github.com',
'github.com/avatar.png',
'github.com:443',
'127.0.0.1',
'[email protected]',
]) {
expect(() => normalizeAllowedHostnames([value]), value)
.toThrow(MarketMediaError)
}
})
it('validates remote image URLs against the exact reviewed host set', () => {
const allowed = new Set(['github.com', 'avatars.githubusercontent.com'])
expect(validateRemoteImageUrl('https://github.com/anywhere-labs.png?size=128', allowed).href)
.toBe('https://github.com/anywhere-labs.png?size=128')
expect(validateRemoteImageUrl('https://github.com:443/anywhere-labs.png', allowed).href)
.toBe('https://github.com/anywhere-labs.png')
for (const value of [
'http://github.com/anywhere-labs.png',
'https://github.com:444/anywhere-labs.png',
'https://user:[email protected]/anywhere-labs.png',
'https://github.com/anywhere-labs.png#fragment',
'https://github.com.attacker.example/anywhere-labs.png',
'not a url',
]) {
expect(() => validateRemoteImageUrl(value, allowed), value)
.toThrow(MarketMediaError)
}
})
it('pins every redirect DNS lookup and permits only adapter-reviewed hosts', async () => {
const lookupAddresses = vi.fn(async (_hostname: string) => [{ address: '93.184.216.34', family: 4 as const }])
const request = vi.fn()
@@ -0,0 +1,84 @@
import { beforeEach, describe, expect, it, vi } from 'vitest'
const hooks = vi.hoisted(() => ({
resolve: undefined as undefined | ((
specifier: string,
context: { parentURL?: string },
nextResolve: (specifier: string, context: { parentURL?: string }) => unknown,
) => unknown),
deregister: vi.fn(),
}))
vi.mock('node:module', () => ({
registerHooks: vi.fn((definition: { resolve: typeof hooks.resolve }) => {
hooks.resolve = definition.resolve
return { deregister: hooks.deregister }
}),
}))
const { installProfilePackageResolver } = await import('../src/module-resolution.ts')
describe('installProfilePackageResolver', () => {
beforeEach(() => {
hooks.resolve = undefined
hooks.deregister.mockClear()
})
it('routes Loader bare imports through the selected profile and keeps relative imports unchanged', async () => {
const profileBaseUrl = 'file:///C:/Users/test/profile/'
const dispose = installProfilePackageResolver(profileBaseUrl)
const nextResolve = vi.fn(async (specifier: string, context: { parentURL?: string }) => ({
specifier,
context,
}))
const loaderEntryUrl = import.meta.resolve('@deepseek-ai/cordis-plugin-loader')
expect(hooks.resolve?.(
'dsh-plugin-desktop',
{ parentURL: loaderEntryUrl },
nextResolve,
)).toEqual({
shortCircuit: true,
url: new URL('../lib/index.js', new URL('../src/module-resolution.ts', import.meta.url)).href,
})
await expect(hooks.resolve?.(
'left-pad',
{ parentURL: loaderEntryUrl },
nextResolve,
)).resolves.toEqual({
specifier: 'left-pad',
context: { parentURL: profileBaseUrl },
})
await expect(hooks.resolve?.(
'./relative.js',
{ parentURL: loaderEntryUrl },
nextResolve,
)).resolves.toEqual({
specifier: './relative.js',
context: { parentURL: loaderEntryUrl },
})
await expect(hooks.resolve?.(
'left-pad',
{ parentURL: 'file:///C:/Users/test/other.js' },
nextResolve,
)).resolves.toEqual({
specifier: 'left-pad',
context: { parentURL: 'file:///C:/Users/test/other.js' },
})
dispose()
expect(hooks.deregister).toHaveBeenCalledTimes(1)
})
it('deregisters hooks only once even if the disposer is reused', () => {
const dispose = installProfilePackageResolver('file:///C:/Users/test/profile/')
dispose()
dispose()
expect(hooks.deregister).toHaveBeenCalledTimes(1)
})
})