mirror of
https://gh-proxy.org/https://github.com/klinsmaya/workdsh.git
synced 2026-11-11 02:46:56 +08:00
test: add self-verifying coverage for boundaries
This commit is contained in:
@@ -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)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user