couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From benk...@apache.org
Subject fauxton commit: updated refs/heads/master to 90c07fa
Date Mon, 04 May 2015 18:23:42 GMT
Repository: couchdb-fauxton
Updated Branches:
  refs/heads/master 410d2c772 -> 90c07fae8


Convert Verify Install page to React


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

Branch: refs/heads/master
Commit: 90c07fae82d6acf2e2cdf2bbb9bf605f9421ee96
Parents: 410d2c7
Author: Ben Keen <ben.keen@gmail.com>
Authored: Mon Apr 20 16:47:38 2015 -0700
Committer: Ben Keen <ben.keen@gmail.com>
Committed: Mon May 4 11:22:33 2015 -0700

----------------------------------------------------------------------
 .../documents/tests/nightwatch/viewEdit.js      |   2 +-
 app/addons/verifyinstall/actions.js             | 109 ++++++++++++++
 app/addons/verifyinstall/actiontypes.js         |  20 +++
 app/addons/verifyinstall/components.react.jsx   | 143 +++++++++++++++++++
 app/addons/verifyinstall/constants.js           |  27 ++++
 app/addons/verifyinstall/routes.js              |   9 +-
 app/addons/verifyinstall/stores.js              |  99 +++++++++++++
 app/addons/verifyinstall/templates/main.html    |  49 -------
 app/addons/verifyinstall/tests/actionsSpec.js   |  33 +++++
 .../tests/componentsSpec.react.jsx              | 136 ++++++++++++++++++
 .../tests/verifyinstall.storesSpec.js           |  51 +++++++
 app/addons/verifyinstall/views.js               | 123 ----------------
 12 files changed, 625 insertions(+), 176 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/90c07fae/app/addons/documents/tests/nightwatch/viewEdit.js
----------------------------------------------------------------------
diff --git a/app/addons/documents/tests/nightwatch/viewEdit.js b/app/addons/documents/tests/nightwatch/viewEdit.js
index ec3365a..f23cda2 100644
--- a/app/addons/documents/tests/nightwatch/viewEdit.js
+++ b/app/addons/documents/tests/nightwatch/viewEdit.js
@@ -57,7 +57,7 @@ module.exports = {
         editor.getSession().setValue("function (doc) { emit(\'hasehase5000\', 1); }");\
       ')
       .execute('$(".save")[0].scrollIntoView();')
-      .click('button.btn-success.save')
+      .clickWhenVisible('button.btn-success.save')
 
       .waitForElementNotVisible('.global-notification', waitTime, false)
       .waitForElementNotPresent('.loading-lines', waitTime, false)

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/90c07fae/app/addons/verifyinstall/actions.js
----------------------------------------------------------------------
diff --git a/app/addons/verifyinstall/actions.js b/app/addons/verifyinstall/actions.js
new file mode 100644
index 0000000..385dd7b
--- /dev/null
+++ b/app/addons/verifyinstall/actions.js
@@ -0,0 +1,109 @@
+// 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.
+
+define([
+  'app',
+  'api',
+  'addons/verifyinstall/constants',
+  'addons/verifyinstall/resources',
+  'addons/verifyinstall/actiontypes'
+],
+function (app, FauxtonAPI, Constants, VerifyInstall, ActionTypes) {
+
+
+  // helper function to publish success/fail result of a single test having been ran
+  var testPassed = function (test) {
+    FauxtonAPI.dispatch({
+      type: ActionTypes.VERIFY_INSTALL_SINGLE_TEST_COMPLETE,
+      test: test,
+      success: true
+    });
+  };
+
+  var testFailed = function (test) {
+    return function (xhr, error) {
+      if (!xhr) { return; }
+
+      FauxtonAPI.dispatch({
+        type: ActionTypes.VERIFY_INSTALL_SINGLE_TEST_COMPLETE,
+        test: test,
+        success: false
+      });
+
+      FauxtonAPI.addNotification({
+        msg: 'Error: ' + JSON.parse(xhr.responseText).reason,
+        type: 'error'
+      });
+    };
+  };
+
+
+  return {
+    resetStore: function () {
+      FauxtonAPI.dispatch({ type: ActionTypes.VERIFY_INSTALL_RESET });
+    },
+
+    startVerification: function () {
+
+      // announce that we're starting the verification tests
+      FauxtonAPI.dispatch({ type: ActionTypes.VERIFY_INSTALL_START });
+
+      var testProcess = VerifyInstall.testProcess;
+
+      testProcess.setup()
+        .then(function () {
+          return testProcess.saveDB();
+        }, testFailed(Constants.TESTS.CREATE_DATABASE))
+        .then(function () {
+          testPassed(Constants.TESTS.CREATE_DATABASE);
+          return testProcess.saveDoc();
+        }, testFailed(Constants.TESTS.CREATE_DOCUMENT))
+        .then(function () {
+          testPassed(Constants.TESTS.CREATE_DOCUMENT);
+          return testProcess.updateDoc();
+        }, testFailed(Constants.TESTS.UPDATE_DOCUMENT))
+        .then(function () {
+          testPassed(Constants.TESTS.UPDATE_DOCUMENT);
+          return testProcess.destroyDoc();
+        }, testFailed(Constants.TESTS.DELETE_DOCUMENT))
+        .then(function () {
+          testPassed(Constants.TESTS.DELETE_DOCUMENT);
+          return testProcess.setupView();
+        }, testFailed(Constants.TESTS.CREATE_VIEW))
+        .then(function () {
+          return testProcess.testView();
+        }, testFailed(Constants.TESTS.CREATE_VIEW))
+        .then(function () {
+          testPassed(Constants.TESTS.CREATE_VIEW);
+          return testProcess.setupReplicate();
+        }, testFailed(Constants.TESTS.CREATE_VIEW))
+        .then(function () {
+          return testProcess.testReplicate();
+        }, testFailed(Constants.TESTS.REPLICATION))
+        .then(function () {
+          testPassed(Constants.TESTS.REPLICATION);
+
+          // now announce the tests have been ran
+          FauxtonAPI.dispatch({ type: ActionTypes.VERIFY_INSTALL_ALL_TESTS_COMPLETE });
+
+          FauxtonAPI.addNotification({
+            msg: 'Success! Your CouchDB installation is working. Time to Relax.',
+            type: 'success'
+          });
+
+          testProcess.removeDBs();
+        }, testFailed(Constants.TESTS.REPLICATION));
+    }
+  };
+
+
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/90c07fae/app/addons/verifyinstall/actiontypes.js
----------------------------------------------------------------------
diff --git a/app/addons/verifyinstall/actiontypes.js b/app/addons/verifyinstall/actiontypes.js
new file mode 100644
index 0000000..72cf1ec
--- /dev/null
+++ b/app/addons/verifyinstall/actiontypes.js
@@ -0,0 +1,20 @@
+// 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.
+
+define([], function () {
+  return {
+    VERIFY_INSTALL_START: 'VERIFY_INSTALL_START',
+    VERIFY_INSTALL_RESET: 'VERIFY_INSTALL_RESET',
+    VERIFY_INSTALL_SINGLE_TEST_COMPLETE: 'VERIFY_INSTALL_SINGLE_TEST_COMPLETE',
+    VERIFY_INSTALL_ALL_TESTS_COMPLETE: 'VERIFY_INSTALL_ALL_TESTS_COMPLETE'
+  };
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/90c07fae/app/addons/verifyinstall/components.react.jsx
----------------------------------------------------------------------
diff --git a/app/addons/verifyinstall/components.react.jsx b/app/addons/verifyinstall/components.react.jsx
new file mode 100644
index 0000000..06b8816
--- /dev/null
+++ b/app/addons/verifyinstall/components.react.jsx
@@ -0,0 +1,143 @@
+// 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.
+
+define([
+  'app',
+  'api',
+  'react',
+  'addons/verifyinstall/constants',
+  'addons/verifyinstall/resources',
+  'addons/verifyinstall/actions',
+  'addons/verifyinstall/stores'
+],
+function (app, FauxtonAPI, React, Constants, VerifyInstall, Actions, Stores) {
+
+  var store = Stores.verifyInstallStore;
+
+
+  var VerifyInstallController = React.createClass({
+    getInitialState: function () {
+      return this.getStoreState();
+    },
+
+    getStoreState: function () {
+      return {
+        isVerifying: store.checkIsVerifying(),
+        testResults: store.getTestResults()
+      };
+    },
+
+    startVerification: function () {
+      Actions.startVerification();
+    },
+
+    onChange: function () {
+      this.setState(this.getStoreState());
+    },
+
+    componentDidMount: function () {
+      store.on('change', this.onChange, this);
+    },
+
+    componentWillUnmount: function () {
+      store.off('change', this.onChange);
+    },
+
+    render: function () {
+      return (
+        <div>
+          <VerifyInstallButton verify={this.startVerification} isVerifying={this.state.isVerifying}
/>
+          <VerifyInstallResults testResults={this.state.testResults} />
+        </div>
+      );
+    }
+  });
+
+
+  var VerifyInstallButton = React.createClass({
+    propTypes: {
+      verify: React.PropTypes.func.isRequired,
+      isVerifying: React.PropTypes.bool.isRequired
+    },
+
+    render: function () {
+      return (
+        <button id="start" className="btn btn-large btn-success" onClick={this.props.verify}
disabled={this.props.isVerifying}>
+          {this.props.isVerifying ? 'Verifying' : 'Verify Installation'}
+        </button>
+      );
+    }
+  });
+
+
+  var VerifyInstallResults = React.createClass({
+    propTypes: {
+      testResults: React.PropTypes.object.isRequired
+    },
+
+    showTestResult: function (test) {
+      if (!this.props.testResults[test].complete) {
+        return '';
+      }
+      if (this.props.testResults[test].success) {
+        return <span>&#10003;</span>;
+      }
+      return <span>&#x2717;</span>;
+    },
+
+    render: function () {
+      return (
+        <table className="table table-striped table-bordered">
+          <thead>
+            <tr>
+              <th>Test</th>
+              <th>Status</th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr>
+              <td>Create Database</td>
+              <td id="js-test-create-db">{this.showTestResult(Constants.TESTS.CREATE_DATABASE)}</td>
+            </tr>
+            <tr>
+              <td>Create Document</td>
+              <td id="js-test-create-doc">{this.showTestResult(Constants.TESTS.CREATE_DOCUMENT)}</td>
+            </tr>
+            <tr>
+              <td>Update Document</td>
+              <td id="js-test-update-doc">{this.showTestResult(Constants.TESTS.UPDATE_DOCUMENT)}</td>
+            </tr>
+            <tr>
+              <td>Delete Document</td>
+              <td id="js-test-delete-doc">{this.showTestResult(Constants.TESTS.DELETE_DOCUMENT)}</td>
+            </tr>
+            <tr>
+              <td>Create View</td>
+              <td id="js-test-create-view">{this.showTestResult(Constants.TESTS.CREATE_VIEW)}</td>
+            </tr>
+            <tr>
+              <td>Replication</td>
+              <td id="js-test-replication">{this.showTestResult(Constants.TESTS.REPLICATION)}</td>
+            </tr>
+          </tbody>
+        </table>
+      );
+    }
+  });
+
+  return {
+    VerifyInstallController: VerifyInstallController,
+    VerifyInstallButton: VerifyInstallButton,
+    VerifyInstallResults: VerifyInstallResults
+  };
+
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/90c07fae/app/addons/verifyinstall/constants.js
----------------------------------------------------------------------
diff --git a/app/addons/verifyinstall/constants.js b/app/addons/verifyinstall/constants.js
new file mode 100644
index 0000000..56de9c9
--- /dev/null
+++ b/app/addons/verifyinstall/constants.js
@@ -0,0 +1,27 @@
+// 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.
+
+define([], function () {
+
+  var CONSTANTS = {
+    TESTS: {
+      CREATE_DATABASE: 'TEST_CREATE_DATABASE',
+      CREATE_DOCUMENT: 'TEST_CREATE_DOCUMENT',
+      UPDATE_DOCUMENT: 'TEST_UPDATE_DOCUMENT',
+      DELETE_DOCUMENT: 'TEST_DELETE_DOCUMENT',
+      CREATE_VIEW: 'TEST_CREATE_VIEW',
+      REPLICATION: 'TEST_REPLICATION'
+    }
+  };
+
+  return CONSTANTS;
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/90c07fae/app/addons/verifyinstall/routes.js
----------------------------------------------------------------------
diff --git a/app/addons/verifyinstall/routes.js b/app/addons/verifyinstall/routes.js
index bc7b8a1..10a523a 100644
--- a/app/addons/verifyinstall/routes.js
+++ b/app/addons/verifyinstall/routes.js
@@ -13,9 +13,11 @@
 define([
   'app',
   'api',
-  'addons/verifyinstall/views'
+  'addons/verifyinstall/resources',
+  'addons/verifyinstall/actions',
+  'addons/verifyinstall/components.react'
 ],
-function (app, FauxtonAPI, VerifyInstall) {
+function (app, FauxtonAPI, VerifyInstall, Actions, Components) {
 
   var VerifyRouteObject = FauxtonAPI.RouteObject.extend({
     layout: 'one_pane',
@@ -26,7 +28,8 @@ function (app, FauxtonAPI, VerifyInstall) {
     selectedHeader: 'Verify',
 
     verifyInstall: function () {
-      this.setView('#dashboard-content', new VerifyInstall.Main({}));
+      Actions.resetStore();
+      this.setComponent('#dashboard-content', Components.VerifyInstallController);
     },
 
     crumbs: [{name: 'Verify CouchDB Installation', link: '#'}]

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/90c07fae/app/addons/verifyinstall/stores.js
----------------------------------------------------------------------
diff --git a/app/addons/verifyinstall/stores.js b/app/addons/verifyinstall/stores.js
new file mode 100644
index 0000000..773837e
--- /dev/null
+++ b/app/addons/verifyinstall/stores.js
@@ -0,0 +1,99 @@
+// 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.
+
+define([
+  'api',
+  'addons/verifyinstall/constants',
+  'addons/verifyinstall/actiontypes'
+],
+
+function (FauxtonAPI, Constants, ActionTypes) {
+
+  var VerifyInstallStore = FauxtonAPI.Store.extend({
+    initialize: function () {
+      this.reset();
+    },
+
+    reset: function () {
+      this._isVerifying = false;
+
+      // reset all the tests
+      this._tests = {};
+      _.each(Object.keys(Constants.TESTS), function (key) {
+        this._tests[Constants.TESTS[key]] = { complete: false };
+      }, this);
+    },
+
+    startVerification: function () {
+      this._isVerifying = true;
+    },
+
+    stopVerification: function () {
+      this._isVerifying = false;
+    },
+
+    checkIsVerifying: function () {
+      return this._isVerifying;
+    },
+
+    updateTestStatus: function (test, success) {
+
+      // shouldn't ever occur since we're using constants for the test names
+      if (!_.has(this._tests, test)) {
+        throw new Error('Invalid test name passed to updateTestStatus()');
+      }
+
+      // mark this test as complete, and track whether it was a success or failure
+      this._tests[test] = { complete: true, success: success };
+    },
+
+    getTestResults: function () {
+      return this._tests;
+    },
+
+    dispatch: function (action) {
+      switch (action.type) {
+        case ActionTypes.VERIFY_INSTALL_START:
+          this.startVerification();
+          this.triggerChange();
+        break;
+
+        case ActionTypes.VERIFY_INSTALL_RESET:
+          this.reset();
+          this.triggerChange();
+        break;
+
+        case ActionTypes.VERIFY_INSTALL_SINGLE_TEST_COMPLETE:
+          this.updateTestStatus(action.test, action.success);
+          this.triggerChange();
+        break;
+
+        case ActionTypes.VERIFY_INSTALL_ALL_TESTS_COMPLETE:
+          this.stopVerification();
+          this.triggerChange();
+        break;
+
+        default:
+        return;
+      }
+    }
+  });
+
+
+  var Stores = {};
+  Stores.verifyInstallStore = new VerifyInstallStore();
+  Stores.verifyInstallStore.dispatchToken = FauxtonAPI.dispatcher.register(Stores.verifyInstallStore.dispatch);
+
+
+  return Stores;
+
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/90c07fae/app/addons/verifyinstall/templates/main.html
----------------------------------------------------------------------
diff --git a/app/addons/verifyinstall/templates/main.html b/app/addons/verifyinstall/templates/main.html
deleted file mode 100644
index 52eb14e..0000000
--- a/app/addons/verifyinstall/templates/main.html
+++ /dev/null
@@ -1,49 +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.
-*/%>
-<button id="start" class="btn btn-large btn-success">Verify Installation</button>
-
-<table id="test-score" class="table table-striped table-bordered">
-  <thead>
-    <tr>
-      <th>Test</th>
-      <th>Status</th>
-    </tr>
-  </thead>
-  <tbody>
-    <tr>
-      <td>Create Database</td>
-      <td id="create-database" class="status"></td>
-    </tr>
-    <tr>
-      <td>Create Document</td>
-      <td id="create-document" class="status"></td>
-    </tr>
-    <tr>
-      <td>Update Document</td>
-      <td id="update-document" class="status"></td>
-    </tr>
-    <tr>
-      <td>Delete Document</td>
-      <td id="delete-document" class="status"></td>
-    </tr>
-    <tr>
-      <td>Create View</td>
-      <td id="create-view" class="status"></td>
-    </tr>
-    <tr>
-      <td>Replication</td>
-      <td id="replicate" class="status"></td>
-    </tr>
-  </tbody>
-</table>

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/90c07fae/app/addons/verifyinstall/tests/actionsSpec.js
----------------------------------------------------------------------
diff --git a/app/addons/verifyinstall/tests/actionsSpec.js b/app/addons/verifyinstall/tests/actionsSpec.js
new file mode 100644
index 0000000..a8f90f2
--- /dev/null
+++ b/app/addons/verifyinstall/tests/actionsSpec.js
@@ -0,0 +1,33 @@
+// 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.
+
+define([
+  'app',
+  'api',
+  'testUtils',
+  'addons/verifyinstall/stores',
+  'addons/verifyinstall/actiontypes'
+], function (app, FauxtonAPI, testUtils, Stores, ActionTypes) {
+
+  var assert = testUtils.assert;
+
+  describe('Verify Install Actions', function () {
+
+    it('resets the store when action called', function () {
+      var spy = sinon.spy(Stores.verifyInstallStore, 'reset');
+      FauxtonAPI.dispatch({ type: ActionTypes.VERIFY_INSTALL_RESET });
+      assert.ok(spy.calledOnce);
+    });
+
+  });
+
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/90c07fae/app/addons/verifyinstall/tests/componentsSpec.react.jsx
----------------------------------------------------------------------
diff --git a/app/addons/verifyinstall/tests/componentsSpec.react.jsx b/app/addons/verifyinstall/tests/componentsSpec.react.jsx
new file mode 100644
index 0000000..e345a70
--- /dev/null
+++ b/app/addons/verifyinstall/tests/componentsSpec.react.jsx
@@ -0,0 +1,136 @@
+// 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.
+
+define([
+  'app',
+  'api',
+  'react',
+  'testUtils',
+  'addons/verifyinstall/constants',
+  'addons/verifyinstall/components.react'
+
+], function (app, FauxtonAPI, React, testUtils, Constants, Components) {
+  FauxtonAPI.router = new FauxtonAPI.Router([]);
+
+  var assert = testUtils.assert;
+  var ReactTestUtils = React.addons.TestUtils;
+
+
+  describe('VerifyInstallResults', function () {
+    var container, el;
+
+    var tests = [
+      { key: 'CREATE_DATABASE', id: 'js-test-create-db' },
+      { key: 'CREATE_DOCUMENT', id: 'js-test-create-doc' },
+      { key: 'UPDATE_DOCUMENT', id: 'js-test-update-doc' },
+      { key: 'DELETE_DOCUMENT', id: 'js-test-delete-doc' },
+      { key: 'CREATE_VIEW', id: 'js-test-create-view' },
+      { key: 'REPLICATION', id: 'js-test-replication' }
+    ];
+
+    var testResults = {};
+    tests.forEach(function (test) {
+      testResults[Constants.TESTS[test.key]] = { complete: false };
+    });
+
+    afterEach(function () {
+      React.unmountComponentAtNode(container);
+    });
+
+    it('confirm all result fields blank before tests ran', function () {
+      container = document.createElement('div');
+      el = ReactTestUtils.renderIntoDocument(<Components.VerifyInstallResults testResults={testResults}
/>, container);
+
+      tests.forEach(function (test) {
+        assert.equal($(el.getDOMNode()).find('#' + test.id).html(), '');
+      });
+    });
+
+    it('confirm each result field shows success after successful test', function () {
+      tests.forEach(function (test) {
+        var copy = _.clone(testResults);
+
+        // mark this single test as complete
+        copy[Constants.TESTS[test.key]] = {
+          complete: true,
+          success: true
+        };
+
+        el = ReactTestUtils.renderIntoDocument(<Components.VerifyInstallResults testResults={copy}
/>, container);
+
+        // now look at the DOM for that element. It should contain a tick char
+        assert.equal($(el.getDOMNode()).find('#' + test.id + ' span').html(), '✓');
+      });
+    });
+
+    it('confirm each result field shows error marker after failed test', function () {
+      tests.forEach(function (test) {
+        var copy = _.clone(testResults);
+
+        // mark this single test as complete
+        copy[Constants.TESTS[test.key]] = {
+          complete: true,
+          success: false
+        };
+
+        el = ReactTestUtils.renderIntoDocument(<Components.VerifyInstallResults testResults={copy}
/>, container);
+
+        // now look at the DOM for that element. It should contain an error char
+        assert.equal($(el.getDOMNode()).find('#' + test.id + ' span').html(), '✗');
+      });
+    });
+  });
+
+
+  describe('VerifyInstallButton', function () {
+    var container, el;
+
+    beforeEach(function () {
+      container = document.createElement('div');
+    });
+
+    afterEach(function () {
+      React.unmountComponentAtNode(container);
+    });
+
+    it('calls verify function on click', function () {
+      var stub = { func: function () { } };
+      var spy = sinon.spy(stub, 'func');
+      el = ReactTestUtils.renderIntoDocument(<Components.VerifyInstallButton verify={stub.func}
isVerifying={false} />, container);
+      ReactTestUtils.Simulate.click($(el.getDOMNode())[0]);
+      assert.ok(spy.calledOnce);
+    });
+
+    it('does not call verify function when verification already ongoing', function () {
+      var stub = { func: function () { } };
+      var spy = sinon.spy(stub, 'func');
+      el = ReactTestUtils.renderIntoDocument(<Components.VerifyInstallButton verify={stub.func}
isVerifying={true} />, container);
+      ReactTestUtils.Simulate.click($(el.getDOMNode())[0]);
+      assert.notOk(spy.calledOnce);
+    });
+
+    it('shows appropriate default label', function () {
+      var stub = { func: function () { } };
+      el = ReactTestUtils.renderIntoDocument(<Components.VerifyInstallButton verify={stub.func}
isVerifying={false} />, container);
+      assert.equal($(el.getDOMNode()).html(), 'Verify Installation');
+    });
+
+    it('shows appropriate label during verification', function () {
+      var stub = { func: function () { } };
+      el = ReactTestUtils.renderIntoDocument(<Components.VerifyInstallButton verify={stub.func}
isVerifying={true} />, container);
+      assert.equal($(el.getDOMNode()).html(), 'Verifying');
+    });
+
+  });
+
+
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/90c07fae/app/addons/verifyinstall/tests/verifyinstall.storesSpec.js
----------------------------------------------------------------------
diff --git a/app/addons/verifyinstall/tests/verifyinstall.storesSpec.js b/app/addons/verifyinstall/tests/verifyinstall.storesSpec.js
new file mode 100644
index 0000000..e3ed59f
--- /dev/null
+++ b/app/addons/verifyinstall/tests/verifyinstall.storesSpec.js
@@ -0,0 +1,51 @@
+// 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.
+
+define([
+  'app',
+  'api',
+  'testUtils',
+  'addons/verifyinstall/stores',
+  'addons/verifyinstall/actiontypes'
+], function (app, FauxtonAPI, testUtils, Stores, ActionTypes) {
+
+  var assert = testUtils.assert;
+
+  describe('VerifyInstallStore', function () {
+
+    afterEach(function () {
+      Stores.verifyInstallStore.reset();
+    });
+
+    it('check store defaults', function () {
+      assert.ok(Stores.verifyInstallStore.checkIsVerifying() === false);
+
+      // confirm all the tests are initially marked as incomplete
+      var tests = Stores.verifyInstallStore.getTestResults();
+      _.each(tests, function (test) {
+        assert.ok(test.complete === false);
+      });
+    });
+
+    it('publishing start event changes state in store', function () {
+      FauxtonAPI.dispatch({ type: ActionTypes.VERIFY_INSTALL_START });
+      assert.ok(Stores.verifyInstallStore.checkIsVerifying() === true);
+    });
+
+    it('publishing completion event changes state in store', function () {
+      FauxtonAPI.dispatch({ type: ActionTypes.VERIFY_INSTALL_ALL_TESTS_COMPLETE });
+      assert.ok(Stores.verifyInstallStore.checkIsVerifying() === false);
+    });
+
+  });
+
+});

http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/90c07fae/app/addons/verifyinstall/views.js
----------------------------------------------------------------------
diff --git a/app/addons/verifyinstall/views.js b/app/addons/verifyinstall/views.js
deleted file mode 100644
index 1c3f9cd..0000000
--- a/app/addons/verifyinstall/views.js
+++ /dev/null
@@ -1,123 +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.
-
-define([
-  'app',
-  'api',
-  'addons/verifyinstall/resources'
-],
-function (app, FauxtonAPI, VerifyInstall) {
-
-  VerifyInstall.Main = FauxtonAPI.View.extend({
-    template: 'addons/verifyinstall/templates/main',
-
-    events: {
-      'click #start': 'startTest'
-    },
-
-    initialize: function () {
-      _.bindAll(this);
-    },
-
-    setPass: function (id) {
-      this.$('#' + id).html('&#10003;');
-    },
-
-    setError: function (id, msg) {
-      this.$('#' + id).html('&#x2717;');
-      FauxtonAPI.addNotification({
-        msg: 'Error: ' + msg,
-        type: 'error'
-      });
-    },
-
-    complete: function () {
-      FauxtonAPI.addNotification({
-        msg: 'Success! Your CouchDB installation is working. Time to Relax.',
-        type: 'success'
-      });
-    },
-
-    enableButton: function () {
-      this.$('#start').removeAttr('disabled').text('Verify Installation');
-    },
-
-    disableButton: function () {
-      this.$('#start').attr('disabled', 'disabled').text('Verifying');
-    },
-
-    formatError: function (id) {
-      var enableButton = this.enableButton,
-          setError = this.setError;
-
-      return function (xhr, error, reason) {
-        enableButton();
-
-        if (!xhr) { return; }
-
-        setError(id, JSON.parse(xhr.responseText).reason);
-      };
-    },
-
-    startTest: function () {
-      this.disableButton();
-      this.$('.status').text('');
-
-      var testProcess = VerifyInstall.testProcess,
-          setPass = this.setPass,
-          complete = this.complete,
-          formatError = this.formatError;
-
-      testProcess.setup()
-      .then(function () {
-        return testProcess.saveDB();
-      }, formatError('create-database'))
-      .then(function () {
-        setPass('create-database');
-        return testProcess.saveDoc();
-      }, formatError('create-document'))
-      .then(function () {
-        setPass('create-document');
-        return testProcess.updateDoc();
-      }, formatError('update-document'))
-      .then(function () {
-        setPass('update-document');
-        return testProcess.destroyDoc();
-      }, formatError('delete-document'))
-      .then(function () {
-        setPass('delete-document');
-        return testProcess.setupView();
-      }, formatError('create-view'))
-      .then(function () {
-        return testProcess.testView();
-      }, formatError('create-view'))
-      .then(function () {
-        setPass('create-view');
-        return testProcess.setupReplicate();
-      }, formatError('create-view'))
-      .then(function () {
-        return testProcess.testReplicate();
-      }, formatError('replicate'))
-      .then(function () {
-        setPass('replicate');
-        complete();
-        testProcess.removeDBs();
-      }, formatError('replicate'));
-
-      this.enableButton();
-    }
-  });
-
-
-  return VerifyInstall;
-
-});


Mime
View raw message