* add GitHub GraphQL api initial support * support mutiple backends for e2e tests - initial commit * add github backend e2e test (currently skipped), fix bugs per tests * refactor e2e tests, add fork workflow tests, support fork workflow in GraphQL api * remove log message that might contain authentication token * return empty error when commit is not found when using GraphQL (align with base class) * disable github backend tests * fix bugs introduced after rebase of GraphQL and OpenAuthoring features * test: update tests per openAuthoring changes, split tests into multiple files * fix: pass in headers for pagination requests, avoid async iterator as it requires a polyfill on old browsers * test(e2e): disable github backend tests
80 lines
2.5 KiB
JavaScript
80 lines
2.5 KiB
JavaScript
import { flow, fromPairs, get } from 'lodash';
|
|
import { map } from 'lodash/fp';
|
|
import { fromJS } from 'immutable';
|
|
import { fileExtension } from './path';
|
|
import unsentRequest from './unsentRequest';
|
|
|
|
export const filterByPropExtension = (extension, propName) => arr =>
|
|
arr.filter(el => fileExtension(get(el, propName)) === extension);
|
|
|
|
const catchFormatErrors = (format, formatter) => res => {
|
|
try {
|
|
return formatter(res);
|
|
} catch (err) {
|
|
throw new Error(
|
|
`Response cannot be parsed into the expected format (${format}): ${err.message}`,
|
|
);
|
|
}
|
|
};
|
|
|
|
const responseFormatters = fromJS({
|
|
json: async res => {
|
|
const contentType = res.headers.get('Content-Type');
|
|
if (!contentType.startsWith('application/json') && !contentType.startsWith('text/json')) {
|
|
throw new Error(`${contentType} is not a valid JSON Content-Type`);
|
|
}
|
|
return res.json();
|
|
},
|
|
text: async res => res.text(),
|
|
blob: async res => res.blob(),
|
|
}).mapEntries(([format, formatter]) => [format, catchFormatErrors(format, formatter)]);
|
|
|
|
export const parseResponse = async (res, { expectingOk = true, format = 'text' } = {}) => {
|
|
if (expectingOk && !res.ok) {
|
|
throw new Error(`Expected an ok response, but received an error status: ${res.status}.`);
|
|
}
|
|
const formatter = responseFormatters.get(format, false);
|
|
if (!formatter) {
|
|
throw new Error(`${format} is not a supported response format.`);
|
|
}
|
|
const body = await formatter(res);
|
|
return body;
|
|
};
|
|
|
|
export const responseParser = options => res => parseResponse(res, options);
|
|
|
|
export const parseLinkHeader = flow([
|
|
linksString => linksString.split(','),
|
|
map(str => str.trim().split(';')),
|
|
map(([linkStr, keyStr]) => [
|
|
keyStr.match(/rel="(.*?)"/)[1],
|
|
linkStr
|
|
.trim()
|
|
.match(/<(.*?)>/)[1]
|
|
.replace(/\+/g, '%20'),
|
|
]),
|
|
fromPairs,
|
|
]);
|
|
|
|
export const getAllResponses = async (url, options = {}, linkHeaderRelName = 'next') => {
|
|
const maxResponses = 30;
|
|
let responseCount = 1;
|
|
|
|
let req = unsentRequest.fromFetchArguments(url, options);
|
|
|
|
const pageResponses = [];
|
|
|
|
while (req && responseCount < maxResponses) {
|
|
const pageResponse = await unsentRequest.performRequest(req);
|
|
const linkHeader = pageResponse.headers.get('Link');
|
|
const nextURL = linkHeader && parseLinkHeader(linkHeader)[linkHeaderRelName];
|
|
|
|
const { headers = {} } = options;
|
|
req = nextURL && unsentRequest.fromFetchArguments(nextURL, { headers });
|
|
pageResponses.push(pageResponse);
|
|
responseCount++;
|
|
}
|
|
|
|
return pageResponses;
|
|
};
|