Files
MyIP/tests/tool-availability.test.js
T
Claude 96525d2fc7 Chore: trim the branch — leftovers, redundancy, comments
A pass over every file the branch touched, after the iOS animation hunt
left tries and reverts behind it. Removed what nothing reaches: the
view-transition rule for a transition no code starts, an unreachable
guard in the transition hook, a no-op KeepAlive key branch, a sign-in
guard the menu already enforces, usage-dialog wrappers that only
forwarded to the store, a duplicated modifier-click check and card
filter (isPlainClick / listedTools), a test that hand-rolled
listedTools, a drawer-era fixture parameter. auth-flow.js folded into
auth-redirect.js. Comments cut to what the code cannot say itself —
file headers of a few lines, the measured iOS reasons, non-obvious
orderings — and stale ones fixed (Nav under KeepAlive, Home.vue
reusing DEFAULT_META, "from Nav", enabledCards). AGENTS.md sections
tightened to the code as it is now.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013GbLTGMZ45MV78qd2tHoco
2026-10-05 16:50:16 +00:00

86 lines
3.8 KiB
JavaScript

// Tests for frontend/utils/tool-availability.js — the listing gate the
// Advanced Tools card grid and nav filter through — plus the gate fields the
// registry in frontend/data/tools.js declares.
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import { isToolAvailable, listedTools } from '../frontend/utils/tool-availability.js';
import { ADVANCED_TOOLS, TOOL_BY_SLUG } from '../frontend/data/tools.js';
const PUBLIC = { slug: 'public' };
const ORIGINAL = { slug: 'original', requiresOriginalSite: true };
const RADAR = { slug: 'radar', requiresConfig: 'cloudFlare' };
const BOTH = { slug: 'both', requiresOriginalSite: true, requiresConfig: 'cloudFlare' };
describe('isToolAvailable', () => {
it('an ungated tool is always available', () => {
assert.equal(isToolAvailable(PUBLIC, {}), true);
assert.equal(isToolAvailable(PUBLIC, undefined), true);
assert.equal(isToolAvailable(PUBLIC, { originalSite: false, cloudFlare: false }), true);
});
it('a gated tool is unavailable until configs land', () => {
assert.equal(isToolAvailable(ORIGINAL, {}), false);
assert.equal(isToolAvailable(RADAR, {}), false);
assert.equal(isToolAvailable(RADAR, null), false);
});
it('requiresOriginalSite follows configs.originalSite', () => {
assert.equal(isToolAvailable(ORIGINAL, { originalSite: true }), true);
assert.equal(isToolAvailable(ORIGINAL, { originalSite: false }), false);
});
it('requiresConfig follows the named configs flag', () => {
assert.equal(isToolAvailable(RADAR, { cloudFlare: true }), true);
assert.equal(isToolAvailable(RADAR, { cloudFlare: false }), false);
assert.equal(isToolAvailable(RADAR, { map: true }), false);
});
it('both gates must pass', () => {
assert.equal(isToolAvailable(BOTH, { originalSite: true, cloudFlare: true }), true);
assert.equal(isToolAvailable(BOTH, { originalSite: true, cloudFlare: false }), false);
assert.equal(isToolAvailable(BOTH, { originalSite: false, cloudFlare: true }), false);
});
it('no tool is unavailable', () => {
assert.equal(isToolAvailable(null, { cloudFlare: true }), false);
assert.equal(isToolAvailable(undefined, {}), false);
});
});
describe('listedTools', () => {
const tools = [PUBLIC, ORIGINAL, RADAR, BOTH];
const slugs = (list) => list.map((tool) => tool.slug);
it('applies the gates in registry order', () => {
assert.deepEqual(slugs(listedTools(tools, {})), ['public']);
assert.deepEqual(slugs(listedTools(tools, { originalSite: true })), ['public', 'original']);
assert.deepEqual(slugs(listedTools(tools, { originalSite: false, cloudFlare: true })), ['public', 'radar']);
assert.deepEqual(slugs(listedTools(tools, { originalSite: true, cloudFlare: true })),
['public', 'original', 'radar', 'both']);
});
it('lists every registered tool once all gates pass', () => {
const configs = { originalSite: true, cloudFlare: true };
assert.equal(listedTools(ADVANCED_TOOLS, configs).length, ADVANCED_TOOLS.length);
});
});
describe('registry gates (data/tools.js)', () => {
it('ASN Profile is gated on the Cloudflare Radar key only', () => {
const asn = TOOL_BY_SLUG.get('asn');
assert.ok(asn, 'asn tool is registered');
assert.equal(asn.requiresConfig, 'cloudFlare');
assert.equal(asn.requiresOriginalSite, undefined);
assert.equal(isToolAvailable(asn, { cloudFlare: false, originalSite: true }), false);
assert.equal(isToolAvailable(asn, { cloudFlare: true, originalSite: false }), true);
});
it('every requiresConfig is a non-empty string', () => {
for (const tool of ADVANCED_TOOLS.filter((entry) => 'requiresConfig' in entry)) {
assert.equal(typeof tool.requiresConfig, 'string', tool.slug);
assert.ok(tool.requiresConfig.length > 0, tool.slug);
}
});
});