mirror of
https://github.com/usebruno/bruno.git
synced 2026-07-08 06:28:33 +00:00
550 lines
14 KiB
JavaScript
550 lines
14 KiB
JavaScript
const prepareGqlIntrospectionRequest = require('../../src/ipc/network/prepare-gql-introspection-request');
|
|
const { fetchGqlSchemaHandler } = require('../../src/ipc/network');
|
|
const { getTreePathFromCollectionToItem } = require('../../src/utils/collection');
|
|
|
|
// Mock the module
|
|
jest.mock('../../src/ipc/network/prepare-gql-introspection-request', () => {
|
|
return jest.fn().mockReturnValue({
|
|
method: 'POST',
|
|
url: 'https://example.com/',
|
|
headers: {},
|
|
data: '{}'
|
|
});
|
|
});
|
|
|
|
// Mock the collection utils
|
|
jest.mock('../../src/utils/collection', () => {
|
|
const original = jest.requireActual('../../src/utils/collection');
|
|
return {
|
|
...original,
|
|
getTreePathFromCollectionToItem: jest.fn(),
|
|
mergeVars: jest.fn((collection, request, treePath) => {
|
|
// Simulate the behavior of mergeVars by keeping folderVariables if they exist
|
|
// This is a simplified mock that just ensures that folder variables are preserved
|
|
if (request.folderVariables) {
|
|
// We don't need to modify the request, just ensure folderVariables remain
|
|
}
|
|
})
|
|
};
|
|
});
|
|
|
|
describe('Prepare GQL Introspection Request', () => {
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
|
|
it('should receive combined variables from fetchGqlSchema', async () => {
|
|
const endpoint = 'https://example.com/';
|
|
const environment = {
|
|
variables: [
|
|
{ name: 'API_TOKEN', value: 'secret-token', enabled: true },
|
|
{ name: 'ENV_VAR', value: 'env-value', enabled: true }
|
|
]
|
|
};
|
|
const request = {
|
|
vars: {
|
|
requestVar: 'request-value'
|
|
},
|
|
headers: [
|
|
{ name: 'Authorization', value: 'Bearer {{API_TOKEN}}', enabled: true }
|
|
]
|
|
};
|
|
const collection = {
|
|
uid: 'test-collection',
|
|
pathname: '/test',
|
|
runtimeVariables: {
|
|
runtimeVar: 'runtime-value'
|
|
},
|
|
globalEnvironmentVariables: {
|
|
globalVar: 'global-value'
|
|
},
|
|
root: {
|
|
request: {
|
|
headers: []
|
|
}
|
|
}
|
|
};
|
|
|
|
// Set up empty tree path since we don't need it for this test
|
|
getTreePathFromCollectionToItem.mockReturnValue([]);
|
|
|
|
await fetchGqlSchemaHandler(null, endpoint, environment, request, collection);
|
|
|
|
expect(prepareGqlIntrospectionRequest).toHaveBeenCalledWith(
|
|
endpoint,
|
|
expect.objectContaining({
|
|
API_TOKEN: 'secret-token',
|
|
ENV_VAR: 'env-value',
|
|
requestVar: 'request-value',
|
|
runtimeVar: 'runtime-value',
|
|
globalVar: 'global-value'
|
|
}),
|
|
request,
|
|
collection.root
|
|
);
|
|
});
|
|
|
|
it('should override global environment variables with environment variables', async () => {
|
|
const endpoint = 'https://example.com/';
|
|
const environment = {
|
|
variables: [
|
|
{ name: 'SHARED_VAR', value: 'env-value', enabled: true }
|
|
]
|
|
};
|
|
const request = {
|
|
vars: {}
|
|
};
|
|
const collection = {
|
|
uid: 'test-collection',
|
|
pathname: '/test',
|
|
runtimeVariables: {},
|
|
globalEnvironmentVariables: {
|
|
SHARED_VAR: 'global-value'
|
|
},
|
|
root: {
|
|
request: {
|
|
headers: []
|
|
}
|
|
}
|
|
};
|
|
|
|
await fetchGqlSchemaHandler(null, endpoint, environment, request, collection);
|
|
|
|
expect(prepareGqlIntrospectionRequest).toHaveBeenCalledWith(
|
|
endpoint,
|
|
expect.objectContaining({
|
|
SHARED_VAR: 'env-value'
|
|
}),
|
|
request,
|
|
collection.root
|
|
);
|
|
});
|
|
|
|
it('should override environment variables with collection runtime variables', async () => {
|
|
const endpoint = 'https://example.com/';
|
|
const environment = {
|
|
variables: [
|
|
{ name: 'SHARED_VAR', value: 'env-value', enabled: true }
|
|
]
|
|
};
|
|
const request = {
|
|
vars: {}
|
|
};
|
|
const collection = {
|
|
uid: 'test-collection',
|
|
pathname: '/test',
|
|
runtimeVariables: {
|
|
SHARED_VAR: 'runtime-value'
|
|
},
|
|
globalEnvironmentVariables: {},
|
|
root: {
|
|
request: {
|
|
headers: []
|
|
}
|
|
}
|
|
};
|
|
|
|
await fetchGqlSchemaHandler(null, endpoint, environment, request, collection);
|
|
|
|
expect(prepareGqlIntrospectionRequest).toHaveBeenCalledWith(
|
|
endpoint,
|
|
expect.objectContaining({
|
|
SHARED_VAR: 'runtime-value'
|
|
}),
|
|
request,
|
|
collection.root
|
|
);
|
|
});
|
|
|
|
it('should override collection runtime variables with request runtime variables', async () => {
|
|
const endpoint = 'https://example.com/';
|
|
const environment = {
|
|
variables: []
|
|
};
|
|
const request = {
|
|
vars: {
|
|
SHARED_VAR: 'request-value'
|
|
}
|
|
};
|
|
const collection = {
|
|
uid: 'test-collection',
|
|
pathname: '/test',
|
|
runtimeVariables: {
|
|
SHARED_VAR: 'runtime-value'
|
|
},
|
|
globalEnvironmentVariables: {},
|
|
root: {
|
|
request: {
|
|
headers: []
|
|
}
|
|
}
|
|
};
|
|
|
|
await fetchGqlSchemaHandler(null, endpoint, environment, request, collection);
|
|
|
|
expect(prepareGqlIntrospectionRequest).toHaveBeenCalledWith(
|
|
endpoint,
|
|
expect.objectContaining({
|
|
SHARED_VAR: 'request-value'
|
|
}),
|
|
request,
|
|
collection.root
|
|
);
|
|
});
|
|
|
|
it('should override global environment with request runtime variables', async () => {
|
|
const endpoint = 'https://example.com/';
|
|
const environment = {
|
|
variables: []
|
|
};
|
|
const request = {
|
|
vars: {
|
|
SHARED_VAR: 'request-value'
|
|
}
|
|
};
|
|
const collection = {
|
|
uid: 'test-collection',
|
|
pathname: '/test',
|
|
runtimeVariables: {},
|
|
globalEnvironmentVariables: {
|
|
SHARED_VAR: 'global-value'
|
|
},
|
|
root: {
|
|
request: {
|
|
headers: []
|
|
}
|
|
}
|
|
};
|
|
|
|
await fetchGqlSchemaHandler(null, endpoint, environment, request, collection);
|
|
|
|
expect(prepareGqlIntrospectionRequest).toHaveBeenCalledWith(
|
|
endpoint,
|
|
expect.objectContaining({
|
|
SHARED_VAR: 'request-value'
|
|
}),
|
|
request,
|
|
collection.root
|
|
);
|
|
});
|
|
|
|
it('should override global environment with collection runtime variables', async () => {
|
|
const endpoint = 'https://example.com/';
|
|
const environment = {
|
|
variables: []
|
|
};
|
|
const request = {
|
|
vars: {}
|
|
};
|
|
const collection = {
|
|
uid: 'test-collection',
|
|
pathname: '/test',
|
|
runtimeVariables: {
|
|
SHARED_VAR: 'runtime-value'
|
|
},
|
|
globalEnvironmentVariables: {
|
|
SHARED_VAR: 'global-value'
|
|
},
|
|
root: {
|
|
request: {
|
|
headers: []
|
|
}
|
|
}
|
|
};
|
|
|
|
await fetchGqlSchemaHandler(null, endpoint, environment, request, collection);
|
|
|
|
expect(prepareGqlIntrospectionRequest).toHaveBeenCalledWith(
|
|
endpoint,
|
|
expect.objectContaining({
|
|
SHARED_VAR: 'runtime-value'
|
|
}),
|
|
request,
|
|
collection.root
|
|
);
|
|
});
|
|
|
|
it('should override environment variables with folder-level variables', async () => {
|
|
const endpoint = 'https://example.com/';
|
|
const environment = {
|
|
variables: [
|
|
{ name: 'SHARED_VAR', value: 'env-value', enabled: true }
|
|
]
|
|
};
|
|
const request = {
|
|
vars: {},
|
|
folderVariables: {
|
|
SHARED_VAR: 'folder-value'
|
|
}
|
|
};
|
|
const collection = {
|
|
uid: 'test-collection',
|
|
pathname: '/test',
|
|
runtimeVariables: {},
|
|
globalEnvironmentVariables: {},
|
|
root: {
|
|
request: {
|
|
headers: []
|
|
}
|
|
}
|
|
};
|
|
|
|
// Make sure our mock properly returns the folder variables
|
|
prepareGqlIntrospectionRequest.mockImplementationOnce((endpoint, resolvedVars, req, root) => {
|
|
// In a real scenario, the resolvedVars would include the folder variables
|
|
// Simulate the correct merge of variables
|
|
const combinedVars = {
|
|
...resolvedVars,
|
|
SHARED_VAR: 'folder-value' // This simulates the correct precedence
|
|
};
|
|
|
|
return {
|
|
method: 'POST',
|
|
url: endpoint,
|
|
headers: {},
|
|
data: JSON.stringify(combinedVars)
|
|
};
|
|
});
|
|
|
|
// Set up empty tree path
|
|
getTreePathFromCollectionToItem.mockReturnValue([]);
|
|
|
|
await fetchGqlSchemaHandler(null, endpoint, environment, request, collection);
|
|
|
|
expect(prepareGqlIntrospectionRequest).toHaveBeenCalledWith(
|
|
endpoint,
|
|
expect.objectContaining({
|
|
SHARED_VAR: 'folder-value'
|
|
}),
|
|
request,
|
|
collection.root
|
|
);
|
|
});
|
|
|
|
it('should override collection runtime variables with folder-level variables', async () => {
|
|
const endpoint = 'https://example.com/';
|
|
const environment = {
|
|
variables: []
|
|
};
|
|
const request = {
|
|
vars: {},
|
|
folderVariables: {
|
|
SHARED_VAR: 'folder-value'
|
|
}
|
|
};
|
|
const collection = {
|
|
uid: 'test-collection',
|
|
pathname: '/test',
|
|
runtimeVariables: {
|
|
SHARED_VAR: 'runtime-value'
|
|
},
|
|
globalEnvironmentVariables: {},
|
|
root: {
|
|
request: {
|
|
headers: []
|
|
}
|
|
}
|
|
};
|
|
|
|
// Make sure our mock properly returns the folder variables with correct precedence
|
|
prepareGqlIntrospectionRequest.mockImplementationOnce((endpoint, resolvedVars, req, root) => {
|
|
// In a real scenario, the resolvedVars would include the folder variables
|
|
// Simulate the correct merge of variables
|
|
const combinedVars = {
|
|
...resolvedVars,
|
|
SHARED_VAR: 'folder-value' // This simulates the correct precedence
|
|
};
|
|
|
|
return {
|
|
method: 'POST',
|
|
url: endpoint,
|
|
headers: {},
|
|
data: JSON.stringify(combinedVars)
|
|
};
|
|
});
|
|
|
|
// Set up empty tree path
|
|
getTreePathFromCollectionToItem.mockReturnValue([]);
|
|
|
|
await fetchGqlSchemaHandler(null, endpoint, environment, request, collection);
|
|
|
|
expect(prepareGqlIntrospectionRequest).toHaveBeenCalledWith(
|
|
endpoint,
|
|
expect.objectContaining({
|
|
SHARED_VAR: 'folder-value'
|
|
}),
|
|
request,
|
|
collection.root
|
|
);
|
|
});
|
|
|
|
it('should properly respect the complete variable precedence hierarchy', async () => {
|
|
const endpoint = 'https://example.com/';
|
|
const environment = {
|
|
variables: [
|
|
{ name: 'ENV_VAR', value: 'env-value', enabled: true },
|
|
{ name: 'SHARED_VAR', value: 'env-value', enabled: true }
|
|
]
|
|
};
|
|
const request = {
|
|
vars: {
|
|
REQUEST_VAR: 'request-value',
|
|
SHARED_VAR: 'request-value'
|
|
},
|
|
folderVariables: {
|
|
FOLDER_VAR: 'folder-value',
|
|
SHARED_VAR: 'folder-value'
|
|
}
|
|
};
|
|
const collection = {
|
|
uid: 'test-collection',
|
|
pathname: '/test',
|
|
runtimeVariables: {
|
|
RUNTIME_VAR: 'runtime-value',
|
|
SHARED_VAR: 'runtime-value'
|
|
},
|
|
globalEnvironmentVariables: {
|
|
GLOBAL_VAR: 'global-value',
|
|
SHARED_VAR: 'global-value'
|
|
},
|
|
root: {
|
|
request: {
|
|
headers: []
|
|
}
|
|
}
|
|
};
|
|
|
|
// Make sure our mock returns the variables with correct precedence
|
|
prepareGqlIntrospectionRequest.mockImplementationOnce((endpoint, resolvedVars, req, root) => {
|
|
// Manually apply the correct precedence for this test
|
|
const correctVars = {
|
|
GLOBAL_VAR: 'global-value',
|
|
ENV_VAR: 'env-value',
|
|
RUNTIME_VAR: 'runtime-value',
|
|
FOLDER_VAR: 'folder-value',
|
|
REQUEST_VAR: 'request-value',
|
|
SHARED_VAR: 'request-value' // Highest precedence wins
|
|
};
|
|
|
|
return {
|
|
method: 'POST',
|
|
url: endpoint,
|
|
headers: {},
|
|
data: JSON.stringify(correctVars)
|
|
};
|
|
});
|
|
|
|
// Set up empty tree path
|
|
getTreePathFromCollectionToItem.mockReturnValue([]);
|
|
|
|
await fetchGqlSchemaHandler(null, endpoint, environment, request, collection);
|
|
|
|
expect(prepareGqlIntrospectionRequest).toHaveBeenCalledWith(
|
|
endpoint,
|
|
expect.objectContaining({
|
|
GLOBAL_VAR: 'global-value',
|
|
ENV_VAR: 'env-value',
|
|
RUNTIME_VAR: 'runtime-value',
|
|
FOLDER_VAR: 'folder-value',
|
|
REQUEST_VAR: 'request-value',
|
|
SHARED_VAR: 'request-value' // Shows highest precedence wins
|
|
}),
|
|
request,
|
|
collection.root
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('GraphQL Schema Handler Header Tests', () => {
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
|
|
const createBasicSetup = () => ({
|
|
endpoint: 'https://example.com/',
|
|
environment: { variables: [] },
|
|
request: { vars: {}, headers: [] },
|
|
collection: {
|
|
uid: 'test-collection',
|
|
pathname: '/test',
|
|
runtimeVariables: {},
|
|
globalEnvironmentVariables: {},
|
|
root: {
|
|
request: {
|
|
headers: []
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
it('should pass root headers to request', async () => {
|
|
const setup = createBasicSetup();
|
|
setup.collection.root.request.headers = [
|
|
{ name: 'X-Root-Header', value: 'root-value', enabled: true }
|
|
];
|
|
|
|
await fetchGqlSchemaHandler(null, setup.endpoint, setup.environment, setup.request, setup.collection);
|
|
|
|
expect(prepareGqlIntrospectionRequest).toHaveBeenCalledWith(
|
|
setup.endpoint,
|
|
expect.any(Object),
|
|
setup.request,
|
|
setup.collection.root
|
|
);
|
|
});
|
|
|
|
it('should pass request headers to request', async () => {
|
|
const setup = createBasicSetup();
|
|
setup.request.headers = [
|
|
{ name: 'X-Request-Header', value: 'request-value', enabled: true }
|
|
];
|
|
|
|
await fetchGqlSchemaHandler(null, setup.endpoint, setup.environment, setup.request, setup.collection);
|
|
|
|
expect(prepareGqlIntrospectionRequest).toHaveBeenCalledWith(
|
|
setup.endpoint,
|
|
expect.any(Object),
|
|
setup.request,
|
|
setup.collection.root
|
|
);
|
|
});
|
|
|
|
it('should handle environment variables in headers', async () => {
|
|
const setup = createBasicSetup();
|
|
setup.environment.variables = [
|
|
{ name: 'AUTH_TOKEN', value: 'token-value', enabled: true }
|
|
];
|
|
setup.request.headers = [
|
|
{ name: 'Authorization', value: 'Bearer {{AUTH_TOKEN}}', enabled: true }
|
|
];
|
|
|
|
await fetchGqlSchemaHandler(null, setup.endpoint, setup.environment, setup.request, setup.collection);
|
|
|
|
expect(prepareGqlIntrospectionRequest).toHaveBeenCalledWith(
|
|
setup.endpoint,
|
|
expect.objectContaining({
|
|
AUTH_TOKEN: 'token-value'
|
|
}),
|
|
setup.request,
|
|
setup.collection.root
|
|
);
|
|
});
|
|
|
|
it('should handle enabled and disabled headers', async () => {
|
|
const setup = createBasicSetup();
|
|
setup.request.headers = [
|
|
{ name: 'X-Enabled', value: 'enabled', enabled: true },
|
|
{ name: 'X-Disabled', value: 'disabled', enabled: false }
|
|
];
|
|
|
|
await fetchGqlSchemaHandler(null, setup.endpoint, setup.environment, setup.request, setup.collection);
|
|
|
|
expect(prepareGqlIntrospectionRequest).toHaveBeenCalledWith(
|
|
setup.endpoint,
|
|
expect.any(Object),
|
|
setup.request,
|
|
setup.collection.root
|
|
);
|
|
});
|
|
});
|