This is an automated email from the ASF dual-hosted git repository.

rabbah pushed a commit to branch master
in repository 
https://gitbox.apache.org/repos/asf/incubator-openwhisk-client-js.git


The following commit(s) were added to refs/heads/master by this push:
     new 8f0e241  switch from request-promise to needle (#78)
8f0e241 is described below

commit 8f0e241da581c9186e8635df3fb1aaf7d2e8979e
Author: Nick Mitchell <star...@users.noreply.github.com>
AuthorDate: Fri Oct 20 13:53:46 2017 -0400

    switch from request-promise to needle (#78)
    
    Switch from request-promise to needle, for an initialization performance 
boost. Fixes #77
    Also adds test coverage for 404 and 409 cases. Fixes #79
    
    * switch from request-promise to needle
    * remove needless clause
    * handle errors for needle
    * improve comments of rp facade code
    * improve error handling test coverage
    * fix for 409 test
---
 lib/client.js                     | 48 ++++++++++++++++++++++++++++++++++++++-
 package.json                      |  2 +-
 test/integration/actions.test.js  | 23 +++++++++++++++++++
 test/integration/packages.test.js |  7 ++++++
 test/integration/rules.test.js    |  7 ++++++
 test/integration/triggers.test.js |  7 ++++++
 6 files changed, 92 insertions(+), 2 deletions(-)

diff --git a/lib/client.js b/lib/client.js
index b6666e8..73dfe4a 100644
--- a/lib/client.js
+++ b/lib/client.js
@@ -5,10 +5,56 @@
 
 const messages = require('./messages')
 const OpenWhiskError = require('./openwhisk_error')
-const rp = require('request-promise')
+const needle = require('needle')
 const url = require('url')
 const http = require('http')
 
+/**
+ * This implements a request-promise-like facade over the needle
+ * library. There are two gaps between needle and rp that need to be
+ * bridged: 1) convert `qs` into a query string; and 2) convert
+ * needle's non-excepting >=400 statusCode responses into exceptions
+ *
+ */
+const rp = opts => {
+    if (opts.qs) {
+        // we turn the qs struct into a query string over the url
+        let first = true
+        for (let key in opts.qs) {
+            const str = 
`${encodeURIComponent(key)}=${encodeURIComponent(opts.qs[key])}`
+            if (first) {
+                opts.url += `?${str}`
+                first = false
+            } else {
+                opts.url += `&${str}`
+            }
+        }
+    }
+
+    // it appears that certain call paths from our code do not set the
+    // opts.json field to true; rp is apparently more resilient to
+    // this situation than needle
+    opts.json = true
+
+    return needle(opts.method.toLowerCase(), // needle takes e.g. 'put' not 
'PUT'
+                  opts.url,
+                  opts.body || opts.params,
+                  opts)
+        .then(resp => {
+            if (resp.statusCode >= 400) {
+                // we turn >=400 statusCode responses into exceptions
+                const error = new Error(resp.body.error || resp.statusMessage)
+                error.statusCode = resp.statusCode   // the http status code
+                error.options = opts                 // the code below 
requires access to the input opts
+                error.error = resp.body              // the error body
+                throw error
+            } else {
+                // otherwise, the response body is the expected return value
+                return resp.body
+            }
+        })
+}
+
 class Client {
   constructor (options) {
     this.options = this.parse_options(options || {})
diff --git a/package.json b/package.json
index 105f154..e856296 100644
--- a/package.json
+++ b/package.json
@@ -42,7 +42,7 @@
     "proxyquire": "1.7.4"
   },
   "dependencies": {
-    "request-promise": "^2.0.1",
+    "needle": "^2.0.1",
     "@types/node": "^8.0.26",
     "@types/swagger-schema-official": "^2.0.6"
   },
diff --git a/test/integration/actions.test.js b/test/integration/actions.test.js
index b1e98e2..d61bd94 100644
--- a/test/integration/actions.test.js
+++ b/test/integration/actions.test.js
@@ -50,6 +50,29 @@ test('list all actions using options namespace', t => {
   })
 })
 
+test('get a non-existing action, expecting 404', async t => {
+  const actions = new Actions(new Client(options))
+  await actions.get({name: 'glorfindel'}).catch(err => {
+      t.is(err.statusCode, 404)
+  })
+})
+
+test('delete a non-existing action, expecting 404', async t => {
+  const actions = new Actions(new Client(options))
+  await actions.delete({name: 'glorfindel'}).catch(err => {
+      t.is(err.statusCode, 404)
+  })
+})
+
+test('create with an existing action, expecting 409', async t => {
+  const actions = new Actions(new Client(options))
+    await actions.create({name: 'glorfindel2', action: 'x=>x'})
+        .then(() => actions.create({name: 'glorfindel2', action: 'x=>x'}))
+        .catch(err => {
+            t.is(err.statusCode, 409)
+        })
+})
+
 test('create, get and delete an action', t => {
   const errors = err => {
     console.log(err)
diff --git a/test/integration/packages.test.js 
b/test/integration/packages.test.js
index 7bb7ffe..d0a66e0 100644
--- a/test/integration/packages.test.js
+++ b/test/integration/packages.test.js
@@ -49,6 +49,13 @@ test('list all packages using options namespace', t => {
   })
 })
 
+test('get a non-existing package, expecting 404', async t => {
+  const packages = new Packages(new Client(options))
+  await packages.get({name: 'glorfindel'}).catch(err => {
+      t.is(err.statusCode, 404)
+  })
+})
+
 test('create, get and delete an package', t => {
   const errors = err => {
     console.log(err)
diff --git a/test/integration/rules.test.js b/test/integration/rules.test.js
index b1e5f84..434bab9 100644
--- a/test/integration/rules.test.js
+++ b/test/integration/rules.test.js
@@ -51,6 +51,13 @@ test('list all rules using options namespace', t => {
   })
 })
 
+test('get a non-existing rule, expecting 404', async t => {
+  const rules = new Rules(new Client(options))
+  await rules.get({name: 'glorfindel'}).catch(err => {
+      t.is(err.statusCode, 404)
+  })
+})
+
 // Running update tests conconcurrently leads to resource conflict errors.
 test.serial('create, get and delete a rule', t => {
   const errors = err => {
diff --git a/test/integration/triggers.test.js 
b/test/integration/triggers.test.js
index d49f08c..4b68e2b 100644
--- a/test/integration/triggers.test.js
+++ b/test/integration/triggers.test.js
@@ -49,6 +49,13 @@ test('list all triggers using options namespace', t => {
   })
 })
 
+test('get a non-existing trigger, expecting 404', async t => {
+  const triggers = new Triggers(new Client(options))
+  await triggers.get({name: 'glorfindel'}).catch(err => {
+      t.is(err.statusCode, 404)
+  })
+})
+
 test('create, get and delete an trigger', t => {
   const errors = err => {
     console.log(err)

-- 
To stop receiving notification emails like this one, please contact
['"commits@openwhisk.apache.org" <commits@openwhisk.apache.org>'].

Reply via email to