feat: folder level scripts and tests

This commit is contained in:
Anoop M D
2024-06-29 16:01:21 +05:30
parent c1a57d30dc
commit ede29e29bd
20 changed files with 511 additions and 224 deletions

View File

@@ -43,39 +43,6 @@ const isCollectionRootBruFile = (pathname, collectionPath) => {
return dirname === collectionPath && basename === 'collection.bru';
};
const isFolderRootBruFile = (pathname, folderPath) => {
const dirname = path.dirname(pathname);
const basename = path.basename(pathname);
return dirname === folderPath && basename === 'folder.bru';
};
const scanDirectory = (directoryPath, callback) => {
fs.readdir(directoryPath, (err, files) => {
if (err) {
console.error(`Error reading directory ${directoryPath}: ${err}`);
return;
}
if (files.includes('folder.bru')) {
callback(directoryPath);
}
// Iterate through each file/folder in the directory
files.forEach((file) => {
const filePath = path.join(directoryPath, file);
// Check if it's a directory
fs.stat(filePath, (err, stats) => {
if (err) {
console.error(`Error statting ${filePath}: ${err}`);
return;
}
// If it's a directory, recursively scan it
if (stats.isDirectory()) {
scanDirectory(filePath, callback);
}
});
});
});
};
const hydrateRequestWithUuid = (request, pathname) => {
request.uid = getRequestUid(pathname);
@@ -257,27 +224,38 @@ const add = async (win, pathname, collectionUid, collectionPath) => {
collectionRoot: true
}
};
const folderCallback = (filePath) => {
const bruContent = fs.readFileSync(`${filePath}/folder.bru`, 'utf8');
if (bruContent) {
const folder = {
meta: {
collectionUid,
pathname: filePath,
name: path.basename(filePath),
folderRoot: true
}
};
folder.data = collectionBruToJson(bruContent);
hydrateBruCollectionFileWithUuid(folder.data);
win.webContents.send('main:collection-tree-updated', 'addFileDir', folder);
}
};
try {
scanDirectory(collectionPath, folderCallback);
let bruContent = fs.readFileSync(pathname, 'utf8');
file.data = collectionBruToJson(bruContent);
hydrateBruCollectionFileWithUuid(file.data);
win.webContents.send('main:collection-tree-updated', 'addFile', file);
return;
} catch (err) {
console.error(err);
return;
}
}
// Is this a folder.bru file?
if (path.basename(pathname) === 'folder.bru') {
console.log('folder.bru file detected');
const file = {
meta: {
collectionUid,
pathname,
name: path.basename(pathname),
folderRoot: true
}
};
try {
let bruContent = fs.readFileSync(pathname, 'utf8');
file.data = collectionBruToJson(bruContent);
hydrateBruCollectionFileWithUuid(file.data);
win.webContents.send('main:collection-tree-updated', 'addFile', file);
return;
@@ -402,6 +380,7 @@ const change = async (win, pathname, collectionUid, collectionPath) => {
const bru = fs.readFileSync(pathname, 'utf8');
file.data = bruToJson(bru);
hydrateRequestWithUuid(file.data, pathname);
win.webContents.send('main:collection-tree-updated', 'change', file);
} catch (err) {

View File

@@ -24,6 +24,16 @@ const collectionBruToJson = (bru) => {
docs: _.get(json, 'docs', '')
};
// add meta if it exists
// this is only for folder bru file
// in the future, all of this will be replaced by standard bru lang
if (json.meta) {
transformedJson.meta = {
name: json.meta.name,
seq: json.meta.seq
};
}
return transformedJson;
} catch (error) {
return Promise.reject(error);
@@ -48,6 +58,16 @@ const jsonToCollectionBru = (json) => {
docs: _.get(json, 'docs', '')
};
// add meta if it exists
// this is only for folder bru file
// in the future, all of this will be replaced by standard bru lang
if (json.meta) {
collectionBruJson.meta = {
name: json.meta.name,
seq: json.meta.seq
};
}
return _jsonToCollectionBru(collectionBruJson);
} catch (error) {
return Promise.reject(error);

View File

@@ -152,11 +152,16 @@ const registerRendererEventHandlers = (mainWindow, watcher, lastOpenedCollection
}
});
ipcMain.handle('renderer:save-folder-root', async (event, folderPathname, folderRoot) => {
ipcMain.handle('renderer:save-folder-root', async (event, folder) => {
try {
const { name: folderName, root: folderRoot, pathname: folderPathname } = folder;
const folderBruFilePath = path.join(folderPathname, 'folder.bru');
const content = jsonToBru(folderRoot);
folderRoot.meta = {
name: folderName
};
const content = jsonToCollectionBru(folderRoot);
await writeFile(folderBruFilePath, content);
} catch (error) {
return Promise.reject(error);

View File

@@ -461,8 +461,7 @@ const registerNetworkIpc = (mainWindow) => {
});
const collectionRoot = get(collection, 'root', {});
const _request = item.draft ? item.draft.request : item.request;
const request = prepareRequest(_request, collectionRoot, collectionPath);
const request = prepareRequest(item, collection);
const envVars = getEnvVars(environment);
const processEnvVars = getProcessEnvVars(collectionUid);
const brunoConfig = getBrunoConfig(collectionUid);
@@ -900,8 +899,7 @@ const registerNetworkIpc = (mainWindow) => {
...eventData
});
const _request = item.draft ? item.draft.request : item.request;
const request = prepareRequest(_request, collectionRoot, collectionPath);
const request = prepareRequest(item, collection);
const requestUid = uuid();
const processEnvVars = getProcessEnvVars(collectionUid);

View File

@@ -1,9 +1,79 @@
const { get, each, filter, extend } = require('lodash');
const os = require('os');
const { get, each, filter, extend, compact } = require('lodash');
const decomment = require('decomment');
var JSONbig = require('json-bigint');
const FormData = require('form-data');
const fs = require('fs');
const path = require('path');
const { getTreePathFromCollectionToItem } = require('../../utils/collection');
const mergeFolderLevelHeaders = (request, requestTreePath) => {
let folderHeaders = new Map();
for (let i of requestTreePath) {
if (i.type === 'folder') {
let headers = get(i, 'root.request.headers', []);
headers.forEach((header) => {
if (header.enabled) {
folderHeaders.set(header.name, header.value);
}
});
}
}
let mergedFolderHeaders = Array.from(folderHeaders, ([name, value]) => ({ name, value, enabled: true }));
let requestHeaders = request.headers || [];
let requestHeadersMap = new Map();
for (let header of requestHeaders) {
if (header.enabled) {
requestHeadersMap.set(header.name, header.value);
}
}
mergedFolderHeaders.forEach((header) => {
requestHeadersMap.set(header.name, header.value);
});
request.headers = Array.from(requestHeadersMap, ([name, value]) => ({ name, value, enabled: true }));
};
const mergeFolderLevelScripts = (request, requestTreePath) => {
let folderCombinedPreReqScript = [];
let folderCombinedPostResScript = [];
let folderCombinedTests = [];
for (let i of requestTreePath) {
if (i.type === 'folder') {
let preReqScript = get(i, 'root.request.script.req', '');
if (preReqScript && preReqScript.trim() !== '') {
folderCombinedPreReqScript.push(preReqScript);
}
let postResScript = get(i, 'root.request.script.res', '');
if (postResScript && postResScript.trim() !== '') {
folderCombinedPostResScript.push(postResScript);
}
let tests = get(i, 'root.request.tests', []);
if (tests && tests?.trim() !== '') {
folderCombinedTests.push(tests);
}
}
}
if (folderCombinedPreReqScript.length) {
request.script.req = compact([...folderCombinedPreReqScript, request?.script?.req || '']).join(os.EOL);
console.log('request.script.req', request.script.req);
}
if (folderCombinedPostResScript.length) {
request.script.res = compact([request?.script?.res || '', ...folderCombinedPostResScript.reverse()]).join(os.EOL);
}
if (folderCombinedTests.length) {
request.tests = compact([request?.tests || '', ...folderCombinedTests.reverse()]).join(os.EOL);
}
};
const parseFormData = (datas, collectionPath) => {
// make axios work in node using form data
@@ -133,7 +203,10 @@ const setAuthHeaders = (axiosRequest, request, collectionRoot) => {
return axiosRequest;
};
const prepareRequest = (request, collectionRoot, collectionPath) => {
const prepareRequest = (item, collection) => {
const request = item.draft ? item.draft.request : item.request;
const collectionRoot = get(collection, 'root', {});
const collectionPath = collection.pathname;
const headers = {};
let contentTypeDefined = false;
let url = request.url;
@@ -148,6 +221,12 @@ const prepareRequest = (request, collectionRoot, collectionPath) => {
}
});
const requestTreePath = getTreePathFromCollectionToItem(collection, item);
if (requestTreePath && requestTreePath.length > 0) {
mergeFolderLevelHeaders(request, requestTreePath);
mergeFolderLevelScripts(request, requestTreePath);
}
each(request.headers, (h) => {
if (h.enabled && h.name.length > 0) {
headers[h.name] = h.value;

View File

@@ -0,0 +1,57 @@
const each = require('lodash/each');
const find = require('lodash/find');
const flattenItems = (items = []) => {
const flattenedItems = [];
const flatten = (itms, flattened) => {
each(itms, (i) => {
flattened.push(i);
if (i.items && i.items.length) {
flatten(i.items, flattened);
}
});
};
flatten(items, flattenedItems);
return flattenedItems;
};
const findItem = (items = [], itemUid) => {
return find(items, (i) => i.uid === itemUid);
};
const findItemInCollection = (collection, itemUid) => {
let flattenedItems = flattenItems(collection.items);
return findItem(flattenedItems, itemUid);
};
const findParentItemInCollection = (collection, itemUid) => {
let flattenedItems = flattenItems(collection.items);
return find(flattenedItems, (item) => {
return item.items && find(item.items, (i) => i.uid === itemUid);
});
};
const getTreePathFromCollectionToItem = (collection, _item) => {
let path = [];
let item = findItemInCollection(collection, _item.uid);
while (item) {
path.unshift(item);
item = findParentItemInCollection(collection, item.uid);
}
return path;
};
module.exports = {
flattenItems,
findItem,
findItemInCollection,
findParentItemInCollection,
getTreePathFromCollectionToItem
};