import { expect, tap } from '@git.zone/tstest/tapbundle'; import * as npmextra from '../ts/index.js'; // Test environment variable with boolean false value tap.test('should handle boolean false values in nested objects correctly', async () => { // Set up test environment variable process.env['S3_USESSL'] = 'false'; process.env['S3_ENDPOINT'] = 'https://s3.example.com'; process.env['S3_REGION'] = 'us-east-1'; process.env['S3_ACCESSKEY'] = 'test-key'; process.env['S3_ACCESSSECRET'] = 'test-secret'; // Create AppData with nested object structure similar to CloudlyConfig const appData = await npmextra.AppData.createAndInit({ ephemeral: true, // Use in-memory storage for testing envMapping: { s3Descriptor: { endpoint: 'S3_ENDPOINT', region: 'S3_REGION', accessKey: 'S3_ACCESSKEY', accessSecret: 'S3_ACCESSSECRET', useSsl: 'boolean:S3_USESSL' } } }); // Get the kvStore and read the configuration const kvStore = await appData.getKvStore(); const s3Descriptor = await kvStore.readKey('s3Descriptor'); console.log('\n=== Test Results ==='); console.log('S3 Descriptor:', JSON.stringify(s3Descriptor, null, 2)); console.log('useSsl value:', s3Descriptor?.useSsl); console.log('useSsl type:', typeof s3Descriptor?.useSsl); console.log('useSsl === false:', (s3Descriptor?.useSsl as any) === false); // Verify the values expect(s3Descriptor).toBeTruthy(); expect(s3Descriptor.endpoint).toEqual('https://s3.example.com'); expect(s3Descriptor.region).toEqual('us-east-1'); expect(s3Descriptor.accessKey).toEqual('test-key'); expect(s3Descriptor.accessSecret).toEqual('test-secret'); // Critical test: useSsl should be false, not undefined expect(s3Descriptor.useSsl).toEqual(false); expect(typeof s3Descriptor.useSsl).toEqual('boolean'); expect(s3Descriptor.useSsl).not.toBeUndefined(); }); tap.test('should handle various boolean representations correctly', async () => { // Test different boolean representations const testCases = [ { env: 'false', expected: false }, { env: 'FALSE', expected: false }, { env: '0', expected: false }, { env: 'no', expected: false }, { env: 'NO', expected: false }, { env: 'n', expected: false }, { env: 'off', expected: false }, { env: 'true', expected: true }, { env: 'TRUE', expected: true }, { env: '1', expected: true }, { env: 'yes', expected: true }, { env: 'YES', expected: true }, { env: 'y', expected: true }, { env: 'on', expected: true }, ]; for (const testCase of testCases) { process.env['TEST_BOOL'] = testCase.env; const appData = await npmextra.AppData.createAndInit({ ephemeral: true, envMapping: { testBool: 'boolean:TEST_BOOL' } }); const kvStore = await appData.getKvStore(); const testBool = await kvStore.readKey('testBool'); console.log(`Input "${testCase.env}" => ${testBool} (expected: ${testCase.expected})`); expect(testBool).toEqual(testCase.expected); } }); tap.test('should handle hardcoded boolean false values', async () => { // Test with hardcoded boolean false value const appData = await npmextra.AppData.createAndInit({ ephemeral: true, envMapping: { boolValue: 'hard_boolean:false' } }); const kvStore = await appData.getKvStore(); const boolValue = await kvStore.readKey('boolValue'); console.log('\n=== Hardcoded Boolean Test ==='); console.log('boolValue:', boolValue); console.log('type:', typeof boolValue); console.log('is false:', (boolValue as any) === false); expect(boolValue).toEqual(false); expect(typeof boolValue).toEqual('boolean'); }); tap.test('should not filter out other falsy values', async () => { process.env['ZERO_VALUE'] = '0'; process.env['EMPTY_STRING'] = ''; // This should be preserved as empty string const appData = await npmextra.AppData.createAndInit({ ephemeral: true, envMapping: { nested: { zeroAsNumber: 'ZERO_VALUE', // Should preserve "0" as string zeroAsBoolean: 'boolean:ZERO_VALUE', // Should convert to false emptyString: 'EMPTY_STRING', // Should preserve empty string hardcodedFalse: 'hard_boolean:false', // Should be false hardcodedZero: 'hard:0', // Should be "0" string } } }); const kvStore = await appData.getKvStore(); const nested = await kvStore.readKey('nested'); console.log('\n=== Falsy Values Test ==='); console.log('nested:', JSON.stringify(nested, null, 2)); expect(nested).toBeTruthy(); expect(nested.zeroAsNumber).toEqual('0'); expect(nested.zeroAsBoolean).toEqual(false); expect(nested.emptyString).toEqual(''); expect(nested.hardcodedFalse).toEqual(false); expect(nested.hardcodedZero).toEqual('0'); }); export default tap.start();