Commit 83f37680 authored by Caleb Weeks's avatar Caleb Weeks

Merge branch 'issue/2-promisifying-async-functions' of...

Merge branch 'issue/2-promisifying-async-functions' of gitlab.entropy.cc:blacklight/npm-sling-connector into issue/2-promisifying-async-functions
parents bcd238c1 1bcda2db
......@@ -20,7 +20,7 @@ var warn=dbg("SLING:warn")
var errorLog=dbg("SLING:error")
const selectors = {
getIfExists: "get-if-exists",
getIfExists: "get-if-exists",
deref: "deref"
}
......@@ -72,13 +72,13 @@ var SlingConnector = module.exports = function(options){
this.mode = options.mode;
this.hasDerefCapability = options.hasDerefCapability;
this.derefByDefault = options.derefByDefault;
this.invalidPathRegex = options.invalidPathRegex || /undefined|\[object Object\]/;
this.invalidPathRegex = options.invalidPathRegex || /undefined|\[object Object\]/;
//need to create copies of the keep alive config (using ...) because that library modifies the options object passed in
this.httpRequestAgent = options.httpRequestAgent || new KeepAliveAgent(options.httpAgentKeepAliveConfig ? {...options.httpAgentKeepAliveConfig} : DefaultKeepAliveConfig);
this.httpsRequestAgent = options.httpsRequestAgent || new KeepAliveAgent.HttpsAgent(options.httpsAgentKeepAliveConfig ? {...options.httpsAgentKeepAliveConfig } : DefaultKeepAliveConfig);
this.hasGetIfExistsCapability = options.hasGetIfExistsCapability;
this.useGetIfExistsByDefault = options.useGetIfExistsByDefault;
this.inMemoryCache = options.inMemoryCache;
this.hasGetIfExistsCapability = options.hasGetIfExistsCapability;
this.useGetIfExistsByDefault = options.useGetIfExistsByDefault;
this.inMemoryCache = options.inMemoryCache;
if(options.logger){
this.logger = options.logger;
......@@ -149,7 +149,6 @@ SC.get = function(path, depth, callback, options){
callback = null;
}
console.log('params', {path, depth, callback, options});
if(!callback){
return new Promise((resolve, reject)=>{
......@@ -225,7 +224,7 @@ SC.getSling = async function(path, options = {}, callback){
resolve(data);
}else{
err = _.isString(err) ? new Error(err) : err
err.slingData = data;
err.slingData = data;
reject(err);
}
})
......@@ -233,7 +232,7 @@ SC.getSling = async function(path, options = {}, callback){
}
//wrap the callback in a try / catch safe function
const actualCb = callback;
const actualCb = callback;
callback = (err, data) => {
try{
actualCb(err, data);
......@@ -243,8 +242,8 @@ SC.getSling = async function(path, options = {}, callback){
}
if(!this.isValidPath(path)){
callback("invalid path provided");
return;
callback("invalid path provided");
return;
}
......@@ -257,7 +256,7 @@ SC.getSling = async function(path, options = {}, callback){
}
// get if exists selector
const useGetIfExists =
const useGetIfExists =
sc_self.hasGetIfExistsCapability && //is the capability enabled
!options.dontParseBody && // dont use on requests that don't parse the body
!_.endsWith(path, '.bl.json') && //don't use on .bl.json requests
......@@ -268,7 +267,7 @@ SC.getSling = async function(path, options = {}, callback){
path = sc_self.util.addSelector(path, selectors.getIfExists, 'json');
}
var preprocess = this.preprocess(path, {method:"GET", options, callback});
......@@ -276,18 +275,18 @@ SC.getSling = async function(path, options = {}, callback){
if(sc_self.inMemoryCache && !options.inMemoryCacheRefresh){
// if this path hasn't already been requested, stick the promise version of it
// in the cache.
// in the cache.
sc_self.inMemoryCache[path] = sc_self.inMemoryCache[path] || sc_self.getSling(path, {...options, inMemoryCacheRefresh: true});
try{
let data = await sc_self.inMemoryCache[path];
let data = await sc_self.inMemoryCache[path];
callback(null, data);
} catch(err){
const errData = err.slingData
delete err.slingData;
callback(err, errData);
}
}else{
if(preprocess.proxy){
preprocess.proxy(preprocess, this, (err, bodyText, res)=>{
......@@ -342,8 +341,8 @@ SC.getSling = async function(path, options = {}, callback){
timeout: options.timeout || quickerTimeoutIfCacheExists || sc_self.timeout,
followRedirect: false,
auth:sc_self.makeAuth(),
headers: sc_self.authCookieHeader(),
agent: sc_self.getRequestAgent(uri),
headers: sc_self.authCookieHeader(),
agent: sc_self.getRequestAgent(uri),
gzip: true
};
......@@ -447,15 +446,15 @@ SC.getSling = async function(path, options = {}, callback){
obj=JSON.parse(bodyText);
if(useGetIfExists){
//need to pluck the actual data out.
//need to pluck the actual data out.
if(_.has(obj, 'exists')){
if(obj.exists){
//the requested path exists, return the result
obj = obj.data;
obj = obj.data;
} else {
//the requested resource doesn't exists. Return "404"
obj = {statusCode: 404};
err = new Error("GetIfExists: The requested resource doesn't exist");
err = new Error("GetIfExists: The requested resource doesn't exist");
}
} else{
//we didn't get the response structure expected. log error, but return
......@@ -524,7 +523,7 @@ SC.getSling = async function(path, options = {}, callback){
var sc_self=this;
if(!cb || typeof(cb) !== "function"){
return new Promise((resolve, reject)=>{
this.checkForBackingFile(path, preprocess, (err, data) =>{
err ? reject(new Error(err)) : resolve(data)
......@@ -617,13 +616,13 @@ SC.isValidPath= function(path) {
return false
}else{
return true;
return true;
}
}
//////////////////////////////////////////////////////////////////////////////////////////
SC.getRequestAgent= function(path = "") {
return path.startsWith("https://") ? this.httpsRequestAgent : this.httpRequestAgent;
return path.startsWith("https://") ? this.httpsRequestAgent : this.httpRequestAgent;
}
......@@ -649,8 +648,8 @@ SC.getStream = function(path, method, headers){
timeout: this.timeout,
followRedirect: false,
auth:this.makeAuth(),
headers: this.authCookieHeader(),
agent: sc_self.getRequestAgent(uri),
headers: this.authCookieHeader(),
agent: sc_self.getRequestAgent(uri),
gzip: true
})
......@@ -676,16 +675,16 @@ SC.getStream = function(path, method, headers){
* @param {function} callback - to call upon completion (err, httpStatusCode, httpResponse, body)
*/
SC.import = function(path, data, options, callback){
if(!callback || typeof(callback) !== "function"){
return new Promise((resolve, reject)=>{
this.import(path, data, options, (err, data) =>{
err ? reject(new Error(err)) : resolve(data)
});
})
}
}
if(typeof options === "function"){
callback=options;
options={}
......@@ -713,7 +712,7 @@ SC.import = function(path, data, options, callback){
//debug("Import form: ", form);
const postUrl = this.buildUri(path);
const postUrl = this.buildUri(path);
request.post({
url: postUrl,
formData: form, // Multi-part mode not necessary, but more efficient for large files than urlencoded
......@@ -883,7 +882,7 @@ SC.util.getNonMeta=function(data, keyProperty, iterator){
}
SC.util.addSelector = (path, selector, extensionCheck) => {
let updatedPath = path;
let updatedPath = path;
//don't add if the selector is already there
if(path.indexOf(`.${selector}`) < 0){
//inject as the first selector
......@@ -898,7 +897,7 @@ SC.util.addSelector = (path, selector, extensionCheck) => {
segment = segmentParts.join('.');
}
return segment;
return segment;
}).join("/");
}else{
let pathParts = path.split(".");
......@@ -907,7 +906,7 @@ SC.util.addSelector = (path, selector, extensionCheck) => {
}
}
return updatedPath;
return updatedPath;
}
......
......@@ -5,7 +5,7 @@ const _ = require("lodash");
const sc = new SlingConnector({baseUri: "../__fixtures__"});
beforeEach(() => {
request.mockClear();
request.mockClear();
});
test('Call getSling with no options', done => {
......@@ -22,16 +22,16 @@ test('Call getSling with leaveMangledNames option', done => {
expect(data['jcr:something']).toBe('also here');
done();
})
});
});
test('default requestAgent', async () => {
await sc.getSling('/content/raw/simple.json');
expect(request).toBeCalled();
expect(request).toBeCalled();
expect(_.first(request.mock.calls)[0].agent).toBeTruthy();
});
test('custom requestAgent', async () => {
const customRequestAgent = new Object();
const customRequestAgent = new Object();
const localSc = sc.clone({httpRequestAgent: customRequestAgent})
await localSc.getSling('/content/raw/simple.json');
expect(request).toBeCalled();
......@@ -51,12 +51,12 @@ describe("inMemoryCache", () => {
const result2 = await sc.getSling('/content/raw/simple.json');
const result3 = await sc.getSling('/content/raw/simple.json');
expect(request).toBeCalledTimes(3);
expect(result1).toStrictEqual(result2);
expect(result2).toStrictEqual(result3);
});
});
test("Call getSling with same params with inMemoryCache", async () => {
let cacheableSc = sc.cacheableClone();
......@@ -65,10 +65,10 @@ describe("inMemoryCache", () => {
const result3 = await cacheableSc.getSling('/content/raw/simple.json');
expect(request).toBeCalledTimes(1);
expect(result1).toStrictEqual(result2);
expect(result2).toStrictEqual(result3);
});
});
});
describe("get-if-exists", () => {
......@@ -79,149 +79,149 @@ describe("get-if-exists", () => {
test("Call getSling with get-if-exists (default) with no other selectors", async () => {
let clonedSc = sc.clone({useGetIfExistsByDefault: true, hasGetIfExistsCapability: true});
const validExistingResult = await clonedSc.getSling('/content/getIfExists/exists.json');
expect(validExistingResult).toHaveProperty("key");
expect(request).toBeCalled();
expect(_.first(request.mock.calls)[0].uri).toMatch(/^.*\.get-if-exists.json$/);
verififyNoDuplicate();
});
verififyNoDuplicate();
});
test("Call getSling with get-if-exists (default) with number selector", async () => {
let clonedSc = sc.clone({useGetIfExistsByDefault: true, hasGetIfExistsCapability: true});
const validExistingResult = await clonedSc.getSling('/content/getIfExists/exists.1.json');
expect(validExistingResult).toHaveProperty("key");
expect(request).toBeCalled();
expect(_.first(request.mock.calls)[0].uri).toMatch(/^.*\.get-if-exists.1.json$/);
verififyNoDuplicate();
});
});
test("Call getSling with get-if-exists (default) with text selector", async () => {
let clonedSc = sc.clone({useGetIfExistsByDefault: true, hasGetIfExistsCapability: true});
const validExistingResult = await clonedSc.getSling('/content/getIfExists/exists.infinity.json');
expect(validExistingResult).toHaveProperty("key");
expect(request).toBeCalled();
expect(_.first(request.mock.calls)[0].uri).toMatch(/^.*\.get-if-exists.infinity.json$/);
verififyNoDuplicate();
verififyNoDuplicate();
});
test("Call getSling with get-if-exists (default) with text and deref selector", async () => {
let clonedSc = sc.clone({useGetIfExistsByDefault: true, hasGetIfExistsCapability: true, hasDerefCapability: true});
const validExistingResult = await clonedSc.getSling('/content/getIfExists/exists.infinity.json', {deref: true});
expect(validExistingResult).toHaveProperty("key");
expect(request).toBeCalled();
expect(_.first(request.mock.calls)[0].uri).toMatch(/^.*\.get-if-exists.deref.infinity.json$/);
verififyNoDuplicate();
});
verififyNoDuplicate();
});
test("Call getSling with get-if-exists (option) with text and deref selector", async () => {
let clonedSc = sc.clone({hasGetIfExistsCapability: true, hasDerefCapability: true});
const validExistingResult = await clonedSc.getSling('/content/getIfExists/exists.infinity.json', {deref: true, useGetIfExists: true});
expect(validExistingResult).toHaveProperty("key");
expect(request).toBeCalled();
expect(_.first(request.mock.calls)[0].uri).toMatch(/^.*\.get-if-exists.deref.infinity.json$/);
verififyNoDuplicate();
});
verififyNoDuplicate();
});
test("Call getSling with get-if-exists (option) against non-existing", async () => {
let clonedSc = sc.clone({hasGetIfExistsCapability: true});
try{
await clonedSc.getSling('/content/getIfExists/doesnt-exist.json', {useGetIfExists: true})
} catch (e){
expect(e).toBeInstanceOf(Error);
expect(e.message).toMatch("The requested resource doesn't exist");
}
expect(request).toBeCalled();
expect(_.first(request.mock.calls)[0].uri).toMatch(/^.*\.get-if-exists.json$/);
verififyNoDuplicate();
});
});
test("Call getSling with get-if-exists (option) with invalid response", async () => {
let clonedSc = sc.clone({hasGetIfExistsCapability: true});
try{
await clonedSc.getSling('/content/getIfExists/invalid-res.json', {useGetIfExists: true})
} catch (e){
expect(e).toBeInstanceOf(Error);
expect(e.message).toMatch("The requested resource doesn't exist");
}
expect(request).toBeCalled();
expect(_.first(request.mock.calls)[0].uri).toMatch(/^.*\.get-if-exists.json$/);
verififyNoDuplicate();
});
verififyNoDuplicate();
});
test("Call getSling with get-if-exists (option) with image path", async () => {
let clonedSc = sc.clone({hasGetIfExistsCapability: true});
try{
await clonedSc.getSling('/content/dam/something/image.jpg/metadata.3.json', {useGetIfExists: true});
}catch(e){
//requesting an asset that doesn't have a mock will always throw an error.
expect(e).toBeTruthy();
//requesting an asset that doesn't have a mock will always throw an error.
expect(e).toBeTruthy();
}
expect(request).toBeCalled();
expect(_.first(request.mock.calls)[0].uri).toMatch(/^.*\.get-if-exists.3.json$/);
verififyNoDuplicate();
});
verififyNoDuplicate();
});
test("Call getSling with get-if-exists (option) with foss-exists", async () => {
let clonedSc = sc.clone({hasGetIfExistsCapability: true});
try{
await clonedSc.getSling('/content/fshr/pages/en.foss-exists.json', {useGetIfExists: true});
}catch(e){
//requesting an asset that doesn't have a mock will always throw an error.
expect(e).toBeTruthy();
//requesting an asset that doesn't have a mock will always throw an error.
expect(e).toBeTruthy();
}
expect(request).toBeCalled();
expect(_.first(request.mock.calls)[0].uri).toMatch(/^.*\.get-if-exists.foss-exists.json$/);
verififyNoDuplicate();
verififyNoDuplicate();
});
test("Call getSling with get-if-exists (option) with dontParseBody", async () => {
let clonedSc = sc.clone({hasGetIfExistsCapability: true});
try{
await clonedSc.getSling('/content/fshr/pages/en.json', {useGetIfExists: true, dontParseBody: true});
}catch(e){
//requesting an asset that doesn't have a mock will always throw an error.
expect(e).toBeTruthy();
//requesting an asset that doesn't have a mock will always throw an error.
expect(e).toBeTruthy();
}
expect(request).toBeCalled();
expect(_.first(request.mock.calls)[0].uri).toMatch(/^.*fshr\/pages\/en.json$/);
});
});
test("Call getSling with get-if-exists (option) with .bl.json", async () => {
let clonedSc = sc.clone({hasGetIfExistsCapability: true});
try{
await clonedSc.getSling('/content/fshr/pages/en.bl.json', {useGetIfExists: true});
}catch(e){
//requesting an asset that doesn't have a mock will always throw an error.
expect(e).toBeTruthy();
//requesting an asset that doesn't have a mock will always throw an error.
expect(e).toBeTruthy();
}
expect(request).toBeCalled();
expect(_.first(request.mock.calls)[0].uri).toMatch(/^.*fshr\/pages\/en.bl.json$/);
});
});
});
describe("Promise vs callback and options", () => {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment