From a3671220d5cec731dd714731515b0f484ded24dd Mon Sep 17 00:00:00 2001 From: DudaGod Date: Mon, 15 Jan 2024 18:23:41 +0300 Subject: [PATCH] feat(merge-reports): ability to pass headers for databaseUrls.json files --- docs/en/html-reporter-commands.md | 13 +- docs/ru/html-reporter-commands.md | 13 +- docs/ru/html-reporter-setup.md | 8 +- lib/cli-commands/merge-reports.js | 9 +- lib/merge-reports/index.js | 38 ++++-- package-lock.json | 175 +++++++++------------------ package.json | 2 +- test/unit/lib/merge-reports/index.js | 141 +++++++++++++++++---- 8 files changed, 239 insertions(+), 160 deletions(-) diff --git a/docs/en/html-reporter-commands.md b/docs/en/html-reporter-commands.md index d6afb066b..64dbc7a00 100644 --- a/docs/en/html-reporter-commands.md +++ b/docs/en/html-reporter-commands.md @@ -83,14 +83,23 @@ The command accepts paths to database files or to `databaseUrls.json` files from ### Usage -The `merge-reports` command supports the following required option: +The `merge-reports` command supports the following options: | **Option** | **Description** | | --------- | ------------ | | -d, --destination | The path to the folder where you want to save the final report. | +| -h, --header
| Http header for databaseUrls.json files from source paths. | Usage example: ```bash -npx hermione merge-reports path-to-database.db path-to-databaseUrls.json -d dest-report +npx hermione merge-reports path-to-database.db path-to-databaseUrls.json -d dest-report -h foo=bar ``` + +Http headers can also be send using the environment variable - `html_reporter_headers` (has a higher priority than the cli option `--header'). Example: + +```bash +html_reporter_headers='{"foo":"bar"}' npx hermione merge-reports path-to-database.db path-to-databaseUrls.json -d dest-report -h baz=qux +``` + +As a result, the `path-to-databaseUrls.json` will be requested with headers: `{foo: 'bar', baz: 'qux'}`. diff --git a/docs/ru/html-reporter-commands.md b/docs/ru/html-reporter-commands.md index 6f9c3e6e8..3609c51b5 100644 --- a/docs/ru/html-reporter-commands.md +++ b/docs/ru/html-reporter-commands.md @@ -83,14 +83,23 @@ npx hermione remove-unused-screens --help ### Использование -Команда `merge-reports` поддерживает следующую обязательную опцию: +Команда `merge-reports` поддерживает следующие опции: | **Опция** | **Описание** | | --------- | ------------ | | -d, --destination | Путь к папке, в которую нужно сохранить итоговый отчет. | +| -h, --header
| Http-хедер для загрузки databaseUrls.json из переданных исходных отчетов. | Пример использования: ```bash -npx hermione merge-reports path-to-database.db path-to-databaseUrls.json -d dest-report +npx hermione merge-reports path-to-database.db path-to-databaseUrls.json -d dest-report -h foo=bar ``` + +Http-хедеры можно так же передавать с помощью переменной окружения - `html_reporter_headers` (имеет приоритет выше, чем cli-опция `--header`). Пример: + +```bash +html_reporter_headers='{"foo":"bar"}' npx hermione merge-reports path-to-database.db path-to-databaseUrls.json -d dest-report -h baz=qux +``` + +В итоге `path-to-databaseUrls.json` будет запрошен с хедерами: `{foo: 'bar', baz: 'qux'}`. diff --git a/docs/ru/html-reporter-setup.md b/docs/ru/html-reporter-setup.md index bd42a0ff0..bac3bf5a0 100644 --- a/docs/ru/html-reporter-setup.md +++ b/docs/ru/html-reporter-setup.md @@ -133,7 +133,7 @@ module.exports = { По умолчанию «не сохранять»: `false`. -Любой плагин гермионы может добавить какие-либо подробности в объект ошибки при её возникновении. Эти подробности могут помочь пользователю в отладке проблем, которые возникли в тесте. Html-reporter сохраняет эти детали в папке `error-details` в файле с именем: `<хэш от полного названия теста>-<браузер>_<номер ретрая>_<временная метка>.json`. +Любой плагин гермионы может добавить какие-либо подробности в объект ошибки при её возникновении. Эти подробности могут помочь пользователю в отладке проблем, которые возникли в тесте. Html-reporter сохраняет эти детали в папке `error-details` в файле с именем: `<хэш от полного названия теста>-<браузер>_<номер ретрая>_<временная метка>.json`. Под стектрейсом html-reporter добавляет раздел `Error details` со ссылкой ``, указывающей на json-файл. Пользователь может открыть этот файл либо в браузере, либо в любой IDE. @@ -238,7 +238,7 @@ throw err; { '<опция-1>': 'значение опции 1', '<опция-2>': 'значение опции 2', - // и т. д. + // и т. д. } ``` @@ -275,7 +275,7 @@ throw err; ### plugins -Список плагинов с их настройками. +Список плагинов с их настройками. Смотрите подробнее в разделе «[Плагины для отчета](./html-reporter-plugins.md)». @@ -304,7 +304,7 @@ customScripts: [ Также в интерфейсе Яндекс.Метрики необходимо перейти в разделе настроек на вкладку _«Счетчик»_, нажать кнопку _«Скопировать»_ и вставить код счетчика в поле [customScripts](#customscripts). -С помощью метрики вы сможете узнать как разработчики взаимодействуют с вашим отчетом и с какого рода проблемами они сталкиваются. +С помощью метрики вы сможете узнать как разработчики взаимодействуют с вашим отчетом и с какого рода проблемами они сталкиваются. Отчет поддерживает следующие [цели для метрики][yandex-metrika-goals]: diff --git a/lib/cli-commands/merge-reports.js b/lib/cli-commands/merge-reports.js index d7349a2b4..eccdd7bc1 100644 --- a/lib/cli-commands/merge-reports.js +++ b/lib/cli-commands/merge-reports.js @@ -12,12 +12,19 @@ module.exports = (program, pluginConfig, hermione) => { .allowUnknownOption() .description('merge reports') .option('-d, --destination <destination>', 'path to directory with merged report', pluginConfig.path) + .option('-h, --header <header>', 'http header for databaseUrls.json files from source paths', collect, []) .action(async (paths, options) => { try { - await mergeReports(pluginConfig, hermione, paths, options); + const {destination: destPath, header: headers} = options; + + await mergeReports(pluginConfig, hermione, paths, {destPath, headers}); } catch (err) { logError(err); process.exit(1); } }); }; + +function collect(newValue, array = []) { + return array.concat(newValue); +} diff --git a/lib/merge-reports/index.js b/lib/merge-reports/index.js index 62742392c..f1d9e367f 100644 --- a/lib/merge-reports/index.js +++ b/lib/merge-reports/index.js @@ -5,10 +5,24 @@ const _ = require('lodash'); const serverUtils = require('../server-utils'); const dbServerUtils = require('../db-utils/server'); -module.exports = async (pluginConfig, hermione, srcPaths, {destination: destPath}) => { - validateOpts(srcPaths, destPath); +module.exports = async (pluginConfig, hermione, srcPaths, {destPath, headers}) => { + validateOpts({srcPaths, destPath, headers}); - const resolvedUrls = await tryResolveUrls(srcPaths); + let headersFromEnv; + + try { + headersFromEnv = JSON.parse(process.env.html_reporter_headers || '{}'); + } catch (e) { + throw new Error(`Couldn't parse headers from "html_reporter_headers" env variable: ${e.message}`); + } + + const headersFromCli = headers.reduce((acc, header) => { + const [key, ...values] = header.split('='); + return _.set(acc, key, values.join('=')); + }, {}); + const parsedHeaders = {...headersFromCli, ...headersFromEnv}; + + const resolvedUrls = await tryResolveUrls(srcPaths, parsedHeaders); await Promise.all([ serverUtils.saveStaticFilesToReportDir(hermione.htmlReporter, pluginConfig, destPath), @@ -18,7 +32,7 @@ module.exports = async (pluginConfig, hermione, srcPaths, {destination: destPath await hermione.htmlReporter.emitAsync(hermione.htmlReporter.events.REPORT_SAVED, {reportPath: destPath}); }; -function validateOpts(srcPaths, destPath) { +function validateOpts({srcPaths, destPath, headers}) { if (!srcPaths.length) { throw new Error('Nothing to merge, no source reports are passed'); } @@ -26,11 +40,17 @@ function validateOpts(srcPaths, destPath) { if (srcPaths.includes(destPath)) { throw new Error(`Destination report path: ${destPath}, exists in source report paths`); } + + for (const header of headers) { + if (!header.includes('=')) { + throw new Error(`Header must has key and value separated by "=" symbol, but got "${header}"`); + } + } } -async function tryResolveUrls(urls) { +async function tryResolveUrls(urls, headers) { const resolvedUrls = []; - const results = await Promise.all(urls.map(tryResolveUrl)); + const results = await Promise.all(urls.map(url => tryResolveUrl(url, headers))); results.forEach(({jsonUrls, dbUrls}) => { resolvedUrls.push(...jsonUrls.concat(dbUrls)); @@ -39,7 +59,7 @@ async function tryResolveUrls(urls) { return resolvedUrls; } -async function tryResolveUrl(url) { +async function tryResolveUrl(url, headers) { const jsonUrls = []; const dbUrls = []; @@ -47,14 +67,14 @@ async function tryResolveUrl(url) { dbUrls.push(url); } else if (serverUtils.isJsonUrl(url)) { try { - const {data} = await axios.get(url); + const {data} = await axios.get(url, {headers}); const currentDbUrls = _.get(data, 'dbUrls', []); const currentJsonUrls = _.get(data, 'jsonUrls', []); const preparedDbUrls = dbServerUtils.prepareUrls(currentDbUrls, url); const preparedJsonUrls = dbServerUtils.prepareUrls(currentJsonUrls, url); - const responses = await Promise.all(preparedJsonUrls.map(tryResolveUrl)); + const responses = await Promise.all(preparedJsonUrls.map(url => tryResolveUrl(url, headers))); dbUrls.push(...preparedDbUrls); diff --git a/package-lock.json b/package-lock.json index aad6de3c9..61032da61 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "dependencies": { "@babel/runtime": "^7.22.5", "@gemini-testing/sql.js": "^2.0.0", - "axios": "^0.18.1", + "axios": "^1.6.5", "better-sqlite3": "^8.5.0", "bluebird": "^3.5.3", "body-parser": "^1.18.2", @@ -6934,8 +6934,7 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "node_modules/atob": { "version": "2.1.2", @@ -6962,13 +6961,13 @@ } }, "node_modules/axios": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.1.tgz", - "integrity": "sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==", - "deprecated": "Critical security vulnerability fixed in v0.21.1. For more information, see https://github.com/axios/axios/pull/3410", + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.5.tgz", + "integrity": "sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==", "dependencies": { - "follow-redirects": "1.5.10", - "is-buffer": "^2.0.2" + "follow-redirects": "^1.15.4", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" } }, "node_modules/b4a": { @@ -8699,7 +8698,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -11323,7 +11321,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true, "engines": { "node": ">=0.4.0" } @@ -15373,29 +15370,24 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", - "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", - "dependencies": { - "debug": "=3.1.0" - }, + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], "engines": { "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } } }, - "node_modules/follow-redirects/node_modules/debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/follow-redirects/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, "node_modules/for-each": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", @@ -15607,6 +15599,19 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/form-data-encoder": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", @@ -19523,28 +19528,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "engines": { - "node": ">=4" - } - }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -20629,20 +20612,6 @@ "source-map": "~0.6.1" } }, - "node_modules/jsdom/node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/jsdom/node_modules/http-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", @@ -24640,8 +24609,7 @@ "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, "node_modules/proxyquire": { "version": "1.8.0", @@ -36985,8 +36953,7 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "atob": { "version": "2.1.2", @@ -37001,12 +36968,13 @@ "dev": true }, "axios": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.1.tgz", - "integrity": "sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==", + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.5.tgz", + "integrity": "sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==", "requires": { - "follow-redirects": "1.5.10", - "is-buffer": "^2.0.2" + "follow-redirects": "^1.15.4", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" } }, "b4a": { @@ -38371,7 +38339,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -40433,8 +40400,7 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, "delegate": { "version": "3.2.0", @@ -43567,27 +43533,9 @@ "dev": true }, "follow-redirects": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", - "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", - "requires": { - "debug": "=3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==" }, "for-each": { "version": "0.3.3", @@ -43763,6 +43711,16 @@ } } }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, "form-data-encoder": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", @@ -46716,11 +46674,6 @@ "has-tostringtag": "^1.0.0" } }, - "is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" - }, "is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -47492,17 +47445,6 @@ "source-map": "~0.6.1" } }, - "form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, "http-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", @@ -50652,8 +50594,7 @@ "proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, "proxyquire": { "version": "1.8.0", diff --git a/package.json b/package.json index 97a059029..54eabd023 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "dependencies": { "@babel/runtime": "^7.22.5", "@gemini-testing/sql.js": "^2.0.0", - "axios": "^0.18.1", + "axios": "^1.6.5", "better-sqlite3": "^8.5.0", "bluebird": "^3.5.3", "body-parser": "^1.18.2", diff --git a/test/unit/lib/merge-reports/index.js b/test/unit/lib/merge-reports/index.js index 15366049e..8b7862c21 100644 --- a/test/unit/lib/merge-reports/index.js +++ b/test/unit/lib/merge-reports/index.js @@ -35,17 +35,110 @@ describe('lib/merge-reports', () => { afterEach(() => sandbox.restore()); describe('options validation', () => { - it('should throw error if no source reports paths are specified', async () => { - await assert.isRejected( - execMergeReports_({paths: []}), - 'Nothing to merge, no source reports are passed' + describe('should throw error if', () => { + it('no source reports paths are specified', async () => { + await assert.isRejected( + execMergeReports_({paths: []}), + 'Nothing to merge, no source reports are passed' + ); + }); + + it('destination report path exists in passed source reports paths', async () => { + await assert.isRejected( + execMergeReports_({ + paths: ['src-report/path', 'dest-report/path'], + opts: {destPath: 'dest-report/path'} + }), + 'Destination report path: dest-report/path, exists in source report paths' + ); + }); + + it('specified header does not contain "=" separator', async () => { + await assert.isRejected( + execMergeReports_({ + paths: ['src-report/path-1.json'], + opts: { + destPath: 'dest-report/path', + headers: ['foo_bar'] + } + }), + 'Header must has key and value separated by "=" symbol, but got "foo_bar"' + ); + }); + }); + }); + + describe('should send headers to request json urls', () => { + let pluginConfig, hermione, paths, destPath; + + beforeEach(() => { + pluginConfig = stubConfig(); + hermione = stubTool(pluginConfig, {}, {}, htmlReporter); + paths = ['src-report/path-1.json']; + destPath = 'dest-report/path'; + }); + + afterEach(() => { + delete process.env['html_reporter_headers']; + }); + + it('from environment variable', async () => { + process.env['html_reporter_headers'] = '{"foo":"bar","baz":"qux"}'; + + await execMergeReports_({pluginConfig, hermione, paths, opts: {destPath, headers: []}}); + + assert.calledOnceWith( + axiosStub.get, + 'src-report/path-1.json', + { + headers: { + foo: 'bar', baz: 'qux' + } + } + ); + }); + + it('from cli option', async () => { + const headers = ['foo=bar', 'baz=qux']; + + await execMergeReports_({pluginConfig, hermione, paths, opts: {destPath, headers}}); + + assert.calledOnceWith( + axiosStub.get, + 'src-report/path-1.json', + { + headers: { + foo: 'bar', baz: 'qux' + } + } ); }); - it('should throw error if destination report path exists in passed source reports paths', async () => { - await assert.isRejected( - execMergeReports_({paths: ['src-report/path', 'dest-report/path'], opts: {destination: 'dest-report/path'}}), - 'Destination report path: dest-report/path, exists in source report paths' + it('from env variable and cli option for each request', async () => { + process.env['html_reporter_headers'] = '{"foo":"bar","baz":"qux"}'; + const headers = ['foo=123', 'abc=def']; + axiosStub.get.withArgs('src-report/path-1.json').resolves({data: {jsonUrls: ['src-report/path-2.json'], dbUrls: []}}); + + await execMergeReports_({pluginConfig, hermione, paths, opts: {destPath, headers}}); + + assert.calledTwice(axiosStub.get); + assert.calledWith( + axiosStub.get.firstCall, + 'src-report/path-1.json', + { + headers: { + foo: 'bar', baz: 'qux', abc: 'def' + } + } + ); + assert.calledWith( + axiosStub.get.secondCall, + 'src-report/path-2.json', + { + headers: { + foo: 'bar', baz: 'qux', abc: 'def' + } + } ); }); }); @@ -54,63 +147,63 @@ describe('lib/merge-reports', () => { const pluginConfig = stubConfig(); const hermione = stubTool(pluginConfig, {}, {}, htmlReporter); const paths = ['src-report/path-1.json', 'src-report/path-2.db']; - const destination = 'dest-report/path'; + const destPath = 'dest-report/path'; - await execMergeReports_({pluginConfig, hermione, paths, opts: {destination}}); + await execMergeReports_({pluginConfig, hermione, paths, opts: {destPath, headers: []}}); - assert.calledOnceWith(serverUtils.saveStaticFilesToReportDir, hermione.htmlReporter, pluginConfig, destination); - assert.calledOnceWith(serverUtils.writeDatabaseUrlsFile, destination, paths); + assert.calledOnceWith(serverUtils.saveStaticFilesToReportDir, hermione.htmlReporter, pluginConfig, destPath); + assert.calledOnceWith(serverUtils.writeDatabaseUrlsFile, destPath, paths); }); it('should resolve json urls while merging reports', async () => { const pluginConfig = stubConfig(); const hermione = stubTool(pluginConfig, {}, {}, htmlReporter); const paths = ['src-report/path-1.json']; - const destination = 'dest-report/path'; + const destPath = 'dest-report/path'; axiosStub.get.withArgs('src-report/path-1.json').resolves({data: {jsonUrls: ['src-report/path-2.json', 'src-report/path-3.json'], dbUrls: ['path-1.db']}}); axiosStub.get.withArgs('src-report/path-2.json').resolves({data: {jsonUrls: [], dbUrls: ['path-2.db']}}); axiosStub.get.withArgs('src-report/path-3.json').resolves({data: {jsonUrls: ['src-report/path-4.json'], dbUrls: ['path-3.db']}}); axiosStub.get.withArgs('src-report/path-4.json').resolves({data: {jsonUrls: [], dbUrls: ['path-4.db']}}); - await execMergeReports_({pluginConfig, hermione, paths, opts: {destination}}); + await execMergeReports_({pluginConfig, hermione, paths, opts: {destPath, headers: []}}); - assert.calledOnceWith(serverUtils.writeDatabaseUrlsFile, destination, ['path-1.db', 'path-2.db', 'path-3.db', 'path-4.db']); + assert.calledOnceWith(serverUtils.writeDatabaseUrlsFile, destPath, ['path-1.db', 'path-2.db', 'path-3.db', 'path-4.db']); }); it('should normalize urls while merging reports', async () => { const pluginConfig = stubConfig(); const hermione = stubTool(pluginConfig, {}, {}, htmlReporter); const paths = ['src-report/path-1.json']; - const destination = 'dest-report/path'; + const destPath = 'dest-report/path'; axiosStub.get.withArgs('src-report/path-1.json').resolves({data: {jsonUrls: ['https://foo.bar/path-2.json']}}); axiosStub.get.withArgs('https://foo.bar/path-2.json').resolves({data: {jsonUrls: [], dbUrls: ['sqlite.db']}}); - await execMergeReports_({pluginConfig, hermione, paths, opts: {destination}}); + await execMergeReports_({pluginConfig, hermione, paths, opts: {destPath, headers: []}}); - assert.calledOnceWith(serverUtils.writeDatabaseUrlsFile, destination, ['https://foo.bar/sqlite.db']); + assert.calledOnceWith(serverUtils.writeDatabaseUrlsFile, destPath, ['https://foo.bar/sqlite.db']); }); it('should fallback to json url while merging reports', async () => { const pluginConfig = stubConfig(); const hermione = stubTool(pluginConfig, {}, {}, htmlReporter); const paths = ['src-report/path-1.json']; - const destination = 'dest-report/path'; + const destPath = 'dest-report/path'; axiosStub.get.rejects(); - await execMergeReports_({pluginConfig, hermione, paths, opts: {destination}}); + await execMergeReports_({pluginConfig, hermione, paths, opts: {destPath, headers: []}}); - assert.calledOnceWith(serverUtils.writeDatabaseUrlsFile, destination, ['src-report/path-1.json']); + assert.calledOnceWith(serverUtils.writeDatabaseUrlsFile, destPath, ['src-report/path-1.json']); }); it('should emit REPORT_SAVED event', async () => { const hermione = stubTool({}, {}, {}, htmlReporter); - const destination = 'dest-report/path'; + const destPath = 'dest-report/path'; - await execMergeReports_({pluginConfig: {}, hermione, paths: [''], opts: {destination}}); + await execMergeReports_({pluginConfig: {}, hermione, paths: [''], opts: {destPath, headers: []}}); - assert.calledOnceWith(hermione.htmlReporter.emitAsync, 'reportSaved', {reportPath: destination}); + assert.calledOnceWith(hermione.htmlReporter.emitAsync, 'reportSaved', {reportPath: destPath}); }); });