Skip to content

Commit

Permalink
Improve error handling in utils.fetch and its uses
Browse files Browse the repository at this point in the history
Minor fixes in tests

Revert to ES2019
  • Loading branch information
shivammathur committed Jul 9, 2021
1 parent 39491a0 commit 14fa980
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 111 deletions.
95 changes: 46 additions & 49 deletions __tests__/tools.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,29 @@ function getData(data: IData): Record<string, string> {

jest
.spyOn(utils, 'fetch')
.mockImplementation(async (url: string): Promise<string> => {
return `[{"ref": "refs/tags/1.2.3", "url": "${url}"}]`;
.mockImplementation(async (url: string, token?: string): Promise<
Record<string, string>
> => {
if (!token || token === 'valid_token') {
return {data: `[{"ref": "refs/tags/1.2.3", "url": "${url}"}]`};
} else if (token === 'no_data') {
return {data: '[]'};
} else {
return {error: 'Invalid token'};
}
});

describe('Tools tests', () => {
it('checking getToolSemver', async () => {
it.each`
token | version
${'invalid_token'} | ${'1.2'}
${'valid_token'} | ${'1.2.3'}
${''} | ${'1.2.3'}
`('checking getToolSemver: $token', async ({token, version}) => {
process.env['COMPOSER_TOKEN'] = token;
expect(
await tools.getToolSemver(getData({tool: 'tool', version: 'latest'}))
).toBe('1.2.3');
await tools.getToolSemver(getData({tool: 'tool', version: '1.2'}))
).toBe(version);
});

it.each`
Expand Down Expand Up @@ -90,49 +104,22 @@ describe('Tools tests', () => {
});
});

it.each([
[
['a', 'b'],
['composer', 'a', 'b']
],
[
['a', 'b', 'composer'],
['composer', 'a', 'b']
],
[
['a', 'b', 'composer:1.2.3'],
['composer:1.2.3', 'a', 'b']
],
[
['a', 'b', 'composer:v1.2.3'],
['composer:1.2.3', 'a', 'b']
],
[
['a', 'b', 'composer:snapshot'],
['composer:snapshot', 'a', 'b']
],
[
['a', 'b', 'composer:preview'],
['composer:preview', 'a', 'b']
],
[
['a', 'b', 'composer:1'],
['composer:1', 'a', 'b']
],
[
['a', 'b', 'composer:2'],
['composer:2', 'a', 'b']
],
[
['a', 'b', 'composer:v1'],
['composer:1', 'a', 'b']
],
[
['a', 'b', 'composer:v2'],
['composer:2', 'a', 'b']
]
])('checking filterList', async (input_list, filtered_list) => {
expect(await tools.filterList(input_list)).toStrictEqual(filtered_list);
it.each`
input_list | filtered_list
${'a, b'} | ${'composer, a, b'}
${'a, b, composer'} | ${'composer, a, b'}
${'a, b, composer:1.2.3'} | ${'composer:1.2.3, a, b'}
${'a, b, composer:v1.2.3'} | ${'composer:1.2.3, a, b'}
${'a, b, composer:snapshot'} | ${'composer:snapshot, a, b'}
${'a, b, composer:preview'} | ${'composer:preview, a, b'}
${'a, b, composer:1'} | ${'composer:1, a, b'}
${'a, b, composer:2'} | ${'composer:2, a, b'}
${'a, b, composer:v1'} | ${'composer:1, a, b'}
${'a, b, composer:v2'} | ${'composer:2, a, b'}
`('checking filterList $input_list', async ({input_list, filtered_list}) => {
expect(await tools.filterList(input_list.split(', '))).toStrictEqual(
filtered_list.split(', ')
);
});

it.each`
Expand Down Expand Up @@ -174,7 +161,7 @@ describe('Tools tests', () => {
${'darwin'} | ${'add_tool https://example.com/tool.phar tool "-v"'}
${'win32'} | ${'Add-Tool https://example.com/tool.phar tool "-v"'}
${'openbsd'} | ${'Platform openbsd is not supported'}
`('checking addPackage: $tool, $os_version', async ({os_version, script}) => {
`('checking addPackage: $os_version', async ({os_version, script}) => {
const data = getData({
tool: 'tool',
version: 'latest',
Expand Down Expand Up @@ -474,4 +461,14 @@ describe('Tools tests', () => {
`('checking composer setup: $tools_csv', async ({tools_csv, script}) => {
expect(await tools.addTools(tools_csv, '7.4', 'linux')).toContain(script);
});

it.each`
tools_csv | token | script
${'cs2pr:1.2'} | ${'invalid_token'} | ${'add_log "$cross" "cs2pr" "Invalid token"'}
${'phpunit:1.2'} | ${'invalid_token'} | ${'add_log "$cross" "phpunit" "Invalid token"'}
${'phpunit:0.1'} | ${'no_data'} | ${'add_log "$cross" "phpunit" "No version found with prefix 0.1."'}
`('checking error: $tools_csv', async ({tools_csv, token, script}) => {
process.env['COMPOSER_TOKEN'] = token;
expect(await tools.addTools(tools_csv, '7.4', 'linux')).toContain(script);
});
});
31 changes: 20 additions & 11 deletions __tests__/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@ jest.mock('@actions/core', () => ({
})
}));

jest.spyOn(utils, 'fetch').mockImplementation(async (url): Promise<string> => {
return `{ "latest": "8.0", "5.x": "5.6", "url": "${url}" }`;
});

async function cleanup(path: string): Promise<void> {
fs.unlink(path, error => {
if (error) {
Expand All @@ -38,16 +34,29 @@ describe('Utils tests', () => {
});

it('checking fetch', async () => {
expect(await utils.fetch('test_url')).toBe(
'{ "latest": "8.0", "5.x": "5.6", "url": "test_url" }'
);
process.env['COMPOSER_TOKEN'] = 'GITHUB_TOKEN';
expect(await utils.fetch('test_url')).toBe(
'{ "latest": "8.0", "5.x": "5.6", "url": "test_url" }'
);
const manifest = await utils.getManifestURL();
let response: Record<string, string> = await utils.fetch(manifest);
expect(response.error).toBe(undefined);
expect(response.data).toContain('latest');

response = await utils.fetch(manifest, 'invalid_token');
expect(response.error).toBe('404: Not Found');
});

it('checking getManifestURL', async () => {
expect(await utils.getManifestURL()).toContain('php-versions.json');
});

it('checking parseVersion', async () => {
jest.spyOn(utils, 'fetch').mockImplementation(async (url, token?): Promise<
Record<string, string>
> => {
if (!token || token === 'valid_token') {
return {data: `{ "latest": "8.0", "5.x": "5.6", "url": "${url}" }`};
} else {
return {error: 'Invalid token'};
}
});
expect(await utils.parseVersion('latest')).toBe('8.0');
expect(await utils.parseVersion('7')).toBe('7.0');
expect(await utils.parseVersion('7.4')).toBe('7.4');
Expand Down
59 changes: 40 additions & 19 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -495,10 +495,18 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.addTools = exports.initToolData = exports.functionRecord = exports.addWPCLI = exports.addSymfony = exports.addPHPUnitTools = exports.addPhive = exports.addPhing = exports.addPECL = exports.addDevTools = exports.addDeployer = exports.addComposer = exports.addBlackfirePlayer = exports.addPackage = exports.addArchive = exports.getPharUrl = exports.getUrl = exports.filterList = exports.parseRelease = exports.getToolVersion = exports.getToolSemver = void 0;
const utils = __importStar(__nccwpck_require__(918));
async function getToolSemver(data) {
const api_url = `https://api.github.com/repos/${data['repository']}/git/matching-refs/tags%2F${data['version_prefix']}${data['version']}`;
return JSON.parse(await utils.fetch(api_url))
.pop()['ref'].split('/')
.pop();
var _a;
const ref = data['version_prefix'] + data['version'];
const url = `https://api.github.com/repos/${data['repository']}/git/matching-refs/tags%2F${ref}.`;
const token = await utils.readEnv('COMPOSER_TOKEN');
const response = await utils.fetch(url, token);
if (response.error || response.data === '[]') {
data['error'] = (_a = response.error) !== null && _a !== void 0 ? _a : `No version found with prefix ${ref}.`;
return data['version'];
}
else {
return JSON.parse(response['data']).pop()['ref'].split('/').pop();
}
}
exports.getToolSemver = getToolSemver;
async function getToolVersion(data) {
Expand Down Expand Up @@ -788,6 +796,9 @@ async function addTools(tools_csv, php_version, os_version) {
const data = await initToolData(await utils.getToolData(release.split(':')[0]), release, php_version, os_version);
script += '\n';
switch (true) {
case data['error'] !== undefined:
script += await utils.addLog('$cross', data['tool'], data['error'], data['os_version']);
break;
case 'phar' === data['type']:
data['url'] = await getUrl(data);
script += await addArchive(data);
Expand All @@ -805,7 +816,7 @@ async function addTools(tools_csv, php_version, os_version) {
case /^none$/.test(data['tool']):
break;
default:
script += await utils.addLog('$cross', data['tool'], 'Tool ' + data['tool'] + ' is not supported', os_version);
script += await utils.addLog('$cross', data['tool'], 'Tool ' + data['tool'] + ' is not supported', data['os_version']);
break;
}
});
Expand Down Expand Up @@ -840,7 +851,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
return result;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.parseExtensionSource = exports.customPackage = exports.scriptTool = exports.scriptExtension = exports.joins = exports.getCommand = exports.getUnsupportedLog = exports.suppressOutput = exports.getExtensionPrefix = exports.CSVArray = exports.extensionArray = exports.getToolData = exports.writeScript = exports.readFile = exports.addLog = exports.stepLog = exports.log = exports.color = exports.asyncForEach = exports.parseVersion = exports.fetch = exports.getInput = exports.readEnv = void 0;
exports.parseExtensionSource = exports.customPackage = exports.scriptTool = exports.scriptExtension = exports.joins = exports.getCommand = exports.getUnsupportedLog = exports.suppressOutput = exports.getExtensionPrefix = exports.CSVArray = exports.extensionArray = exports.getToolData = exports.writeScript = exports.readFile = exports.addLog = exports.stepLog = exports.log = exports.color = exports.asyncForEach = exports.parseVersion = exports.getManifestURL = exports.fetch = exports.getInput = exports.readEnv = void 0;
const fs = __importStar(__nccwpck_require__(747));
const https = __importStar(__nccwpck_require__(211));
const path = __importStar(__nccwpck_require__(622));
Expand Down Expand Up @@ -871,35 +882,45 @@ async function getInput(name, mandatory) {
}
}
exports.getInput = getInput;
async function fetch(input_url) {
async function fetch(input_url, auth_token) {
const fetch_promise = new Promise(resolve => {
const url_object = new url.URL(input_url);
const auth_token = process.env['COMPOSER_TOKEN'] || '';
const auth_header = auth_token ? 'Bearer' + auth_token : '';
const headers = {
'User-Agent': `Mozilla/5.0 (${process.platform} ${process.arch}) setup-php`
};
if (auth_token) {
headers.authorization = 'Bearer ' + auth_token;
}
const options = {
hostname: url_object.hostname,
path: url_object.pathname,
headers: {
authorization: auth_header,
'User-Agent': 'setup-php'
}
headers: headers
};
const req = https.get(options, (res) => {
res.setEncoding('utf8');
let body = '';
res.on('data', chunk => (body += chunk));
res.on('end', () => resolve(body));
if (res.statusCode != 200) {
resolve({ error: `${res.statusCode}: ${res.statusMessage}` });
}
else {
let body = '';
res.setEncoding('utf8');
res.on('data', chunk => (body += chunk));
res.on('end', () => resolve({ data: `${body}` }));
}
});
req.end();
});
return await fetch_promise;
}
exports.fetch = fetch;
async function getManifestURL() {
return 'https://raw.githubusercontent.com/shivammathur/setup-php/develop/src/configs/php-versions.json';
}
exports.getManifestURL = getManifestURL;
async function parseVersion(version) {
const manifest = 'https://raw.githubusercontent.com/shivammathur/setup-php/develop/src/configs/php-versions.json';
const manifest = await getManifestURL();
switch (true) {
case /^(latest|\d+\.x)$/.test(version):
return JSON.parse(await fetch(manifest))[version];
return JSON.parse((await fetch(manifest))['data'])[version];
default:
switch (true) {
case version.length > 1:
Expand Down
25 changes: 19 additions & 6 deletions src/tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@ import * as utils from './utils';
export async function getToolSemver(
data: Record<string, string>
): Promise<string> {
const api_url = `https://api.github.com/repos/${data['repository']}/git/matching-refs/tags%2F${data['version_prefix']}${data['version']}`;
return JSON.parse(await utils.fetch(api_url))
.pop()
['ref'].split('/')
.pop();
const ref: string = data['version_prefix'] + data['version'];
const url = `https://api.github.com/repos/${data['repository']}/git/matching-refs/tags%2F${ref}.`;
const token: string = await utils.readEnv('COMPOSER_TOKEN');
const response: Record<string, string> = await utils.fetch(url, token);
if (response.error || response.data === '[]') {
data['error'] = response.error ?? `No version found with prefix ${ref}.`;
return data['version'];
} else {
return JSON.parse(response['data']).pop()['ref'].split('/').pop();
}
}

/**
Expand Down Expand Up @@ -463,6 +468,14 @@ export async function addTools(
);
script += '\n';
switch (true) {
case data['error'] !== undefined:
script += await utils.addLog(
'$cross',
data['tool'],
data['error'],
data['os_version']
);
break;
case 'phar' === data['type']:
data['url'] = await getUrl(data);
script += await addArchive(data);
Expand All @@ -489,7 +502,7 @@ export async function addTools(
'$cross',
data['tool'],
'Tool ' + data['tool'] + ' is not supported',
os_version
data['os_version']
);
break;
}
Expand Down
Loading

0 comments on commit 14fa980

Please sign in to comment.