Report network failures to plugins

Usage:

plugin.get(url).then(doStuff).catch(onError);
plugin.post(url, payload).then(doStuff).catch(onError);

onError will receive an error string, that is one of the following:
- error message from Gerrit REST API, eg. "Cherry pick failed: ..."
- error message from Fetch API, eg "TypeError: Failed to fetch"
- HTTP failure code, eg "404"

Bug: Issue 6595
Change-Id: I1a598fe2c249c8e87bc575359d51ad2e15431356
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface_test.html b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface_test.html
index 761fe2a..1ff08ea 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface_test.html
@@ -47,7 +47,7 @@
     setup(() => {
       sandbox = sinon.sandbox.create();
       getResponseObjectStub = sandbox.stub().returns(Promise.resolve());
-      sendStub = sandbox.stub().returns(Promise.resolve());
+      sendStub = sandbox.stub().returns(Promise.resolve({status: 200}));
       stub('gr-rest-api-interface', {
         getAccount() {
           return Promise.resolve({name: 'Judy Hopps'});
@@ -76,24 +76,47 @@
           'http://test.com/plugins/testplugin/static/test.js');
     });
 
-    test('get', done => {
-      const response = {foo: 'foo'};
-      getResponseObjectStub.returns(Promise.resolve(response));
-      plugin.get('/url', r => {
-        assert.isTrue(sendStub.calledWith('GET', '/url'));
-        assert.strictEqual(r, response);
-        done();
+    test('_send on failure rejects with response text', () => {
+      sendStub.returns(Promise.resolve(
+          {status: 400, text() {return Promise.resolve('text');}}));
+      return plugin._send().catch(r => {
+        assert.equal(r, 'text');
       });
     });
 
-    test('post', done => {
+    test('_send on failure without text rejects with code', () => {
+      sendStub.returns(Promise.resolve(
+          {status: 400, text() {return Promise.resolve(null);}}));
+      return plugin._send().catch(r => {
+        assert.equal(r, '400');
+      });
+    });
+
+    test('get', () => {
+      const response = {foo: 'foo'};
+      getResponseObjectStub.returns(Promise.resolve(response));
+      return plugin.get('/url', r => {
+        assert.isTrue(sendStub.calledWith('GET', '/url'));
+        assert.strictEqual(r, response);
+      });
+    });
+
+    test('get using Promise', () => {
+      const response = {foo: 'foo'};
+      getResponseObjectStub.returns(Promise.resolve(response));
+      return plugin.get('/url', r => 'rubbish').then(r => {
+        assert.isTrue(sendStub.calledWith('GET', '/url'));
+        assert.strictEqual(r, response);
+      });
+    });
+
+    test('post', () => {
       const payload = {foo: 'foo'};
       const response = {bar: 'bar'};
       getResponseObjectStub.returns(Promise.resolve(response));
-      plugin.post('/url', payload, r => {
+      return plugin.post('/url', payload, r => {
         assert.isTrue(sendStub.calledWith('POST', '/url', payload));
         assert.strictEqual(r, response);
-        done();
       });
     });