@redocly/respect-core
Version:
API testing framework core
99 lines • 4.24 kB
JavaScript
import { dirname, resolve } from 'node:path';
import { bundleOpenApi } from '../../description-parser/index.js';
import { createFaker } from '../../faker.js';
import { infoSubstitute } from '../../arazzo-description-generator/index.js';
import { formatCliInputs } from '../inputs/index.js';
import { bundleArazzo } from '../get-test-description-from-file.js';
import { getNestedValue } from '../../../utils/get-nested-value.js';
import { getPublicWorkflows } from './set-public-workflows.js';
import { resolveSeverityConfiguration } from '../../checks/index.js';
const faker = createFaker();
export async function createTestContext(testDescription, options, apiClient) {
const sourceDescriptions = testDescription?.sourceDescriptions;
const bundledDescriptions = {};
if (sourceDescriptions) {
await Promise.all(sourceDescriptions.map(async (sourceDescription) => {
if (sourceDescription.type === 'openapi') {
const parsedDocument = await bundleOpenApi({
descriptionPath: sourceDescription.url,
config: options.config,
base: options.filePath,
externalRefResolver: options?.externalRefResolver,
});
const { paths, servers, info, security, components } = parsedDocument;
bundledDescriptions[sourceDescription.name] = {
paths,
servers,
info,
security,
components,
};
}
else if (sourceDescription.type === 'arazzo') {
const { url: sourceDescriptionPath, name } = sourceDescription;
const filePath = resolve(dirname(options.filePath), sourceDescriptionPath);
const bundledTestDescription = await bundleArazzo({
filePath,
version: options?.version,
logger: options.logger,
externalRefResolver: options?.externalRefResolver,
skipLint: options?.skipLint,
});
bundledDescriptions[name] = bundledTestDescription;
}
}));
}
for (const workflow of testDescription.workflows || []) {
for (const step of workflow.steps) {
step.checks = []; // we are mutating the copy of the arazzo file
}
}
const ctx = {
$response: undefined,
$request: undefined,
$inputs: { env: {} },
$faker: faker,
$sourceDescriptions: bundledDescriptions,
$workflows: getPublicWorkflows({
workflows: testDescription.workflows || [],
inputs: formatCliInputs(options?.input),
env: options.envVariables || {},
}),
$steps: {},
$components: testDescription.components || {},
$outputs: {},
executedSteps: [],
workflows: testDescription.workflows || [],
options,
testDescription,
info: testDescription.info || infoSubstitute,
arazzo: testDescription.arazzo || '',
sourceDescriptions: testDescription.sourceDescriptions || [],
noSecretsMasking: options.noSecretsMasking || false,
secretsSet: new Set(),
severity: resolveSeverityConfiguration(options.severity),
apiClient,
};
// Collect all secret fields from the input schema and the workflow inputs
for (const workflow of testDescription.workflows || []) {
if (workflow.inputs) {
collectSecretValues(ctx, workflow.inputs, ctx.$workflows[workflow.workflowId].inputs);
}
}
return ctx;
}
export function collectSecretValues(ctx, schema, inputs, path = []) {
if (!schema || !inputs)
return;
const inputValue = getNestedValue(inputs, path);
if (schema.format === 'password' && inputValue) {
ctx.secretsSet.add(inputValue);
}
if (schema.properties) {
Object.entries(schema.properties).forEach(([key, value]) => {
const currentPath = [...path, key];
collectSecretValues(ctx, value, inputs, currentPath);
});
}
}
//# sourceMappingURL=create-test-context.js.map