button no longer active after replication

Project: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/commit/597fd8c2
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/tree/597fd8c2
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/diff/597fd8c2

Branch: refs/heads/new-replication
Commit: 597fd8c2ae4a5e2bedd0f1856438ede7b4c0fe08
Parents: 0ffc579
Author: Garren Smith <garren.sm...@gmail.com>
Authored: Wed Sep 14 14:35:33 2016 +0200
Committer: Garren Smith <garren.sm...@gmail.com>
Committed: Wed Sep 14 17:22:30 2016 +0200

----------------------------------------------------------------------
 Gruntfile.js                                    |   8 +-
 app/addons/replication/actions.js               |   4 +
 app/addons/replication/actiontypes.js           |   3 +-
 .../replication/assets/less/replication.less    |   4 +-
 app/addons/replication/controller.js            |  29 ++-
 app/addons/replication/stores.js                |  14 ++
 app/addons/replication/tests/controllerSpec.js  |   1 -
 app/addons/replication/tests/replicationSpec.js | 213 -------------------
 package.json                                    |   3 +-
 test/dev.js                                     |   2 +-
 test/test.config.underscore                     |   1 +
 webpack.config.test.js                          |  17 +-
 12 files changed, 68 insertions(+), 231 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/597fd8c2/Gruntfile.js
----------------------------------------------------------------------
diff --git a/Gruntfile.js b/Gruntfile.js
index bbd8103..a68c20c 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -215,10 +215,10 @@ module.exports = function (grunt) {
       default: {
         files: {
           src: initHelper.getFileList(['[Ss]pec.js'], [
-            // './app/core/**/*[Ss]pec.js',
-             './app/addons/replication/**/*[Ss]pec.js',
-            // './app/addons/**/*[Ss]pec.react.jsx',
-            //'./app/addons/**/*[Ss]pec.jsx'
+            './app/core/**/*[Ss]pec.js',
+            './app/addons/**/*[Ss]pec.js',
+            './app/addons/**/*[Ss]pec.react.jsx',
+            './app/addons/**/*[Ss]pec.jsx'
           ])
         },
         template: 'test/test.config.underscore'

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/597fd8c2/app/addons/replication/actions.js
----------------------------------------------------------------------
diff --git a/app/addons/replication/actions.js 
b/app/addons/replication/actions.js
index c886750..e5b5f8c 100644
--- a/app/addons/replication/actions.js
+++ b/app/addons/replication/actions.js
@@ -53,6 +53,10 @@ function replicate (params) {
   const source = Helpers.getDatabaseLabel(replicationDoc.source);
   const target = Helpers.getDatabaseLabel(replicationDoc.target);
 
+  FauxtonAPI.dispatch({
+    type: ActionTypes.REPLICATION_STARTING,
+  });
+
   promise.then(() => {
     FauxtonAPI.addNotification({
       msg: 'Replication from <code>' + source + '</code> to <code>' + target + 
'</code> has begun.',

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/597fd8c2/app/addons/replication/actiontypes.js
----------------------------------------------------------------------
diff --git a/app/addons/replication/actiontypes.js 
b/app/addons/replication/actiontypes.js
index 87e689e..880c47d 100644
--- a/app/addons/replication/actiontypes.js
+++ b/app/addons/replication/actiontypes.js
@@ -16,6 +16,7 @@ define([], function () {
     CHANGE_REPLICATION_SOURCE: 'CHANGE_REPLICATION_SOURCE',
     REPLICATION_DATABASES_LOADED: 'REPLICATION_DATABASES_LOADED',
     REPLICATION_UPDATE_FORM_FIELD: 'REPLICATION_UPDATE_FORM_FIELD',
-    REPLICATION_CLEAR_FORM: 'REPLICATION_CLEAR_FORM'
+    REPLICATION_CLEAR_FORM: 'REPLICATION_CLEAR_FORM',
+    REPLICATION_STARTING: 'REPLICATION_STARTING'
   };
 });

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/597fd8c2/app/addons/replication/assets/less/replication.less
----------------------------------------------------------------------
diff --git a/app/addons/replication/assets/less/replication.less 
b/app/addons/replication/assets/less/replication.less
index 92f728e..cbaa7f9 100644
--- a/app/addons/replication/assets/less/replication.less
+++ b/app/addons/replication/assets/less/replication.less
@@ -78,7 +78,7 @@ div.replication-page {
   }
 }
 
-.replication-remote-connection-url {
+.replication-remote-connection-url[type="text"] {
   font-size: 14px;
   width: 100%;
 }
@@ -89,7 +89,7 @@ div.replication-page {
   margin-bottom: 8px;
 }
 
-.replication-new-input {
+.replication-new-input[type="text"] {
   width: 248px;
   font-size: 14px;
 }

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/597fd8c2/app/addons/replication/controller.js
----------------------------------------------------------------------
diff --git a/app/addons/replication/controller.js 
b/app/addons/replication/controller.js
index 19d7e6b..90919b4 100644
--- a/app/addons/replication/controller.js
+++ b/app/addons/replication/controller.js
@@ -60,7 +60,8 @@ export default class ReplicationController extends 
React.Component {
       // other
       passwordModalVisible: store.isPasswordModalVisible(),
       replicationType: store.getReplicationType(),
-      replicationDocName: store.getReplicationDocName()
+      replicationDocName: store.getReplicationDocName(),
+      submittedNoChange: store.getSubmittedNoChange()
     };
   }
 
@@ -131,7 +132,13 @@ export default class ReplicationController extends 
React.Component {
   }
 
   validate () {
-    const { replicationTarget, targetDatabase, databases } = this.state;
+    const {
+      replicationTarget,
+      replicationSource,
+      targetDatabase,
+      sourceDatabase,
+      databases,
+    } = this.state;
 
     if (replicationTarget === Constants.REPLICATION_TARGET.NEW_LOCAL_DATABASE 
&& _.contains(databases, targetDatabase)) {
       FauxtonAPI.addNotification({
@@ -162,6 +169,17 @@ export default class ReplicationController extends 
React.Component {
       }
     }
 
+    if (replicationTarget === replicationSource || sourceDatabase === 
targetDatabase) {
+        FauxtonAPI.addNotification({
+          msg: 'Cannot replicate a database to itself',
+          type: 'error',
+          escape: false,
+          clear: true
+        });
+
+        return false;
+    }
+
     return true;
   }
 
@@ -172,9 +190,14 @@ export default class ReplicationController extends 
React.Component {
       replicationSource,
       replicationTarget,
       localTargetDatabaseKnown,
-      targetDatabase
+      targetDatabase,
+      submittedNoChange,
     } = this.state;
 
+    if (submittedNoChange) {
+      return false;
+    }
+
     if (!replicationSource || !replicationTarget) {
       return false;
     }

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/597fd8c2/app/addons/replication/stores.js
----------------------------------------------------------------------
diff --git a/app/addons/replication/stores.js b/app/addons/replication/stores.js
index 2da7c61..6500ec8 100644
--- a/app/addons/replication/stores.js
+++ b/app/addons/replication/stores.js
@@ -41,6 +41,15 @@ const ReplicationStore = FauxtonAPI.Store.extend({
     this._isPasswordModalVisible = false;
     this._replicationType = Constants.REPLICATION_TYPE.ONE_TIME;
     this._replicationDocName = '';
+    this._submittedNoChange = false;
+  },
+
+  getSubmittedNoChange () {
+    return this._submittedNoChange;
+  },
+
+  changeAfterSubmit () {
+    this._submittedNoChange = false;
   },
 
   isLoading: function () {
@@ -148,6 +157,7 @@ const ReplicationStore = FauxtonAPI.Store.extend({
       break;
 
       case ActionTypes.REPLICATION_UPDATE_FORM_FIELD:
+        this.changeAfterSubmit();
         this.updateFormField(action.options.fieldName, action.options.value);
       break;
 
@@ -155,6 +165,10 @@ const ReplicationStore = FauxtonAPI.Store.extend({
         this.reset();
       break;
 
+      case ActionTypes.REPLICATION_STARTING:
+        this._submittedNoChange = true;
+      break;
+
       case AccountActionTypes.AUTH_SHOW_PASSWORD_MODAL:
         this._isPasswordModalVisible = true;
       break;

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/597fd8c2/app/addons/replication/tests/controllerSpec.js
----------------------------------------------------------------------
diff --git a/app/addons/replication/tests/controllerSpec.js 
b/app/addons/replication/tests/controllerSpec.js
index 4489e00..2de99e4 100644
--- a/app/addons/replication/tests/controllerSpec.js
+++ b/app/addons/replication/tests/controllerSpec.js
@@ -36,7 +36,6 @@ describe('Replication Controller', () => {
         targetDatabase: 'new-database',
       });
 
-      console.log(controller.instance());
       assert.ok(controller.instance().validate());
     });
 

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/597fd8c2/app/addons/replication/tests/replicationSpec.js
----------------------------------------------------------------------
diff --git a/app/addons/replication/tests/replicationSpec.js 
b/app/addons/replication/tests/replicationSpec.js
deleted file mode 100644
index 9788aa0..0000000
--- a/app/addons/replication/tests/replicationSpec.js
+++ /dev/null
@@ -1,213 +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 React from 'react';
-import ReactDOM from 'react-dom';
-import FauxtonAPI from '../../../core/api';
-import TestUtils from 'react-addons-test-utils';
-import utils from '../../../../test/mocha/testUtils';
-import Components from '../components.react';
-import Constants from '../constants';
-import Actions from '../actions';
-import ActionTypes from '../actiontypes';
-import Stores from '../stores';
-
-const assert = utils.assert;
-const store = Stores.replicationStore;
-
-
-const updateField = function (fieldName, value) {
-  FauxtonAPI.dispatch({
-    type: ActionTypes.REPLICATION_UPDATE_FORM_FIELD,
-    options: {
-      fieldName: fieldName,
-      value: value
-    }
-  });
-};
-
-
-describe('Replication', () => {
-
-  describe('ReplicationTargetRow', () => {
-    let el, container;
-
-    beforeEach(() => {
-      container = document.createElement('div');
-    });
-
-    afterEach(() => {
-      ReactDOM.unmountComponentAtNode(container);
-      store.reset();
-    });
-
-    it('new remote replication target shows a URL field', () => {
-      el = TestUtils.renderIntoDocument(
-        <Components.ReplicationTargetRow
-          remoteTarget="remotetarget"
-          replicationTarget={Constants.REPLICATION_TARGET.NEW_REMOTE_DATABASE}
-          databases={['one', 'two']}
-          targetDatabase=""
-        />,
-        container
-      );
-      
assert.equal($(ReactDOM.findDOMNode(el)).find('input.connection-url').length, 
1);
-    });
-
-    it('existing remote replication target also shows a URL field', () => {
-      el = TestUtils.renderIntoDocument(
-        <Components.ReplicationTargetRow
-          remoteTarget="remotetarget"
-          
replicationTarget={Constants.REPLICATION_TARGET.EXISTING_REMOTE_DATABASE}
-          databases={['one', 'two']}
-          targetDatabase=""
-        />,
-        container
-      );
-      
assert.equal($(ReactDOM.findDOMNode(el)).find('input.connection-url').length, 
1);
-    });
-
-    it('new local database fields have simple textfield', () => {
-      el = TestUtils.renderIntoDocument(
-        <Components.ReplicationTargetRow
-          remoteTarget="remotetarget"
-          replicationTarget={Constants.REPLICATION_TARGET.NEW_LOCAL_DATABASE}
-          databases={['one', 'two']}
-          targetDatabase=""
-        />,
-        container
-      );
-      
assert.equal($(ReactDOM.findDOMNode(el)).find('input.connection-url').length, 
0);
-      
assert.equal($(ReactDOM.findDOMNode(el)).find('input.new-local-db').length, 1);
-    });
-
-    it('existing local databases fields have typeahead field', () => {
-      el = TestUtils.renderIntoDocument(
-        <Components.ReplicationTargetRow
-          remoteTarget="remotetarget"
-          
replicationTarget={Constants.REPLICATION_TARGET.EXISTING_LOCAL_DATABASE}
-          databases={['one', 'two']}
-          targetDatabase=""
-        />,
-        container
-      );
-      
assert.equal($(ReactDOM.findDOMNode(el)).find('input.connection-url').length, 
0);
-      
assert.equal($(ReactDOM.findDOMNode(el)).find('input.new-local-db').length, 0);
-
-      // (the typeahead field has a search icon)
-      assert.equal($(ReactDOM.findDOMNode(el)).find('.Select--single').length, 
1);
-    });
-
-  });
-
-
-  describe('ReplicationController', () => {
-
-    describe('Replicate button', () => {
-      let el, container;
-
-      beforeEach(() => {
-        container = document.createElement('div');
-      });
-
-      afterEach(() => {
-        ReactDOM.unmountComponentAtNode(container);
-        store.reset();
-      });
-
-      it('shows loading spinner until databases loaded', () => {
-        el = TestUtils.renderIntoDocument(<Components.ReplicationController/>, 
container);
-        Actions.initReplicator('sourcedb');
-        assert.ok($(ReactDOM.findDOMNode(el)).hasClass('loading-lines'));
-
-        FauxtonAPI.dispatch({
-          type: ActionTypes.REPLICATION_DATABASES_LOADED,
-          options: { databases: ['one', 'two', 'three'] }
-        });
-        assert.notOk($(ReactDOM.findDOMNode(el)).hasClass('loading-lines'));
-      });
-
-      it('disabled by default', () => {
-        el = TestUtils.renderIntoDocument(<Components.ReplicationController/>, 
container);
-        Actions.initReplicator('sourcedb');
-        FauxtonAPI.dispatch({
-          type: ActionTypes.REPLICATION_DATABASES_LOADED,
-          options: { databases: ['one', 'two', 'three'] }
-        });
-        
assert.ok($(ReactDOM.findDOMNode(el)).find('#replicate').is(':disabled'));
-      });
-
-      it('enabled when all fields entered', () => {
-        el = TestUtils.renderIntoDocument(<Components.ReplicationController/>, 
container);
-        Actions.initReplicator('sourcedb');
-        FauxtonAPI.dispatch({
-          type: ActionTypes.REPLICATION_DATABASES_LOADED,
-          options: { databases: ['one', 'two', 'three'] }
-        });
-
-        updateField('replicationSource', Constants.REPLICATION_SOURCE.LOCAL);
-        updateField('sourceDatabase', 'one');
-        updateField('replicationTarget', 
Constants.REPLICATION_TARGET.EXISTING_LOCAL_DATABASE);
-        updateField('targetDatabase', 'two');
-
-        
assert.notOk($(ReactDOM.findDOMNode(el)).find('#replicate').is(':disabled'));
-      });
-
-      it('disabled when missing replication source', () => {
-        el = TestUtils.renderIntoDocument(<Components.ReplicationController/>, 
container);
-        Actions.initReplicator('sourcedb');
-        FauxtonAPI.dispatch({
-          type: ActionTypes.REPLICATION_DATABASES_LOADED,
-          options: { databases: ['one', 'two', 'three'] }
-        });
-
-        updateField('replicationTarget', 
Constants.REPLICATION_TARGET.EXISTING_LOCAL_DATABASE);
-        updateField('targetDatabase', 'two');
-
-        
assert.ok($(ReactDOM.findDOMNode(el)).find('#replicate').is(':disabled'));
-      });
-
-      it('disabled when source is local, but not in known list of dbs', () => {
-        el = TestUtils.renderIntoDocument(<Components.ReplicationController/>, 
container);
-        Actions.initReplicator('sourcedb');
-        FauxtonAPI.dispatch({
-          type: ActionTypes.REPLICATION_DATABASES_LOADED,
-          options: { databases: ['one', 'two', 'three'] }
-        });
-
-        updateField('replicationSource', Constants.REPLICATION_SOURCE.LOCAL);
-        updateField('sourceDatabase', 'unknown-source-db');
-        updateField('replicationTarget', 
Constants.REPLICATION_TARGET.EXISTING_LOCAL_DATABASE);
-        updateField('targetDatabase', 'two');
-
-        
assert.ok($(ReactDOM.findDOMNode(el)).find('#replicate').is(':disabled'));
-      });
-
-      it('disabled when target is local, but not in known list of dbs', () => {
-        el = TestUtils.renderIntoDocument(<Components.ReplicationController/>, 
container);
-        Actions.initReplicator('sourcedb');
-        FauxtonAPI.dispatch({
-          type: ActionTypes.REPLICATION_DATABASES_LOADED,
-          options: { databases: ['one', 'two', 'three'] }
-        });
-
-        updateField('replicationSource', Constants.REPLICATION_SOURCE.LOCAL);
-        updateField('sourceDatabase', 'one');
-        updateField('replicationTarget', 
Constants.REPLICATION_TARGET.EXISTING_LOCAL_DATABASE);
-        updateField('targetDatabase', 'unknown-target-db');
-
-        
assert.ok($(ReactDOM.findDOMNode(el)).find('#replicate').is(':disabled'));
-      });
-    });
-  });
-
-});
-*/

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/597fd8c2/package.json
----------------------------------------------------------------------
diff --git a/package.json b/package.json
index 1eece6e..f8db411 100644
--- a/package.json
+++ b/package.json
@@ -24,7 +24,8 @@
     "nightwatch": "~0.9.0",
     "phantomjs-prebuilt": "^2.1.7",
     "react-addons-test-utils": "~15.0.1",
-    "sinon": "git+https://github.com/sinonjs/sinon.git";
+    "sinon": "git+https://github.com/sinonjs/sinon.git";,
+    "url-polyfill": "github/url-polyfill"
   },
   "dependencies": {
     "async": "~0.2.6",

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/597fd8c2/test/dev.js
----------------------------------------------------------------------
diff --git a/test/dev.js b/test/dev.js
index 874a35e..5fa7e15 100644
--- a/test/dev.js
+++ b/test/dev.js
@@ -13,7 +13,7 @@
 
 // This will search for files ending in .test.js and require them
 // so that they are added to the webpack bundle
-var context = require.context('../app/', true, /[Ss]pec/);
+var context = require.context('../app/addons/replication', true, /[Ss]pec/);
 console.log('Testing files', context.keys());
 context.keys().forEach(context);
 module.exports = context;

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/597fd8c2/test/test.config.underscore
----------------------------------------------------------------------
diff --git a/test/test.config.underscore b/test/test.config.underscore
index d1b4804..32a16a7 100644
--- a/test/test.config.underscore
+++ b/test/test.config.underscore
@@ -14,6 +14,7 @@
 //
 
 require([
+  "url-polyfill",
   <% _.each(testFiles, function (test) {%>
   '.././<%= test %>',
  <% }) %>

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/597fd8c2/webpack.config.test.js
----------------------------------------------------------------------
diff --git a/webpack.config.test.js b/webpack.config.test.js
index eae1b2b..5a96b8c 100644
--- a/webpack.config.test.js
+++ b/webpack.config.test.js
@@ -31,16 +31,23 @@ module.exports = {
       //loader: 'react-hot!babel'
       loader: 'babel'
     },
-    { test: require.resolve("jquery"),
+    {
+      test: require.resolve("jquery"),
       loader: "expose?$!expose?jQuery"
-     },
-    { test: require.resolve("sinon"),
+    },
+    {
+      test: require.resolve("sinon"),
       loader: "expose?sinon"
-     },
-    { test: require.resolve("backbone"),
+    },
+    {
+      test: require.resolve("backbone"),
       loader: "expose?Backbone"
     },
     {
+      test: require.resolve("url-polyfill"),
+      loader: "imports?this=>window"
+    },
+    {
       test: require.resolve("react"),
       loader: "imports?shim=es5-shim/es5-shim&sham=es5-shim/es5-sham"
     },

Reply via email to