diff --git a/packages/bruno-api-docs/src/hooks/useVariableResolver.spec.tsx b/packages/bruno-api-docs/src/hooks/useVariableResolver.spec.tsx index 22b79ac1..3f9af104 100644 --- a/packages/bruno-api-docs/src/hooks/useVariableResolver.spec.tsx +++ b/packages/bruno-api-docs/src/hooks/useVariableResolver.spec.tsx @@ -141,3 +141,61 @@ describe('lookup (variable hover card)', () => { expect(html).toContain('undefined'); }); }); + +const NestedProbe: React.FC = () => { + const r = useResolvedVariables(); + return ( +
+ {r.resolve('{{endpoint}}')} + {r.interpolate('{{endpoint}}')} +
+ ); +}; + +describe('nested variable resolution', () => { + const nested = { + request: { + variables: [ + { name: 'endpoint', value: '{{host}}/v1' }, + { name: 'host', value: 'https://api.test' } + ] + }, + config: { environments: [{ name: 'Dev', variables: [] }] } + } as unknown as typeof collection; + + it('follows a variable that points at another variable, for display and for interpolation', () => { + const store = createOpenCollectionStore(); + store.dispatch(setDocsCollection(nested)); + store.dispatch(setActiveEnv('Dev')); + store.dispatch(setShowVars(true)); + + const html = renderToStaticMarkup( + + + + + + ); + + expect(html).toContain('https://api.test/v1'); + expect(html).toContain('https://api.test/v1'); + }); + + it('gates resolve on showVars but never interpolate', () => { + const store = createOpenCollectionStore(); + store.dispatch(setDocsCollection(nested)); + store.dispatch(setActiveEnv('Dev')); + store.dispatch(setShowVars(false)); + + const html = renderToStaticMarkup( + + + + + + ); + + expect(html).toContain('{{endpoint}}'); + expect(html).toContain('https://api.test/v1'); + }); +}); diff --git a/packages/bruno-api-docs/src/hooks/useVariableResolver.tsx b/packages/bruno-api-docs/src/hooks/useVariableResolver.tsx index e88b2224..f07b9d64 100644 --- a/packages/bruno-api-docs/src/hooks/useVariableResolver.tsx +++ b/packages/bruno-api-docs/src/hooks/useVariableResolver.tsx @@ -12,7 +12,7 @@ import { getItemUuid } from '@/utils/itemUtils'; import { mockDataFunctions, timeBasedDynamicVars } from '@/runner/utils/faker-functions'; import { buildScopedVariableModel, - resolveVariables, + resolveValueDeep, singleReferenceName, detectSpecialScope, isValidVariableName, @@ -95,7 +95,7 @@ const makeResolver = ( activeEnvName: string | null ): VariableResolver => { const isSecret = (name: string) => model.secretNames.has(name.trim()); - const interpolate = (raw: string) => resolveVariables(raw, model.values); + const interpolate = (raw: string) => resolveValueDeep(raw, model.values); return { showVars, activeEnvName, @@ -263,7 +263,7 @@ export const ItemVariableResolverProvider: React.FC<{ ); const interpolateWithSecrets = useCallback( - (raw: string) => resolveVariables(raw, model.fullValues), + (raw: string) => resolveValueDeep(raw, model.fullValues), [model] );