From 8b484e41c21345497c902b6a771552a8f33fe83c Mon Sep 17 00:00:00 2001 From: Shalahuddin Date: Sat, 11 Jul 2026 02:47:41 +0700 Subject: [PATCH] fix(config): normalize empty/whitespace TESTSPRITE_PROFILE to unset --- src/lib/config.test.ts | 17 +++++++++++++++++ src/lib/config.ts | 10 +++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/lib/config.test.ts b/src/lib/config.test.ts index cf56eaf..2a58fc8 100644 --- a/src/lib/config.test.ts +++ b/src/lib/config.test.ts @@ -55,6 +55,23 @@ describe('loadConfig', () => { ).toBe('option-profile'); }); + it('treats empty TESTSPRITE_PROFILE as unset (falls back to default)', () => { + expect(loadConfig({ env: { TESTSPRITE_PROFILE: '' }, credentialsPath }).profile).toBe( + 'default', + ); + }); + + it('treats whitespace-only TESTSPRITE_PROFILE as unset (falls back to default)', () => { + const config = loadConfig({ env: { TESTSPRITE_PROFILE: ' ' }, credentialsPath }); + expect(config.profile).toBe('default'); + }); + + it('reads credentials from the default profile when TESTSPRITE_PROFILE is blank', () => { + writeProfile('default', { apiKey: 'sk-default' }, { path: credentialsPath }); + const config = loadConfig({ env: { TESTSPRITE_PROFILE: ' ' }, credentialsPath }); + expect(config.apiKey).toBe('sk-default'); + }); + it('option.endpointUrl overrides everything', () => { writeProfile('default', { apiUrl: 'https://file' }, { path: credentialsPath }); const config = loadConfig({ diff --git a/src/lib/config.ts b/src/lib/config.ts index 7f8065f..a69f2e4 100644 --- a/src/lib/config.ts +++ b/src/lib/config.ts @@ -39,13 +39,17 @@ export function defaultConfigPath(): string { */ export function loadConfig(options: LoadConfigOptions = {}): Config { const env = options.env ?? process.env; - const profile = options.profile ?? env.TESTSPRITE_PROFILE ?? DEFAULT_PROFILE; + const profile = options.profile ?? normalizeEnvVar(env.TESTSPRITE_PROFILE) ?? DEFAULT_PROFILE; const credentialsPath = options.credentialsPath ?? defaultCredentialsPath(); const fileEntry = readProfile(profile, { path: credentialsPath }); // Empty / whitespace-only env vars are treated as unset so they do not - // short-circuit the `??` chain (e.g. `export TESTSPRITE_API_URL=` in a shell - // profile). Matches the normalization in auth configure and init/setup. + // short-circuit the `??` chain (e.g. `export TESTSPRITE_API_URL=` or + // `export TESTSPRITE_PROFILE=` in a shell profile). For the profile this + // also avoids a confusing VALIDATION_ERROR: an empty name fails the INI + // section-name guard, so without normalization a blank env var would break + // every command instead of falling back to the default profile. Matches the + // normalization in auth configure and init/setup. const envApiUrl = normalizeEnvVar(env.TESTSPRITE_API_URL); const envApiKey = normalizeEnvVar(env.TESTSPRITE_API_KEY);