registry.test.ts
1 /** 2 * Tests for registry.ts: Strategy enum, cli() registration, helpers. 3 */ 4 5 import { describe, it, expect, beforeEach } from 'vitest'; 6 import { cli, getRegistry, fullName, strategyLabel, registerCommand, Strategy, type CliCommand } from './registry.js'; 7 8 describe('cli() registration', () => { 9 it('registers a command and returns it', () => { 10 const cmd = cli({ 11 site: 'test-registry', 12 name: 'hello', 13 description: 'A test command', 14 strategy: Strategy.PUBLIC, 15 browser: false, 16 }); 17 18 expect(cmd.site).toBe('test-registry'); 19 expect(cmd.name).toBe('hello'); 20 expect(cmd.strategy).toBe(Strategy.PUBLIC); 21 expect(cmd.browser).toBe(false); 22 expect(cmd.args).toEqual([]); 23 }); 24 25 it('puts registered command in the registry', () => { 26 cli({ 27 site: 'test-registry', 28 name: 'registered', 29 description: 'test', 30 }); 31 32 const registry = getRegistry(); 33 expect(registry.has('test-registry/registered')).toBe(true); 34 }); 35 36 it('defaults strategy to COOKIE when browser is true', () => { 37 const cmd = cli({ 38 site: 'test-registry', 39 name: 'default-strategy', 40 }); 41 42 expect(cmd.strategy).toBe(Strategy.COOKIE); 43 expect(cmd.browser).toBe(true); 44 }); 45 46 it('defaults strategy to PUBLIC when browser is false', () => { 47 const cmd = cli({ 48 site: 'test-registry', 49 name: 'no-browser', 50 browser: false, 51 }); 52 53 expect(cmd.strategy).toBe(Strategy.PUBLIC); 54 }); 55 56 it('preserves LOCAL strategy on registration', () => { 57 const cmd = cli({ 58 site: 'test-registry', 59 name: 'local-strategy', 60 description: 'reads local credentials', 61 strategy: Strategy.LOCAL, 62 browser: false, 63 }); 64 65 expect(cmd.strategy).toBe(Strategy.LOCAL); 66 expect(cmd.browser).toBe(false); 67 }); 68 69 it('overwrites existing command on re-registration', () => { 70 cli({ site: 'test-registry', name: 'overwrite', description: 'v1' }); 71 cli({ site: 'test-registry', name: 'overwrite', description: 'v2' }); 72 73 const reg = getRegistry(); 74 expect(reg.get('test-registry/overwrite')?.description).toBe('v2'); 75 }); 76 77 it('registers aliases as alternate registry keys for the same command', () => { 78 const cmd = cli({ 79 site: 'test-registry', 80 name: 'canonical', 81 description: 'test aliases', 82 aliases: ['compat', 'legacy-name'], 83 }); 84 85 const registry = getRegistry(); 86 expect(cmd.aliases).toEqual(['compat', 'legacy-name']); 87 expect(registry.get('test-registry/canonical')).toBe(cmd); 88 expect(registry.get('test-registry/compat')).toBe(cmd); 89 expect(registry.get('test-registry/legacy-name')).toBe(cmd); 90 }); 91 92 it('preserves defaultFormat on the registered command', () => { 93 const cmd = cli({ 94 site: 'test-registry', 95 name: 'plain-default', 96 description: 'prefers plain output', 97 defaultFormat: 'plain', 98 }); 99 100 expect(cmd.defaultFormat).toBe('plain'); 101 expect(getRegistry().get('test-registry/plain-default')?.defaultFormat).toBe('plain'); 102 }); 103 }); 104 105 describe('fullName', () => { 106 it('returns site/name', () => { 107 const cmd: CliCommand = { 108 site: 'bilibili', name: 'hot', description: '', args: [], 109 }; 110 expect(fullName(cmd)).toBe('bilibili/hot'); 111 }); 112 }); 113 114 describe('strategyLabel', () => { 115 it('returns strategy string', () => { 116 const cmd: CliCommand = { 117 site: 'test', name: 'test', description: '', args: [], 118 strategy: Strategy.INTERCEPT, 119 }; 120 expect(strategyLabel(cmd)).toBe('intercept'); 121 }); 122 123 it('returns public when no strategy set', () => { 124 const cmd: CliCommand = { 125 site: 'test', name: 'test', description: '', args: [], 126 }; 127 expect(strategyLabel(cmd)).toBe('public'); 128 }); 129 }); 130 131 describe('registerCommand', () => { 132 it('registers a pre-built command', () => { 133 const cmd: CliCommand = { 134 site: 'test-registry', 135 name: 'direct-reg', 136 description: 'directly registered', 137 args: [], 138 strategy: Strategy.HEADER, 139 browser: true, 140 }; 141 registerCommand(cmd); 142 143 const reg = getRegistry(); 144 expect(reg.get('test-registry/direct-reg')?.strategy).toBe(Strategy.HEADER); 145 }); 146 }); 147 148 describe('normalizeCommand (via registerCommand)', () => { 149 it('COOKIE + domain → navigateBefore is the domain URL', () => { 150 registerCommand({ 151 site: 'test-norm', name: 'cookie-domain', description: '', args: [], 152 strategy: Strategy.COOKIE, domain: 'x.com', 153 }); 154 const cmd = getRegistry().get('test-norm/cookie-domain')!; 155 expect(cmd.browser).toBe(true); 156 expect(cmd.navigateBefore).toBe('https://x.com'); 157 }); 158 159 it('COOKIE without domain → navigateBefore is true (auth context, no URL)', () => { 160 registerCommand({ 161 site: 'test-norm', name: 'cookie-nodomain', description: '', args: [], 162 strategy: Strategy.COOKIE, 163 }); 164 const cmd = getRegistry().get('test-norm/cookie-nodomain')!; 165 expect(cmd.browser).toBe(true); 166 expect(cmd.navigateBefore).toBe(true); 167 }); 168 169 it('INTERCEPT → navigateBefore is true (auth context)', () => { 170 registerCommand({ 171 site: 'test-norm', name: 'intercept', description: '', args: [], 172 strategy: Strategy.INTERCEPT, domain: 'example.com', 173 }); 174 const cmd = getRegistry().get('test-norm/intercept')!; 175 expect(cmd.browser).toBe(true); 176 expect(cmd.navigateBefore).toBe(true); 177 }); 178 179 it('PUBLIC → browser false, navigateBefore undefined', () => { 180 registerCommand({ 181 site: 'test-norm', name: 'public', description: '', args: [], 182 strategy: Strategy.PUBLIC, 183 }); 184 const cmd = getRegistry().get('test-norm/public')!; 185 expect(cmd.browser).toBe(false); 186 expect(cmd.navigateBefore).toBeUndefined(); 187 }); 188 189 it('LOCAL → browser false, navigateBefore undefined', () => { 190 registerCommand({ 191 site: 'test-norm', name: 'local', description: '', args: [], 192 strategy: Strategy.LOCAL, 193 }); 194 const cmd = getRegistry().get('test-norm/local')!; 195 expect(cmd.strategy).toBe(Strategy.LOCAL); 196 expect(strategyLabel(cmd)).toBe('local'); 197 expect(cmd.browser).toBe(false); 198 expect(cmd.navigateBefore).toBeUndefined(); 199 }); 200 201 it('explicit navigateBefore: false overrides COOKIE + domain', () => { 202 registerCommand({ 203 site: 'test-norm', name: 'cookie-override', description: '', args: [], 204 strategy: Strategy.COOKIE, domain: 'amazon.com', navigateBefore: false, 205 }); 206 const cmd = getRegistry().get('test-norm/cookie-override')!; 207 expect(cmd.browser).toBe(true); 208 expect(cmd.navigateBefore).toBe(false); 209 }); 210 211 it('explicit navigateBefore URL overrides strategy default', () => { 212 registerCommand({ 213 site: 'test-norm', name: 'explicit-url', description: '', args: [], 214 strategy: Strategy.COOKIE, domain: 'x.com', 215 navigateBefore: 'https://x.com/explore', 216 }); 217 const cmd = getRegistry().get('test-norm/explicit-url')!; 218 expect(cmd.navigateBefore).toBe('https://x.com/explore'); 219 }); 220 });