visual-journal / scripts /hf-space-doctor-utils.test.mjs
misonL's picture
Deploy 4566102 to Docker Space
3e8ea5d verified
Raw
History Blame Contribute Delete
5.09 kB
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import { resolve } from 'node:path';
import { pathToFileURL } from 'node:url';
import {
assertKnownOptions,
assertSpaceTargetConfig,
buildNextActions,
classifyRequiredAndRecommendedNames,
getJsonKeyValues,
getJsonNames,
isMainModule,
readOptionValue,
runDoctorCommand,
validateSpaceId,
validateSpaceUrl
} from './hf-space-doctor-utils.mjs';
describe('HF Space doctor utilities', () => {
it('parses hf CLI JSON output after hint lines', () => {
const names = getJsonNames(
[
'Hint: Use `hf spaces variables add user/space -e KEY=VALUE` to add variables.',
'[{"key":"APP_PASSWORD"},{"key":"AGENT_API_TOKEN"}]'
].join('\n')
);
assert.deepEqual([...names], ['APP_PASSWORD', 'AGENT_API_TOKEN']);
});
it('does not treat square brackets in hint text as JSON', () => {
const names = getJsonNames(
[
'Hint: Usage: hf spaces secrets list [OPTIONS] SPACE_ID',
'[{"key":"OPENAI_API_KEY"}]'
].join('\n')
);
assert.deepEqual([...names], ['OPENAI_API_KEY']);
});
it('parses hf CLI variable values after hint lines', () => {
const values = getJsonKeyValues(
[
'Hint: Use `hf spaces variables add user/space -e KEY=VALUE` to add variables.',
'[{"key":"AGENT_STATE_BACKEND","value":"memory"},{"key":"NEXT_PUBLIC_IMAGE_STORAGE_MODE","value":"indexeddb"}]'
].join('\n')
);
assert.deepEqual([...values], [
['AGENT_STATE_BACKEND', 'memory'],
['NEXT_PUBLIC_IMAGE_STORAGE_MODE', 'indexeddb']
]);
});
it('keeps auth remediation broad enough for network and token failures', () => {
const actions = buildNextActions([
{
status: 'fail',
name: 'hf-auth',
message: 'hf CLI auth check failed.',
error: 'TLS failed while checking auth'
}
]);
assert.equal(actions.length, 1);
assert.match(actions[0], /network\/proxy/);
assert.match(actions[0], /hf auth login/);
});
it('classifies required and recommended remote variables separately', () => {
const result = classifyRequiredAndRecommendedNames(
new Set(['AGENT_STATE_BACKEND', 'NEXT_PUBLIC_IMAGE_STORAGE_MODE']),
['AGENT_STATE_BACKEND', 'NEXT_PUBLIC_IMAGE_STORAGE_MODE'],
['APP_LOG_LEVEL']
);
assert.deepEqual(result, {
missingRequired: [],
missingRecommended: ['APP_LOG_LEVEL']
});
});
it('detects the main module with file URL encoding', () => {
const argvPath = 'scripts/path with space.mjs';
const moduleUrl = pathToFileURL(resolve(argvPath)).href;
assert.equal(isMainModule(moduleUrl, argvPath), true);
assert.equal(isMainModule(moduleUrl, undefined), false);
});
it('validates Hugging Face Space target config consistently', () => {
assert.equal(validateSpaceId('example/demo'), undefined);
assert.equal(validateSpaceId('demo'), undefined);
assert.equal(validateSpaceUrl('https://example-demo.hf.space'), undefined);
assert.match(validateSpaceId('a/b/c'), /space_name or namespace\/space_name/);
assert.match(validateSpaceId('.bad/demo'), /cannot start/);
assert.match(validateSpaceId('bad--name/demo'), /cannot start/);
assert.match(validateSpaceId('bad.git/demo'), /cannot start/);
assert.match(validateSpaceId(`${'a'.repeat(97)}/demo`), /1-96 characters/);
assert.match(validateSpaceUrl('https://example.com'), /\.hf\.space/);
assert.match(validateSpaceUrl('https://user:pass@example-demo.hf.space'), /plain Space origin/);
assert.match(validateSpaceUrl('https://example-demo.hf.space/share/abc'), /plain Space origin/);
assert.match(validateSpaceUrl('https://example-demo.hf.space?token=secret'), /plain Space origin/);
assert.throws(
() =>
assertSpaceTargetConfig({
spaceId: 'example/demo',
spaceUrl: 'https://example.com'
}),
/\.hf\.space/
);
});
it('rejects unknown CLI options and blank inline option values', () => {
assert.doesNotThrow(() => assertKnownOptions(['--skip-remote'], ['--skip-remote']));
assert.throws(() => assertKnownOptions(['--unknown'], ['--skip-remote']), /Unknown option/);
assert.throws(() => readOptionValue(['--space-id='], '--space-id'), /requires a value/);
});
it('times out direct doctor commands instead of hanging', () => {
const result = runDoctorCommand(process.execPath, ['-e', 'setTimeout(() => {}, 1000)'], { timeoutMs: 100 });
assert.equal(result.ok, false);
assert.match(result.error, /timed out|ETIMEDOUT|SIGTERM/i);
});
});