You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ga...@apache.org on 2017/08/03 14:05:42 UTC

[couchdb-fauxton] branch master updated: (#938) - Refactor CORS tests to run with Jest and Enzyme

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

garren pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/couchdb-fauxton.git


The following commit(s) were added to refs/heads/master by this push:
     new 2ed28b1  (#938) - Refactor CORS tests to run with Jest and Enzyme
2ed28b1 is described below

commit 2ed28b1222df1b3065aec37a82e54ef469b5ae73
Author: Antonio Maranhao <30...@users.noreply.github.com>
AuthorDate: Thu Aug 3 10:05:40 2017 -0400

    (#938) - Refactor CORS tests to run with Jest and Enzyme
---
 .../actionsSpecs.js => __tests__/actions.test.js}  |  49 +++--
 app/addons/cors/__tests__/components.test.js       | 214 ++++++++++++++++++
 .../resources.test.js}                             |  40 ++--
 .../storesSpec.js => __tests__/stores.test.js}     |  38 ++--
 app/addons/cors/tests/componentsSpec.js            | 239 ---------------------
 5 files changed, 283 insertions(+), 297 deletions(-)

diff --git a/app/addons/cors/tests/actionsSpecs.js b/app/addons/cors/__tests__/actions.test.js
similarity index 70%
rename from app/addons/cors/tests/actionsSpecs.js
rename to app/addons/cors/__tests__/actions.test.js
index 2188ebd..124845d 100644
--- a/app/addons/cors/tests/actionsSpecs.js
+++ b/app/addons/cors/__tests__/actions.test.js
@@ -17,84 +17,92 @@ import sinon from "sinon";
 const assert = utils.assert;
 const restore = utils.restore;
 
-describe('CORS actions', function () {
+describe('CORS actions', () => {
 
-  describe('save', function () {
+  describe('save', () => {
 
-    afterEach(function () {
+    let localNode = 'node2@127.0.0.1';
+
+    afterEach(() => {
       restore(Actions.saveCorsOrigins);
 
       restore(FauxtonAPI.when);
       restore(FauxtonAPI.addNotification);
     });
 
-    it('should save cors enabled to httpd', function () {
+    it('should save cors enabled to httpd', () => {
       var spy = sinon.spy(Actions, 'saveEnableCorsToHttpd');
 
       Actions.saveCors({
-        enableCors: false
+        enableCors: false,
+        node: localNode
       });
 
       assert.ok(spy.calledWith(false));
     });
 
-    it('does not save cors origins if cors not enabled', function () {
+    it('does not save cors origins if cors not enabled', () => {
       var spy = sinon.spy(Actions, 'saveCorsOrigins');
 
       Actions.saveCors({
         enableCors: false,
-        origins: ['*']
+        origins: ['*'],
+        node: localNode
       });
 
       assert.notOk(spy.calledOnce);
     });
 
-    it('saves cors origins', function () {
+    it('saves cors origins', () => {
       var spy = sinon.spy(Actions, 'saveCorsOrigins');
 
       Actions.saveCors({
         enableCors: true,
-        origins: ['*']
+        origins: ['*'],
+        node: localNode
       });
 
       assert.ok(spy.calledWith('*'));
     });
 
-    it('saves cors allow credentials', function () {
+    it('saves cors allow credentials', () => {
       var spy = sinon.spy(Actions, 'saveCorsCredentials');
 
       Actions.saveCors({
         enableCors: true,
-        origins: ['https://testdomain.com']
+        origins: ['https://testdomain.com'],
+        node: localNode
       });
 
       assert.ok(spy.calledOnce);
     });
 
-    it('saves cors headers', function () {
+    it('saves cors headers', () => {
       var spy = sinon.spy(Actions, 'saveCorsHeaders');
 
       Actions.saveCors({
         enableCors: true,
-        origins: ['https://testdomain.com']
+        origins: ['https://testdomain.com'],
+        node: localNode
       });
 
       assert.ok(spy.calledOnce);
     });
 
-    it('saves cors methods', function () {
+    it('saves cors methods', () => {
       var spy = sinon.spy(Actions, 'saveCorsMethods');
 
       Actions.saveCors({
         enableCors: true,
-        origins: ['https://testdomain.com']
+        origins: ['https://testdomain.com'],
+        node: localNode
       });
 
       assert.ok(spy.calledOnce);
 
     });
 
-    it('shows notification on successful save', function () {
+    it('shows notification on successful save', () => {
       var stub = sinon.stub(FauxtonAPI, 'when');
       var spy = sinon.spy(FauxtonAPI, 'addNotification');
       var promise = FauxtonAPI.Deferred();
@@ -103,7 +111,8 @@ describe('CORS actions', function () {
 
       Actions.saveCors({
         enableCors: true,
-        origins: ['https://testdomain.com']
+        origins: ['https://testdomain.com'],
+        node: localNode
       });
 
       assert.ok(spy.calledOnce);
@@ -111,15 +120,15 @@ describe('CORS actions', function () {
 
   });
 
-  describe('Sanitize origins', function () {
+  describe('Sanitize origins', () => {
 
-    it('joins array into string', function () {
+    it('joins array into string', () => {
       var origins = ['https://hello.com', 'https://hello2.com'];
 
       assert.deepEqual(Actions.sanitizeOrigins(origins), origins.join(','));
     });
 
-    it('returns empty string for no origins', function () {
+    it('returns empty string for no origins', () => {
       var origins = [];
 
       assert.deepEqual(Actions.sanitizeOrigins(origins), '');
diff --git a/app/addons/cors/__tests__/components.test.js b/app/addons/cors/__tests__/components.test.js
new file mode 100644
index 0000000..d61f7e9
--- /dev/null
+++ b/app/addons/cors/__tests__/components.test.js
@@ -0,0 +1,214 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+import FauxtonAPI from "../../../core/api";
+import Views from "../components";
+import Actions from "../actions";
+import Resources from "../resources";
+import Stores from "../stores";
+import utils from "../../../../test/mocha/testUtils";
+import React from "react";
+import ReactDOM from "react-dom";
+import sinon from "sinon";
+import { shallow, mount } from 'enzyme';
+
+FauxtonAPI.router = new FauxtonAPI.Router([]);
+const {assert, restore} = utils;
+const corsStore = Stores.corsStore;
+
+describe('CORS Components', () => {
+
+  describe('CorsController', () => {
+
+    beforeEach(() => {
+      corsStore._origins = ['http://hello.com'];
+      corsStore._node = 'node2@127.0.0.1';
+      corsStore._isEnabled = true;
+      corsStore._configChanged = true;
+    });
+
+    afterEach(() => {
+      restore(window.confirm);
+    });
+
+    it('confirms user change from restricted origin to disabled cors', () => {
+      const spy = sinon.stub(window, 'confirm');
+      spy.returns(false);
+
+      const wrapper = shallow(<Views.CORSController />);
+      wrapper.find('.enable-disable .btn').simulate('click');
+      assert.ok(spy.calledOnce);
+    });
+
+    it('does not confirm user change to disable cors when restricted origins are empty', () => {
+      const spy = sinon.stub(window, 'confirm');
+      spy.returns(false);
+
+      // Set selected origins to empty
+      corsStore._origins = [];
+
+      const wrapper = shallow(<Views.CORSController />);
+      wrapper.find('.enable-disable .btn').simulate('click');
+      assert.ok(spy.notCalled);
+    });
+
+    it('confirms user change when moving from selected origins to all origins', () => {
+      const spy = sinon.stub(window, 'confirm');
+      spy.returns(false);
+
+      const wrapper = mount(<Views.CORSController />);
+      wrapper.find('input').at(0).simulate('change', {target: {checked: true, value: 'all'}});
+      assert.ok(spy.calledOnce);
+    });
+
+    it('does not confirm all origins change if selected origins are emtpy', () => {
+      const spy = sinon.stub(window, 'confirm');
+      spy.returns(false);
+
+      // Set selected origins to empty
+      corsStore._origins = [];
+
+      const wrapper = mount(<Views.CORSController />);
+      wrapper.find('input').at(0).simulate('change', {target: {checked: true, value: 'all'}});
+      assert.notOk(spy.calledOnce);
+    });
+
+    it('shows loading bars', () => {
+      const wrapper = mount(<Views.CORSController />);
+      Actions.toggleLoadingBarsToEnabled(true);
+      assert.ok(wrapper.find('.loading-lines').exists());
+    });
+
+    it('hides loading bars', () => {
+      const wrapper = mount(<Views.CORSController />);
+      Actions.toggleLoadingBarsToEnabled(false);
+      assert.notOk(wrapper.find('.loading-lines').exists());
+    });
+  });
+
+  describe('OriginInput', () => {
+    const newOrigin = 'http://new-site.com';
+
+    it('calls validates each domain', () => {
+      const spyValidateCORSDomain = sinon.spy(Resources, 'validateCORSDomain');
+      const addOriginStub = sinon.stub();
+      const wrapper = shallow(<Views.OriginInput isVisible={true} addOrigin={addOriginStub}/>);
+
+      wrapper.find('input').simulate('change', {target: {value: newOrigin}});
+      wrapper.find('.btn').simulate('click', {preventDefault: sinon.stub()});
+      assert.ok(spyValidateCORSDomain.calledWith(newOrigin));
+    });
+
+    it('calls addOrigin on add click with valid domain', () => {
+      const addOriginSpy = sinon.spy();
+      const wrapper = shallow(<Views.OriginInput isVisible={true} addOrigin={addOriginSpy}/>);
+
+      wrapper.find('input').simulate('change', {target: {value: newOrigin}});
+      wrapper.find('.btn').simulate('click', {preventDefault: sinon.stub()});
+      assert.ok(addOriginSpy.calledWith(newOrigin));
+    });
+
+    it('shows notification if origin is not valid', () => {
+      const spyAddNotification = sinon.spy(FauxtonAPI, 'addNotification');
+      const wrapper = shallow(<Views.OriginInput isVisible={true} addOrigin={sinon.stub()}/>);
+
+      wrapper.find('input').simulate('change', {target: {value: 'badOrigin'}});
+      wrapper.find('.btn').simulate('click', {preventDefault: sinon.stub()});
+      assert.ok(spyAddNotification.calledOnce);
+    });
+  });
+
+  describe('Origins', () => {
+    const spyChangeOrigin = sinon.spy();
+
+    afterEach(() => {
+      spyChangeOrigin.reset();
+    });
+
+    it('calls changeOrigin() when you switch from "Select List of Origins" to "Allow All Origins"', () => {
+      const wrapper = shallow(<Views.Origins corsEnabled={true} isAllOrigins={false} originChange={spyChangeOrigin}/>);
+
+      wrapper.find('input[value="all"]').simulate('change', {target: {checked: true, value: 'all'}});
+      assert.ok(spyChangeOrigin.calledWith(true));
+    });
+
+    it('calls changeOrigin() when you switch from "Allow All Origins" to "Select List of Origins"', () => {
+      const wrapper = shallow(<Views.Origins corsEnabled={true} isAllOrigins={true} originChange={spyChangeOrigin}/>);
+
+      wrapper.find('input[value="selected"]').simulate('change', {target: {checked: true, value: 'selected'}});
+      assert.ok(spyChangeOrigin.calledWith(false));
+    });
+  });
+
+  describe('OriginRow', () => {
+    const spyUpdateOrigin = sinon.spy();
+    let origin;
+
+    beforeEach(() => {
+      origin = 'https://hello.com';
+    });
+
+    afterEach(() => {
+      spyUpdateOrigin.reset();
+    });
+
+    it('should show confirm modal on delete', () => {
+      const wrapper = mount(<Views.OriginTable updateOrigin={spyUpdateOrigin} isVisible={true} origins={[origin]}/>);
+
+      wrapper.find('.fonticon-trash').simulate('click', { preventDefault: sinon.stub() });
+      assert.ok(corsStore.isDeleteDomainModalVisible());
+    });
+
+    it('does not throw error if origins is undefined', () => {
+      mount(<Views.OriginTable updateOrigin={spyUpdateOrigin} isVisible={true} origins={false}/>);
+    });
+
+    it('should change origin to input on edit click, then hide input on 2nd click', () => {
+      const wrapper = mount(<Views.OriginTable updateOrigin={spyUpdateOrigin} isVisible={true} origins={[origin]}/>);
+      // Text input appears after clicking Edit
+      wrapper.find('.fonticon-pencil').simulate('click', { preventDefault: sinon.stub() });
+      assert.ok(wrapper.find('input').exists());
+
+      // Text input is hidden after clicking Edit for the 2nd time
+      wrapper.find('.fonticon-pencil').simulate('click', { preventDefault: sinon.stub() });
+      assert.notOk(wrapper.find('input').exists());
+    });
+
+    it('should update origin on update clicked', () => {
+      let updatedOrigin = 'https://updated-origin.com';
+      const wrapper = mount(
+        <Views.OriginTable
+          updateOrigin={spyUpdateOrigin}
+          isVisible={true} origins={[origin]}/>
+      );
+
+      wrapper.find('.fonticon-pencil').simulate('click', { preventDefault: sinon.stub() });
+      wrapper.find('input').simulate('change', {target: {value: updatedOrigin}});
+      wrapper.find('.btn').at(0).simulate('click', { preventDefault: sinon.stub() });
+      assert.ok(spyUpdateOrigin.calledWith(updatedOrigin));
+    });
+
+    it('should not update origin on update clicked with bad origin', () => {
+      let updatedOrigin = 'updated-origin';
+      const wrapper = mount(
+        <Views.OriginTable
+          updateOrigin={spyUpdateOrigin}
+          isVisible={true} origins={[origin]}/>
+      );
+      wrapper.find('.fonticon-pencil').simulate('click', { preventDefault: sinon.stub() });
+      wrapper.find('input').simulate('change', {target: {value: updatedOrigin}});
+      wrapper.find('.btn').at(0).simulate('click', { preventDefault: sinon.stub() });
+      assert.notOk(spyUpdateOrigin.calledWith(updatedOrigin));
+    });
+
+  });
+
+});
diff --git a/app/addons/cors/tests/resourcesSpec.js b/app/addons/cors/__tests__/resources.test.js
similarity index 69%
rename from app/addons/cors/tests/resourcesSpec.js
rename to app/addons/cors/__tests__/resources.test.js
index e75efc6..322b168 100644
--- a/app/addons/cors/tests/resourcesSpec.js
+++ b/app/addons/cors/__tests__/resources.test.js
@@ -11,35 +11,35 @@
 // the License.
 import testUtils from "../../../../test/mocha/testUtils";
 import CORS from "../resources";
-var assert = testUtils.assert;
+const assert = testUtils.assert;
 
-describe('Cors Config Model', function () {
-  var cors;
+describe('Cors Config Model', () => {
+  let cors;
 
-  beforeEach(function () {
-    cors = new CORS.Config(null, {node: 'node2@127.0.0.1'});
+  beforeEach(() => {
+    cors = new CORS.Config(null, { node: 'node2@127.0.0.1' });
   });
 
-  it('Splits up origins into array', function () {
-    var origins = ['http://hello.com', 'http://another.co.a'];
-    cors.set(cors.parse({origins: origins.join(',')}));
+  it('Splits up origins into array', () => {
+    const origins = ['http://hello.com', 'http://another.co.a'];
+    cors.set(cors.parse({ origins: origins.join(',') }));
     assert.deepEqual(cors.get('origins'), origins);
   });
 
-  it('returns empty array for undefined', function () {
-    var origins = { origins : undefined };
+  it('returns empty array for undefined', () => {
+    const origins = { origins: undefined };
     cors.set(cors.parse(origins));
     assert.deepEqual(cors.get('origins'), []);
   });
 
-  it('does not return an empty string (empty origin), when "specific origins" is set, but there are no domains on that list', function () {
-      var emptyOrigins = {origins: ''};
-      cors.set(cors.parse(emptyOrigins));
-      assert.deepEqual(cors.get('origins'), []);
-    });
+  it('does not return an empty string (empty origin), when "specific origins" is set, but there are no domains on that list', () => {
+    const emptyOrigins = { origins: '' };
+    cors.set(cors.parse(emptyOrigins));
+    assert.deepEqual(cors.get('origins'), []);
+  });
 
-  it('allows valid domains', function () {
-    var urls = [
+  it('allows valid domains', () => {
+    const urls = [
       'http://something.com',
       'https://a.ca',
       'https://something.com:8000',
@@ -54,8 +54,8 @@ describe('Cors Config Model', function () {
     });
   });
 
-  it('fails on non http/https domains', function () {
-    var urls = [
+  it('fails on non http/https domains', () => {
+    const urls = [
       'whoahnellythisaintright',
       'ftp://site.com'
     ];
@@ -64,7 +64,7 @@ describe('Cors Config Model', function () {
     });
   });
 
-  it('normalizes common cases, like accidentally added subfolders', function () {
+  it('normalizes common cases, like accidentally added subfolders', () => {
     assert.equal('https://foo.com', CORS.normalizeUrls('https://foo.com/blerg'));
     assert.equal('https://192.168.1.113', CORS.normalizeUrls('https://192.168.1.113/blerg'));
     assert.equal('https://foo.com:1337', CORS.normalizeUrls('https://foo.com:1337/blerg'));
diff --git a/app/addons/cors/tests/storesSpec.js b/app/addons/cors/__tests__/stores.test.js
similarity index 71%
rename from app/addons/cors/tests/storesSpec.js
rename to app/addons/cors/__tests__/stores.test.js
index f9ee787..e9be117 100644
--- a/app/addons/cors/tests/storesSpec.js
+++ b/app/addons/cors/__tests__/stores.test.js
@@ -11,34 +11,36 @@
 // the License.
 import testUtils from "../../../../test/mocha/testUtils";
 import Stores from "../stores";
-var assert = testUtils.assert;
-var store = Stores.corsStore;
+const assert = testUtils.assert;
+const store = Stores.corsStore;
 
-describe('CORS store', function () {
+describe('CORS store', () => {
 
-  describe('isAllOrigins', function () {
+  describe('isAllOrigins', () => {
 
-    it('returns true for all origins', function () {
+    it('returns true for all origins', () => {
       store._origins = ['*'];
 
       assert.ok(store.isAllOrigins());
     });
 
-    it('returns false for specific origins', function () {
+    it('returns false for specific origins', () => {
       store._origins = ['https://hello.com', 'http://another.com'];
+
       assert.notOk(store.isAllOrigins());
     });
 
-    it('returns false for empty array', function () {
+    it('returns false for empty array', () => {
       store._origins = [];
+
       assert.notOk(store.isAllOrigins());
     });
   });
 
-  describe('addOrigin', function () {
+  describe('addOrigin', () => {
 
-    it('adds Origin to list', function () {
-      var origin = 'http://hello.com';
+    it('adds Origin to list', () => {
+      const origin = 'http://hello.com';
       store._origins = [];
       store.addOrigin(origin);
 
@@ -47,15 +49,15 @@ describe('CORS store', function () {
 
   });
 
-  describe('originChange', function () {
+  describe('originChange', () => {
 
-    it('sets origins to * for true', function () {
+    it('sets origins to * for true', () => {
       store.originChange(true);
 
       assert.deepEqual(store.getOrigins(), ['*']);
     });
 
-    it('sets origins to [] for true', function () {
+    it('sets origins to [] for true', () => {
       store.originChange(false);
 
       assert.deepEqual(store.getOrigins(), []);
@@ -63,9 +65,9 @@ describe('CORS store', function () {
 
   });
 
-  describe('deleteOrigin', function () {
+  describe('deleteOrigin', () => {
 
-    it('removes origin', function () {
+    it('removes origin', () => {
       store._origins = ['http://first.com', 'http://hello.com', 'http://second.com'];
       store.deleteOrigin('http://hello.com');
 
@@ -75,9 +77,9 @@ describe('CORS store', function () {
 
   });
 
-  describe('update origin', function () {
+  describe('update origin', () => {
 
-    it('removes old origin', function () {
+    it('removes old origin', () => {
       store._origins = ['http://first.com', 'http://hello.com', 'http://second.com'];
       store.updateOrigin('http://hello123.com', 'http://hello.com');
 
@@ -85,7 +87,7 @@ describe('CORS store', function () {
 
     });
 
-    it('adds new origin', function () {
+    it('adds new origin', () => {
       store._origins = ['http://first.com', 'http://hello.com', 'http://second.com'];
       store.updateOrigin('http://hello123.com', 'http://hello.com');
 
diff --git a/app/addons/cors/tests/componentsSpec.js b/app/addons/cors/tests/componentsSpec.js
deleted file mode 100644
index 1c39b5f..0000000
--- a/app/addons/cors/tests/componentsSpec.js
+++ /dev/null
@@ -1,239 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-import FauxtonAPI from "../../../core/api";
-import Views from "../components";
-import Actions from "../actions";
-import Resources from "../resources";
-import Stores from "../stores";
-import utils from "../../../../test/mocha/testUtils";
-import React from "react";
-import ReactDOM from "react-dom";
-import TestUtils from "react-addons-test-utils";
-import sinon from "sinon";
-
-FauxtonAPI.router = new FauxtonAPI.Router([]);
-var assert = utils.assert;
-var corsStore = Stores.corsStore;
-
-describe('CORS Components', function () {
-
-
-  describe('CorsController', function () {
-    var container, corsEl;
-
-    beforeEach(function () {
-      container = document.createElement('div');
-      corsStore._origins = ['http://hello.com'];
-      corsStore._node = 'node2@127.0.0.1';
-      corsStore._isEnabled = true;
-      corsStore._configChanged = true;
-      corsEl = TestUtils.renderIntoDocument(<Views.CORSController />, container);
-      //stub this out so it doesn't keep trying to save cors and crash phantomjs
-      sinon.stub(corsEl, 'save');
-    });
-
-    afterEach(function () {
-      utils.restore(Actions.toggleLoadingBarsToEnabled);
-      utils.restore(corsEl.save);
-
-      ReactDOM.unmountComponentAtNode(container);
-      window.confirm.restore && window.confirm.restore();
-    });
-
-    it('confirms user change from restricted origin to disabled cors', function () {
-      var spy = sinon.stub(window, 'confirm');
-      spy.returns(false);
-      corsEl.state.isAllOrigins = false;
-      corsEl.state.corsEnabled = true;
-      corsEl.enableCorsChange();
-      assert.ok(spy.calledOnce);
-    });
-
-    it('does not confirm for selected origins are emtpy for disabled cors change', function () {
-      var spy = sinon.stub(window, 'confirm');
-      sinon.stub(Actions, 'toggleLoadingBarsToEnabled');
-      spy.returns(false);
-      corsEl.state.corsEnabled = true;
-      corsEl.state.isAllOrigins = false;
-      corsEl.state.origins = [];
-      corsEl.enableCorsChange();
-      assert.notOk(spy.calledOnce);
-    });
-
-    it('confirms user change when moving from selected origins to all origins', function () {
-      var spy = sinon.stub(window, 'confirm');
-      spy.returns(false);
-      corsEl.state.corsEnabled = true;
-      corsEl.state.isAllOrigins = false;
-      corsEl.originChange(true);
-      assert.ok(spy.calledOnce);
-    });
-
-    it('does not confirm all origins change if selected origins are emtpy', function () {
-      var spy = sinon.stub(window, 'confirm');
-      sinon.stub(Actions, 'toggleLoadingBarsToEnabled');
-      spy.returns(false);
-      corsEl.state.corsEnabled = true;
-      corsEl.state.isAllOrigins = false;
-      corsEl.state.origins = [];
-      corsEl.originChange(true);
-
-      assert.notOk(spy.calledOnce);
-    });
-
-    it('shows loading bars', function () {
-      Actions.toggleLoadingBarsToEnabled(true);
-      assert.equal($(ReactDOM.findDOMNode(corsEl)).find('.loading-lines').length, 1);
-    });
-
-    it('hides loading bars', function () {
-      Actions.toggleLoadingBarsToEnabled(false);
-
-      assert.equal($(ReactDOM.findDOMNode(corsEl)).find('.loading-lines').length, 0);
-    });
-  });
-
-  describe('OriginInput', function () {
-    var container, inputEl, addOrigin;
-    var newOrigin = 'http://new-site.com';
-
-    beforeEach(function () {
-      addOrigin = sinon.spy();
-      container = document.createElement('div');
-      inputEl = TestUtils.renderIntoDocument(<Views.OriginInput isVisible={true} addOrigin={addOrigin}/>, container);
-    });
-
-    afterEach(function () {
-      utils.restore(Resources.validateCORSDomain);
-      utils.restore(FauxtonAPI.addNotification);
-      ReactDOM.unmountComponentAtNode(container);
-    });
-
-    it('calls validates each domain', function () {
-      var spy = sinon.spy(Resources, 'validateCORSDomain');
-      TestUtils.Simulate.change($(ReactDOM.findDOMNode(inputEl)).find('input')[0], {target: {value: newOrigin}});
-      TestUtils.Simulate.click($(ReactDOM.findDOMNode(inputEl)).find('.btn')[0]);
-      assert.ok(spy.calledWith(newOrigin));
-    });
-
-    it('calls addOrigin on add click with valid domain', function () {
-      TestUtils.Simulate.change($(ReactDOM.findDOMNode(inputEl)).find('input')[0], {target: {value: newOrigin}});
-      TestUtils.Simulate.click($(ReactDOM.findDOMNode(inputEl)).find('.btn')[0]);
-      assert.ok(addOrigin.calledWith(newOrigin));
-    });
-
-    it('shows notification if origin is not valid', function () {
-      var spy = sinon.spy(FauxtonAPI, 'addNotification');
-      TestUtils.Simulate.change($(ReactDOM.findDOMNode(inputEl)).find('input')[0], {target: {value: 'badOrigin'}});
-      TestUtils.Simulate.click($(ReactDOM.findDOMNode(inputEl)).find('.btn')[0]);
-      assert.ok(spy.calledOnce);
-    });
-  });
-
-  describe('Origins', function () {
-    var container, originEl, changeOrigin;
-
-    beforeEach(function () {
-      changeOrigin = sinon.spy();
-      container = document.createElement('div');
-      originEl = TestUtils.renderIntoDocument(<Views.Origins corsEnabled={true} isAllOrigins={false} originChange={changeOrigin}/>, container);
-    });
-
-    afterEach(function () {
-      ReactDOM.unmountComponentAtNode(container);
-    });
-
-    it('calls change Origin on all origins selected', function () {
-      TestUtils.Simulate.change($(ReactDOM.findDOMNode(originEl)).find('input[value="all"]')[0]);
-      assert.ok(changeOrigin.calledWith(true));
-    });
-
-    it('calls changeOrigin() when you switch from "Allow All Origins" to "Select List of Origins"', function () {
-      //changeOrigin(true) = sets origins to ['*']
-      //changeOrigin(false) = sets origins to [] (an empty array which user can populate with URLs)
-
-      //this test begins with 'select origins' checked,
-      //1. render radio buttons with 'all origins'
-      originEl = TestUtils.renderIntoDocument(<Views.Origins corsEnabled={true} isAllOrigins={true} originChange={changeOrigin}/>, container);
-      //2. switch back to 'select origins'
-      TestUtils.Simulate.change($(ReactDOM.findDOMNode(originEl)).find('input[value="selected"]')[0]);
-      assert.ok(changeOrigin.calledWith(false));
-    });
-  });
-
-  describe('OriginRow', function () {
-    var container, originTableEl, origin, deleteOrigin, updateOrigin;
-
-    beforeEach(function () {
-      deleteOrigin = sinon.spy();
-      updateOrigin = sinon.spy();
-      container = document.createElement('div');
-      origin = 'https://hello.com';
-      //because OriginRow is inside a table have to render the whole table to test
-      originTableEl = TestUtils.renderIntoDocument(<Views.OriginTable updateOrigin={updateOrigin} deleteOrigin={deleteOrigin} isVisible={true} origins={[origin]}/>, container);
-    });
-
-    afterEach(function () {
-      window.confirm.restore && window.confirm.restore();
-      Actions.deleteOrigin.restore && Actions.deleteOrigin.restore();
-      ReactDOM.unmountComponentAtNode(container);
-      Actions.hideDeleteDomainModal();
-    });
-
-    it('should show confirm modal on delete', function () {
-      assert.equal($('body').find('.confirmation-modal').length, 0);
-      TestUtils.Simulate.click($(ReactDOM.findDOMNode(originTableEl)).find('.fonticon-trash')[0]);
-      assert.notEqual($('body').find('.confirmation-modal').length, 1); // a little sneaky.
-    });
-
-    it('does not throw on origins being undefined', function () {
-      TestUtils.renderIntoDocument(
-        <Views.OriginTable
-          updateOrigin={updateOrigin}
-          isVisible={true}
-          origins={false} />,
-        container
-      );
-    });
-
-    it('should change origin to input on edit click', function () {
-      TestUtils.Simulate.click($(ReactDOM.findDOMNode(originTableEl)).find('.fonticon-pencil')[0]);
-      assert.ok($(ReactDOM.findDOMNode(originTableEl)).find('input').length === 1);
-    });
-
-    it('should update origin on update clicked', function () {
-      var updatedOrigin = 'https://updated-origin.com';
-      TestUtils.Simulate.click($(ReactDOM.findDOMNode(originTableEl)).find('.fonticon-pencil')[0]);
-      TestUtils.Simulate.change($(ReactDOM.findDOMNode(originTableEl)).find('input')[0], {
-        target: {
-          value: updatedOrigin
-        }
-      });
-      TestUtils.Simulate.click($(ReactDOM.findDOMNode(originTableEl)).find('.btn')[0]);
-      assert.ok(updateOrigin.calledWith(updatedOrigin));
-    });
-
-    it('should not update origin on update clicked with bad origin', function () {
-      var updatedOrigin = 'updated-origin';
-      TestUtils.Simulate.click($(ReactDOM.findDOMNode(originTableEl)).find('.fonticon-pencil')[0]);
-      TestUtils.Simulate.change($(ReactDOM.findDOMNode(originTableEl)).find('input')[0], {
-        target: {
-          value: updatedOrigin
-        }
-      });
-      TestUtils.Simulate.click($(ReactDOM.findDOMNode(originTableEl)).find('.btn')[0]);
-      assert.notOk(updateOrigin.calledOnce);
-    });
-
-  });
-
-});

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