From f6a74b0cab30c2c42c9301bc4e515fbba602f626 Mon Sep 17 00:00:00 2001 From: Boris Starkov Date: Thu, 22 Jan 2026 15:09:10 +0000 Subject: [PATCH] fix --- src/__tests__/utils.test.ts | 97 +++++++++++++++++++++++++++++++++++++ src/shared/utils.ts | 8 ++- 2 files changed, 103 insertions(+), 2 deletions(-) diff --git a/src/__tests__/utils.test.ts b/src/__tests__/utils.test.ts index b09bdfd..571778f 100644 --- a/src/__tests__/utils.test.ts +++ b/src/__tests__/utils.test.ts @@ -537,6 +537,103 @@ describe("Utils", () => { } }); }); + + it("should preserve dynamic_variables keys in toCamelCaseKeys", () => { + // This is what a test config looks like after being pulled from the API (snake_case) + const input = { + test_config: { + dynamic_variables: { + "damage_id": "123", + "user_name": "Jan", + "order_status": "pending" + }, + some_other_field: "value" + } + }; + + const result = toCamelCaseKeys(input); + + // dynamic_variables keys should be preserved (they are user-defined variable names) + expect(result).toEqual({ + testConfig: { + dynamicVariables: { + "damage_id": "123", // preserved - user-defined variable name + "user_name": "Jan", // preserved - user-defined variable name + "order_status": "pending" // preserved - user-defined variable name + }, + someOtherField: "value" // converted - regular field + } + }); + }); + + it("should preserve dynamicVariables keys in toSnakeCaseKeys", () => { + // This is what a test config looks like after being returned from the API (camelCase) + const input = { + testConfig: { + dynamicVariables: { + "damage_id": "123", + "user_name": "Jan", + "order_status": "pending" + }, + someOtherField: "value" + } + }; + + const result = toSnakeCaseKeys(input); + + // dynamicVariables keys should be preserved (they are user-defined variable names) + expect(result).toEqual({ + test_config: { + dynamic_variables: { + "damage_id": "123", // preserved - user-defined variable name + "user_name": "Jan", // preserved - user-defined variable name + "order_status": "pending" // preserved - user-defined variable name + }, + some_other_field: "value" // converted - regular field + } + }); + }); + + it("should maintain round-trip conversion symmetry for dynamic_variables", () => { + // Simulate pull → push cycle for tests + const originalTestConfig = { + dynamic_variables: { + "damage_id": "123", + "user_name": "Jan", + "complex_key_name": "value" + }, + success_examples: [], + failure_examples: [] + }; + + // Simulate push (local file → API): snake_case → camelCase + const afterPush = toCamelCaseKeys(originalTestConfig); + + // Verify variable names are preserved after push + expect(afterPush).toEqual({ + dynamicVariables: { + "damage_id": "123", // preserved + "user_name": "Jan", // preserved + "complex_key_name": "value" // preserved + }, + successExamples: [], + failureExamples: [] + }); + + // Simulate pull (API → local file): camelCase → snake_case + const afterPull = toSnakeCaseKeys(afterPush); + + // Verify round-trip preserves variable names + expect(afterPull).toEqual({ + dynamic_variables: { + "damage_id": "123", // preserved through round-trip + "user_name": "Jan", // preserved through round-trip + "complex_key_name": "value" // preserved through round-trip + }, + success_examples: [], + failure_examples: [] + }); + }); }); describe("generateUniqueFilename", () => { diff --git a/src/shared/utils.ts b/src/shared/utils.ts index 3196cd8..0f8e52c 100644 --- a/src/shared/utils.ts +++ b/src/shared/utils.ts @@ -133,7 +133,9 @@ export function toCamelCaseKeys(value: T, skipHeaderConversion: boo result[k] = toCamelCaseKeys(v, false); } else { // Normal conversion - result[toCamelCaseKey(k)] = toCamelCaseKeys(v, k === 'request_headers' ? 'names-only' : false); + // Preserve keys for request_headers (HTTP header names) and dynamic_variables (user-defined variable names) + const preserveKeys = k === 'request_headers' || k === 'dynamic_variables'; + result[toCamelCaseKey(k)] = toCamelCaseKeys(v, preserveKeys ? 'names-only' : false); } } return (result as unknown) as T; @@ -156,7 +158,9 @@ export function toSnakeCaseKeys(value: T, skipHeaderConversion: boo result[k] = toSnakeCaseKeys(v, false); } else { // Normal conversion - result[toSnakeCaseKey(k)] = toSnakeCaseKeys(v, k === 'request_headers' || k === 'requestHeaders' ? 'names-only' : false); + // Preserve keys for request_headers (HTTP header names) and dynamic_variables (user-defined variable names) + const preserveKeys = k === 'request_headers' || k === 'requestHeaders' || k === 'dynamic_variables' || k === 'dynamicVariables'; + result[toSnakeCaseKey(k)] = toSnakeCaseKeys(v, preserveKeys ? 'names-only' : false); } } return (result as unknown) as T;