Breadcrumbs React port: fix & delete broken tests - fixes race conditions in tests where the global singleton `FauxtonAPI` was monkey patched later in other modules, but `fauxton/base.js` wasn't loaded - deletes tests that messed with references / monkey patching and did not add much value - fixes a few restore calls
PR: #732 PR-URL: https://github.com/apache/couchdb-fauxton/pull/732 Reviewed-By: garren smith <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/commit/db95bb3c Tree: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/tree/db95bb3c Diff: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/diff/db95bb3c Branch: refs/heads/master Commit: db95bb3c7a9bbbeacfa1097bd2888800cd48a2ba Parents: 42259fd Author: Robert Kowalski <[email protected]> Authored: Thu Jun 23 16:55:14 2016 +0200 Committer: Robert Kowalski <[email protected]> Committed: Mon Jul 4 15:25:28 2016 +0200 ---------------------------------------------------------------------- app/addons/cors/tests/actionsSpecs.js | 11 +- app/addons/databases/tests/actionsSpec.js | 249 ------------------- .../documents/doc-editor/components.react.jsx | 5 +- app/addons/documents/resources.js | 20 +- app/addons/fauxton/base.js | 26 -- app/core/base.js | 25 +- 6 files changed, 54 insertions(+), 282 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/db95bb3c/app/addons/cors/tests/actionsSpecs.js ---------------------------------------------------------------------- diff --git a/app/addons/cors/tests/actionsSpecs.js b/app/addons/cors/tests/actionsSpecs.js index 9b4fb7a..6778982 100644 --- a/app/addons/cors/tests/actionsSpecs.js +++ b/app/addons/cors/tests/actionsSpecs.js @@ -14,14 +14,19 @@ import testUtils from "testUtils"; import FauxtonAPI from "../../../core/api"; import Actions from "../actions"; import sinon from "sinon"; -var assert = testUtils.assert; + +const assert = testUtils.assert; +const restore = testUtils.restore; describe('CORS actions', function () { describe('save', function () { afterEach(function () { - Actions.saveCorsOrigins.restore && Actions.saveCorsOrigins.restore(); + restore(Actions.saveCorsOrigins); + + restore(FauxtonAPI.when); + restore(FauxtonAPI.addNotification); }); it('should save cors enabled to httpd', function () { @@ -103,8 +108,6 @@ describe('CORS actions', function () { }); assert.ok(spy.calledOnce); - FauxtonAPI.when.restore(); - FauxtonAPI.addNotification.restore(); }); }); http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/db95bb3c/app/addons/databases/tests/actionsSpec.js ---------------------------------------------------------------------- diff --git a/app/addons/databases/tests/actionsSpec.js b/app/addons/databases/tests/actionsSpec.js deleted file mode 100644 index 3dbe0c2..0000000 --- a/app/addons/databases/tests/actionsSpec.js +++ /dev/null @@ -1,249 +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 app from "../../../app"; -import FauxtonAPI from "../../../core/api"; -import utils from "../../../../test/mocha/testUtils"; -import Base from "../base"; -import Stores from "../stores"; -import Actions from "../actions"; -import ActionTypes from "../actiontypes"; -import Resources from "../resources"; -import "../../documents/base"; - -var assert = utils.assert; - -describe('Databases Actions', function () { - - describe('Initialization', function () { - - var oldDispatch, oldWhen, oldGetParams; - var dispatchEvents, thenCallback, alwaysCallback; - var databasesMock; - - beforeEach(function () { - oldDispatch = FauxtonAPI.dispatch; - dispatchEvents = []; - FauxtonAPI.dispatch = function (what) { - dispatchEvents.push(what); - }; - oldWhen = FauxtonAPI.when; - FauxtonAPI.when = function () { - return { - then: function (callback) { - thenCallback = callback; - callback(); - }, - always: function (callback) { - alwaysCallback = callback; - callback(); - } - }; - }; - // (replace on demand) - oldGetParams = app.getParams; - databasesMock = { - fetch: function () { - }, - paginated: function () { - return []; - } - }; - }); - - afterEach(function () { - FauxtonAPI.dispatch = oldDispatch; - FauxtonAPI.when = oldWhen; - app.getParams = oldGetParams; - }); - - it('Starts loading first', function () { - app.getParams = function () { - return {}; - }; - Actions.init(databasesMock); - assert(!!thenCallback || !!alwaysCallback); - // now we should have resolved it all - assert.equal(2, dispatchEvents.length); - assert.equal(ActionTypes.DATABASES_STARTLOADING, dispatchEvents[0].type); - assert.equal(ActionTypes.DATABASES_INIT, dispatchEvents[1].type); - assert.equal(1, dispatchEvents[1].options.page); - }); - - it('Accepts page params', function () { - app.getParams = function () { - return { - page: 33 - }; - }; - Actions.init(databasesMock); - // now we should have resolved it all - assert.equal(2, dispatchEvents.length); - assert.equal(ActionTypes.DATABASES_INIT, dispatchEvents[1].type); - assert.equal(33, dispatchEvents[1].options.page); - }); - - }); - - describe('Add database', function () { - - var oldColl, oldBackbone, oldRouter, oldNotification, oldDispatch; - var passedId, doneCallback, errorCallback, navigationTarget, notificationText, dispatchEvents; - - beforeEach(function () { - oldColl = Stores.databasesStore._collection; - oldBackbone = Stores.databasesStore._backboneCollection; - passedId = null; - Stores.databasesStore._backboneCollection = {}; - Stores.databasesStore._backboneCollection.model = function (options) { - passedId = options.id; - return { - "save": function () { - var res = { - "done": function (callback) { - doneCallback = callback; - return res; - }, - "error": function (callback) { - errorCallback = callback; - return res; - } - }; - return res; - } - }; - }; - oldRouter = app.router; - navigationTarget = null; - app.router = { - navigate: function (target) { - navigationTarget = target; - } - }; - oldNotification = FauxtonAPI.addNotification; - notificationText = []; - FauxtonAPI.addNotification = function (options) { - notificationText.push(options.msg); - }; - oldDispatch = FauxtonAPI.dispatch; - dispatchEvents = []; - FauxtonAPI.dispatch = function (what) { - dispatchEvents.push(what); - }; - }); - - afterEach(function () { - Stores.databasesStore._collection = oldColl; - Stores.databasesStore._backboneCollection = oldBackbone; - app.router = oldRouter; - FauxtonAPI.addNotification = oldNotification; - FauxtonAPI.dispatch = oldDispatch; - }); - - it("Creates database in backend", function () { - Actions.createNewDatabase("testdb"); - doneCallback(); - assert.equal("testdb", passedId); - assert.equal(1, _.map(dispatchEvents, function (item) { - if (item.type === ActionTypes.DATABASES_SET_PROMPT_VISIBLE) { - return item; - } - }).length); - assert.equal(2, notificationText.length); - assert(notificationText[0].indexOf("Creating") >= 0); - assert(notificationText[1].indexOf("success") >= 0); - assert.ok(navigationTarget.indexOf("testdb") >= 0); - }); - - it("Creates no database without name", function () { - Actions.createNewDatabase(" "); - assert(passedId === null); - assert.equal(0, _.map(dispatchEvents, function (item) { - if (item.type === ActionTypes.DATABASES_SET_PROMPT_VISIBLE) { - return item; - } - }).length); - assert.equal(1, notificationText.length); - assert(notificationText[0].indexOf("valid database name") >= 0); - }); - - it("Shows error message on create fail", function () { - Actions.createNewDatabase("testdb"); - errorCallback({"responseText": JSON.stringify({"reason": "testerror"})}); - assert.equal("testdb", passedId); - assert.equal(2, notificationText.length); - assert(notificationText[0].indexOf("Creating") >= 0); - assert(notificationText[1].indexOf("failed") >= 0); - assert(notificationText[1].indexOf("testerror") >= 0); - assert(navigationTarget === null); - }); - - }); - - describe('Jump to database', function () { - - var container, jumpEl, oldNavigate, oldAddNotification, oldGetDatabaseNames, old$; - var navigationTarget, notificationText; - - beforeEach(function () { - old$ = $; - // simulate typeahead - $ = function (selector) { - var res = old$(selector); - res.typeahead = function () {}; - return res; - }; - oldNavigate = FauxtonAPI.navigate; - navigationTarget = null; - FauxtonAPI.navigate = function (url) { - navigationTarget = url; - }; - oldAddNotification = FauxtonAPI.addNotification; - notificationText = []; - FauxtonAPI.addNotification = function (options) { - notificationText.push(options.msg); - }; - oldGetDatabaseNames = Stores.databasesStore.getDatabaseNames; - Stores.databasesStore.getDatabaseNames = function () { - return ["db1", "db2"]; - }; - }); - - afterEach(function () { - $ = old$; - FauxtonAPI.navigate = oldNavigate; - FauxtonAPI.addNotification = oldAddNotification; - Stores.databasesStore.getDatabaseNames = oldGetDatabaseNames; - }); - - it("jumps to an existing DB", function () { - Actions.jumpToDatabase("db1"); - assert(navigationTarget.indexOf("db1") >= 0); - assert.equal(0, notificationText.length); - }); - - it("does nothing on empty name", function () { - Actions.jumpToDatabase(" "); - assert(navigationTarget === null); - assert.equal(0, notificationText.length); - }); - - it("shows a message on non-existent DB", function () { - Actions.jumpToDatabase("db3"); - assert(navigationTarget === null); - assert.equal(1, notificationText.length); - assert(notificationText[0].indexOf("not exist") >= 0); - }); - - }); - -}); http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/db95bb3c/app/addons/documents/doc-editor/components.react.jsx ---------------------------------------------------------------------- diff --git a/app/addons/documents/doc-editor/components.react.jsx b/app/addons/documents/doc-editor/components.react.jsx index 7c53dd6..f338a70 100644 --- a/app/addons/documents/doc-editor/components.react.jsx +++ b/app/addons/documents/doc-editor/components.react.jsx @@ -22,6 +22,8 @@ import GeneralComponents from "../../components/react-components.react"; import { Modal } from "react-bootstrap"; import Helpers from "../../../helpers"; +import DocumentResources from '../resources'; + var store = Stores.docEditorStore; var DocEditorController = React.createClass({ @@ -394,8 +396,9 @@ const CloneDocModal = React.createClass({ }, componentDidUpdate: function () { + //XXX model-code in component if (this.state.uuid === null) { - var uuid = new FauxtonAPI.UUID(); + var uuid = new DocumentResources.UUID(); uuid.fetch().then(function () { this.setState({ uuid: uuid.next() }); }.bind(this)); http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/db95bb3c/app/addons/documents/resources.js ---------------------------------------------------------------------- diff --git a/app/addons/documents/resources.js b/app/addons/documents/resources.js index b93dd3d..270ee88 100644 --- a/app/addons/documents/resources.js +++ b/app/addons/documents/resources.js @@ -14,6 +14,24 @@ import app from "../../app"; import FauxtonAPI from "../../core/api"; import Documents from "./shared-resources"; import PagingCollection from "../../../assets/js/plugins/cloudant.pagingcollection"; + + +Documents.UUID = FauxtonAPI.Model.extend({ + initialize: function (options) { + options = _.extend({count: 1}, options); + this.count = options.count; + }, + + url: function () { + return app.host + "/_uuids?count=" + this.count; + }, + + next: function () { + return this.get("uuids").pop(); + } +}); + + Documents.QueryParams = (function () { var _eachParams = function (params, action) { // clone to avoid in-place modification @@ -304,7 +322,7 @@ Documents.MangoDocumentCollection = PagingCollection.extend({ Documents.NewDoc = Documents.Doc.extend({ fetch: function () { - var uuid = new FauxtonAPI.UUID(); + var uuid = new Documents.UUID(); var deferred = this.deferred = $.Deferred(); var that = this; http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/db95bb3c/app/addons/fauxton/base.js ---------------------------------------------------------------------- diff --git a/app/addons/fauxton/base.js b/app/addons/fauxton/base.js index 8999bda..11c412b 100644 --- a/app/addons/fauxton/base.js +++ b/app/addons/fauxton/base.js @@ -26,32 +26,6 @@ import {Breadcrumbs} from '../components/header-breadcrumbs'; import "./assets/less/fauxton.less"; var Fauxton = FauxtonAPI.addon(); -FauxtonAPI.addNotification = function (options) { - options = _.extend({ - msg: 'Notification Event Triggered!', - type: 'info', - escape: true, - clear: false - }, options); - - // log all notifications in a store - Actions.addNotification(options); -}; - -FauxtonAPI.UUID = FauxtonAPI.Model.extend({ - initialize: function (options) { - options = _.extend({count: 1}, options); - this.count = options.count; - }, - - url: function () { - return app.host + "/_uuids?count=" + this.count; - }, - - next: function () { - return this.get("uuids").pop(); - } -}); Fauxton.initialize = function () { http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/db95bb3c/app/core/base.js ---------------------------------------------------------------------- diff --git a/app/core/base.js b/app/core/base.js index 999fb2a..0ea2676 100644 --- a/app/core/base.js +++ b/app/core/base.js @@ -20,7 +20,30 @@ var FauxtonAPI = { masterLayout: {}, - addNotification: function () {}, + // I haven't wrapped these dispatch methods in a action + // because I don't want to require fauxton/actions in this method. + addHeaderLink: function (link) { + FauxtonAPI.dispatch({ + type: 'ADD_NAVBAR_LINK', + link: link + }); + }, + addNotification: function (options) { + + options = _.extend({ + msg: 'Notification Event Triggered!', + type: 'info', + escape: true, + clear: false + }, options); + + FauxtonAPI.dispatch({ + type: 'ADD_NOTIFICATION', + options: { + info: options + } + }); + }, config: function (options) { return _.extend(this, options);
