Skip to content

Commit

Permalink
168 validate config file (#174)
Browse files Browse the repository at this point in the history
* feat: remove reports from root of the config

* chore: add validations on config
  • Loading branch information
ASaiAnudeep authored May 5, 2024
1 parent 33d70e4 commit a7bea71
Show file tree
Hide file tree
Showing 8 changed files with 432 additions and 20 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"cSpell.words": [
"pactum",
"testbeats"
"testbeats",
"testng"
]
}
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "testbeats",
"version": "2.0.0",
"version": "2.0.1",
"description": "Publish test results to Microsoft Teams, Google Chat, Slack and InfluxDB",
"main": "src/index.js",
"types": "./src/index.d.ts",
Expand Down Expand Up @@ -44,7 +44,7 @@
"bugs": {
"url": "https://github.com/test-results-reporter/testbeats/issues"
},
"homepage": "https://test-results-reporter.github.io",
"homepage": "https://testbeats.com",
"dependencies": {
"async-retry": "^1.3.3",
"dotenv": "^14.3.2",
Expand Down
34 changes: 28 additions & 6 deletions src/beats/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,41 @@ function get_base_url() {
* @param {TestResult} result
*/
async function run(config, result) {
if (config.project && config.run && config.api_key) {
init(config);
if (isValid(config)) {
const run_id = await publishTestResults(config, result);
if (run_id) {
attachTestBeatsReportHyperLink(config, run_id);
}
} else {
console.warn('Missing testbeats config parameters');
}
}

/**
* @param {import('../index').PublishReport} config
*
* @param {import('../index').PublishReport} config
*/
function init(config) {
config.project = config.project || process.env.TEST_BEATS_PROJECT;
config.run = config.run || process.env.TEST_BEATS_RUN;
config.api_key = config.api_key || process.env.TEST_BEATS_API_KEY;
}

/**
*
* @param {import('../index').PublishReport} config
*/
function isValid(config) {
return config.project && config.run && config.api_key
}

/**
* @param {import('../index').PublishReport} config
* @param {TestResult} result
*/
async function publishTestResults(config, result) {
console.log("Publishing results to TestBeats");
try {
const payload = {
project: config.project,
Expand All @@ -34,7 +56,7 @@ async function publishTestResults(config, result) {
if (ci) {
payload.ci_details = [ci];
}

const response = await request.post({
url: `${get_base_url()}/api/core/v1/test-runs`,
headers: {
Expand Down Expand Up @@ -63,9 +85,9 @@ function attachTestBeatsReportHyperLink(config, run_id) {
}

/**
*
* @param {string} run_id
* @returns
*
* @param {string} run_id
* @returns
*/
function get_test_beats_report_link(run_id) {
return `${get_base_url()}/reports/${run_id}`;
Expand Down
8 changes: 4 additions & 4 deletions src/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
require('dotenv').config();

const sade = require('sade');
const prog = sade('test-results-reporter');

const prog = sade('testbeats');
const publish = require('./commands/publish');

prog
.version('0.0.7')
.version('2.0.1')
.option('-c, --config', 'Provide path to custom config', 'config.json');

prog.command('publish')
Expand Down
109 changes: 106 additions & 3 deletions src/commands/publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,29 @@ const target_manager = require('../targets');
* @param {import('../index').PublishOptions} opts
*/
async function run(opts) {
if (!opts) {
throw new Error('Missing publish options');
}
if (!opts.config) {
throw new Error('Missing publish config');
}
if (typeof opts.config === 'string') {
const cwd = process.cwd();
opts.config = require(path.join(cwd, opts.config));
const file_path = path.join(cwd, opts.config);
try {
opts.config = require(path.join(cwd, opts.config));
} catch (error) {
throw new Error(`Config file not found: ${file_path}`);
}
}
const config = processData(opts.config);
if (config.reports) {
for (const report of config.reports) {
validateConfig(report);
await processReport(report);
}
} else {
validateConfig(config);
await processReport(config);
}
}
Expand All @@ -43,8 +56,98 @@ async function processReport(report) {
for (let i = 0; i < parsed_results.length; i++) {
const result = parsed_results[i];
await beats.run(report, result);
for (const target of report.targets) {
await target_manager.run(target, result);
if (report.targets) {
for (const target of report.targets) {
await target_manager.run(target, result);
}
} else {
console.log('No targets defined, skipping sending results to targets');
}
}
}

/**
*
* @param {import('../index').PublishReport} config
*/
function validateConfig(config) {
if (!config) {
throw new Error('Missing publish config');
}
validateResults(config);
validateTargets(config);
}

/**
*
* @param {import('../index').PublishReport} config
*/
function validateResults(config) {
if (!config.results) {
throw new Error('Missing results properties in config');
}
if (!Array.isArray(config.results)) {
throw new Error('results must be an array');
}
if (!config.results.length) {
throw new Error('At least one result must be defined');
}
for (const result of config.results) {
if (!result.type) {
throw new Error('Missing result type');
}
if (result.type === 'custom') {
if (!result.result) {
throw new Error('Missing result');
}
} else {
if (!result.files) {
throw new Error('Missing result files');
}
if (!Array.isArray(result.files)) {
throw new Error('result files must be an array');
}
if (!result.files.length) {
throw new Error('At least one result file must be defined');
}
}
}
}

/**
*
* @param {import('../index').PublishReport} config
*/
function validateTargets(config) {
if (!config.targets) {
console.warn('targets are not defined in config');
return;
}
if (!Array.isArray(config.targets)) {
throw new Error('targets must be an array');
}
for (const target of config.targets) {
if (!target.name) {
throw new Error('missing target name');
}
if (target.name === 'slack' || target.name === 'teams' || target.name === 'chat') {
if (!target.inputs) {
throw new Error(`missing inputs in ${target.name} target`);
}
}
if (target.inputs) {
const inputs = target.inputs;
if (target.name === 'slack' || target.name === 'teams' || target.name === 'chat') {
if (!inputs.url) {
throw new Error(`missing url in ${target.name} target inputs`);
}
if (typeof inputs.url !== 'string') {
throw new Error(`url in ${target.name} target inputs must be a string`);
}
if (!inputs.url.startsWith('http')) {
throw new Error(`url in ${target.name} target inputs must start with 'http' or 'https'`);
}
}
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,8 @@ export interface CustomTargetInputs {

export interface Target {
name: TargetName;
condition: Condition;
inputs: SlackInputs | TeamsInputs | ChatInputs | CustomTargetInputs | InfluxDBTargetInputs;
condition?: Condition;
inputs?: SlackInputs | TeamsInputs | ChatInputs | CustomTargetInputs | InfluxDBTargetInputs;
extensions?: Extension[];
}

Expand Down
Loading

0 comments on commit a7bea71

Please sign in to comment.