tests: move tests to subcomponents some subcomponents already have this, this removes the remaining tests to their subcomponents
PR: #405 PR-URL: https://github.com/apache/couchdb-fauxton/pull/405 Reviewed-By: Benjamin Keen <[email protected]> Reviewed-By: Michelle Phung <[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/deaf53c9 Tree: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/tree/deaf53c9 Diff: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/diff/deaf53c9 Branch: refs/heads/master Commit: deaf53c9f60ea9047eb203c9d60b3a7cd6d5b1f0 Parents: 2c9723a Author: Robert Kowalski <[email protected]> Authored: Tue May 12 12:28:06 2015 +0200 Committer: Robert Kowalski <[email protected]> Committed: Wed May 13 11:14:41 2015 +0200 ---------------------------------------------------------------------- .../tests/changes.componentsSpec.react.jsx | 375 +++++++++++++++++++ .../changes/tests/changes.storesSpec.js | 107 ++++++ .../documents/header/tests/headerSpec.react.jsx | 112 ++++++ .../documents/index-editor/tests/actionsSpec.js | 348 +++++++++++++++++ .../documents/index-editor/tests/storesSpec.js | 311 +++++++++++++++ .../tests/viewIndex.componentsSpec.react.jsx | 268 +++++++++++++ app/addons/documents/tests/actionsSpec.js | 348 ----------------- .../tests/changes.componentsSpec.react.jsx | 375 ------------------- .../documents/tests/changes.storesSpec.js | 107 ------ app/addons/documents/tests/headerSpec.react.jsx | 112 ------ app/addons/documents/tests/storesSpec.js | 311 --------------- .../tests/viewIndex.componentsSpec.react.jsx | 268 ------------- .../documents/tests/views-advancedoptsSpec.js | 32 -- 13 files changed, 1521 insertions(+), 1553 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/deaf53c9/app/addons/documents/changes/tests/changes.componentsSpec.react.jsx ---------------------------------------------------------------------- diff --git a/app/addons/documents/changes/tests/changes.componentsSpec.react.jsx b/app/addons/documents/changes/tests/changes.componentsSpec.react.jsx new file mode 100644 index 0000000..ecf3f35 --- /dev/null +++ b/app/addons/documents/changes/tests/changes.componentsSpec.react.jsx @@ -0,0 +1,375 @@ +// 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/documents/changes/components.react', + 'addons/documents/changes/stores', + 'addons/documents/changes/actions', + 'testUtils' +], function (app, FauxtonAPI, React, Changes, Stores, Actions, utils) { + FauxtonAPI.router = new FauxtonAPI.Router([]); + + var assert = utils.assert; + var TestUtils = React.addons.TestUtils; + + + // suppresses unwanted console.log()'s on missing URLs + FauxtonAPI.registerUrls('document', { + server: function (database, doc) { return app.host + '/' + database + '/' + doc; }, + app: function (database, doc) { return '/database/' + database + '/' + doc; }, + apiurl: function (database, doc) { return window.location.origin + '/' + database + '/' + doc; }, + 'web-index': function (database, doc) { return '/database/' + database + '/' + doc; } + }); + + + describe('ChangesHeader', function () { + var container, tab, spy; + + describe('Testing DOM', function () { + beforeEach(function () { + spy = sinon.spy(Actions, 'toggleTabVisibility'); + container = document.createElement('div'); + tab = TestUtils.renderIntoDocument(<Changes.ChangesHeaderController />, container); + }); + + afterEach(function () { + Stores.changesStore.reset(); + React.unmountComponentAtNode(container); + }); + + // similar as previous, except it confirms that the action gets fired, not the custom toggle func + it('calls toggleTabVisibility action on selecting a tab', function () { + TestUtils.Simulate.click($(tab.getDOMNode()).find('a')[0]); + assert.ok(spy.calledOnce); + }); + }); + }); + + describe('ChangesHeaderTab', function () { + var container, tab, toggleTabVisibility; + + beforeEach(function () { + toggleTabVisibility = sinon.spy(); + container = document.createElement('div'); + tab = TestUtils.renderIntoDocument(<Changes.ChangesHeaderTab onToggle={toggleTabVisibility} />, container); + }); + + afterEach(function () { + Stores.changesStore.reset(); + React.unmountComponentAtNode(container); + }); + + it('should call toggle function on clicking tab', function () { + TestUtils.Simulate.click($(tab.getDOMNode()).find('a')[0]); + assert.ok(toggleTabVisibility.calledOnce); + }); + }); + + + describe('ChangesTabContent', function () { + var container, changesFilterEl; + + beforeEach(function () { + container = document.createElement('div'); + changesFilterEl = TestUtils.renderIntoDocument(<Changes.ChangesTabContent />, container); + }); + + afterEach(function () { + Stores.changesStore.reset(); + React.unmountComponentAtNode(container); + }); + + it('should add filter markup', function () { + var $el = $(changesFilterEl.getDOMNode()), + submitBtn = $el.find('[type="submit"]')[0], + addItemField = $el.find('.js-changes-filter-field')[0]; + + addItemField.value = 'I wandered lonely as a filter'; + TestUtils.Simulate.change(addItemField); + TestUtils.Simulate.submit(submitBtn); + + addItemField.value = 'A second filter'; + TestUtils.Simulate.change(addItemField); + TestUtils.Simulate.submit(submitBtn); + + assert.equal(2, $el.find('.js-remove-filter').length); + }); + + it('should call addFilter action on click', function () { + var $el = $(changesFilterEl.getDOMNode()), + submitBtn = $el.find('[type="submit"]')[0], + addItemField = $el.find('.js-changes-filter-field')[0]; + + var spy = sinon.spy(Actions, 'addFilter'); + + addItemField.value = 'I wandered lonely as a filter'; + TestUtils.Simulate.change(addItemField); + TestUtils.Simulate.submit(submitBtn); + + assert.ok(spy.calledOnce); + }); + + it('should remove filter markup', function () { + var $el = $(changesFilterEl.getDOMNode()), + submitBtn = $el.find('[type="submit"]')[0], + addItemField = $el.find('.js-changes-filter-field')[0]; + + addItemField.value = 'Bloop'; + TestUtils.Simulate.change(addItemField); + TestUtils.Simulate.submit(submitBtn); + + addItemField.value = 'Flibble'; + TestUtils.Simulate.change(addItemField); + TestUtils.Simulate.submit(submitBtn); + + // clicks ALL 'remove' elements + TestUtils.Simulate.click($el.find('.js-remove-filter')[0]); + TestUtils.Simulate.click($el.find('.js-remove-filter')[0]); + + assert.equal(0, $el.find('.js-remove-filter').length); + }); + + it('should call removeFilter action on click', function () { + var $el = $(changesFilterEl.getDOMNode()), + submitBtn = $el.find('[type="submit"]')[0], + addItemField = $el.find('.js-changes-filter-field')[0]; + + var spy = sinon.spy(Actions, 'removeFilter'); + + addItemField.value = 'I wandered lonely as a filter'; + TestUtils.Simulate.change(addItemField); + TestUtils.Simulate.submit(submitBtn); + TestUtils.Simulate.click($el.find('.js-remove-filter')[0]); + + assert.ok(spy.calledOnce); + }); + + it('should not add empty filters', function () { + var $el = $(changesFilterEl.getDOMNode()), + submitBtn = $el.find('[type="submit"]')[0], + addItemField = $el.find('.js-changes-filter-field')[0]; + + addItemField.value = ''; + TestUtils.Simulate.change(addItemField); + TestUtils.Simulate.submit(submitBtn); + + assert.equal(0, $el.find('.js-remove-filter').length); + }); + + it('should not add tooltips by default', function () { + assert.equal(0, $(changesFilterEl.getDOMNode()).find('.js-remove-filter').length); + }); + + it('should not add the same filter twice', function () { + var $el = $(changesFilterEl.getDOMNode()), + submitBtn = $el.find('[type="submit"]')[0], + addItemField = $el.find('.js-changes-filter-field')[0]; + + var filter = 'I am unique in the whole wide world'; + addItemField.value = filter; + TestUtils.Simulate.change(addItemField); + TestUtils.Simulate.submit(submitBtn); + + addItemField.value = filter; + TestUtils.Simulate.change(addItemField); + TestUtils.Simulate.submit(submitBtn); + + assert.equal(1, $el.find('.js-remove-filter').length); + }); + }); + + + // tests Changes Controller; includes tests in conjunction with ChangesHeaderController + describe('ChangesController', function () { + var containerEl, headerEl, $headerEl, changesEl, $changesEl; + + var results = [ + { id: 'doc_1', seq: 4, deleted: false, changes: { code: 'here' } }, + { id: 'doc_2', seq: 1, deleted: false, changes: { code: 'here' } }, + { id: 'doc_3', seq: 6, deleted: true, changes: { code: 'here' } }, + { id: 'doc_4', seq: 7, deleted: false, changes: { code: 'here' } }, + { id: 'doc_5', seq: 1, deleted: true, changes: { code: 'here' } } + ]; + var changesResponse = JSON.stringify({ + last_seq: 123, + 'results': results + }); + + beforeEach(function () { + Actions.initChanges({ databaseName: 'testDatabase' }); + headerEl = TestUtils.renderIntoDocument(<Changes.ChangesHeaderController />, containerEl); + $headerEl = $(headerEl.getDOMNode()); + changesEl = TestUtils.renderIntoDocument(<Changes.ChangesController />, containerEl); + $changesEl = $(changesEl.getDOMNode()); + Actions.updateChanges(changesResponse); + }); + + afterEach(function () { + Stores.changesStore.reset(); + React.unmountComponentAtNode(containerEl); + }); + + + it('should list the right number of changes', function () { + assert.equal(results.length, $changesEl.find('.change-box').length); + }); + + + it('"false"/"true" filter strings should apply to change deleted status', function () { + // expand the header + TestUtils.Simulate.click($headerEl.find('a')[0]); + + // add a filter + var addItemField = $headerEl.find('.js-changes-filter-field')[0]; + var submitBtn = $headerEl.find('[type="submit"]')[0]; + addItemField.value = 'true'; + TestUtils.Simulate.change(addItemField); + TestUtils.Simulate.submit(submitBtn); + + // confirm only the two deleted items shows up and the IDs maps to the deleted rows + assert.equal(2, $changesEl.find('.change-box').length); + assert.equal('doc_3', $($changesEl.find('.js-doc-id').get(0)).html()); + assert.equal('doc_5', $($changesEl.find('.js-doc-id').get(1)).html()); + }); + + + it('confirms that a filter affects the actual search results', function () { + // expand the header + TestUtils.Simulate.click($headerEl.find('a')[0]); + + // add a filter + var addItemField = $headerEl.find('.js-changes-filter-field')[0]; + var submitBtn = $headerEl.find('[type="submit"]')[0]; + addItemField.value = '6'; // should match doc_3's sequence ID + TestUtils.Simulate.change(addItemField); + TestUtils.Simulate.submit(submitBtn); + + // confirm only one item shows up and the ID maps to what we'd expect + assert.equal(1, $changesEl.find('.change-box').length); + assert.equal('doc_3', $($changesEl.find('.js-doc-id').get(0)).html()); + }); + + + // confirms that if there are multiple filters, ALL are applied to return the subset of results that match + // all filters + it('multiple filters should all be applied to results', function () { + TestUtils.Simulate.click($headerEl.find('a')[0]); + + // add the filters + var addItemField = $headerEl.find('.js-changes-filter-field')[0]; + var submitBtn = $headerEl.find('[type="submit"]')[0]; + + // *** should match doc_1, doc_2 and doc_5 + addItemField.value = '1'; + TestUtils.Simulate.change(addItemField); + TestUtils.Simulate.submit(submitBtn); + + // *** should match doc_3 and doc_5 + addItemField.value = 'true'; + TestUtils.Simulate.change(addItemField); + TestUtils.Simulate.submit(submitBtn); + + // confirm only one item shows up and that it's doc_5 + assert.equal(1, $changesEl.find('.change-box').length); + assert.equal('doc_5', $($changesEl.find('.js-doc-id').get(0)).html()); + }); + }); + + + describe('ChangesController max results', function () { + var containerEl, changesEl; + var maxChanges = 10; + + beforeEach(function () { + + var changes = []; + _.times(maxChanges + 10, function (i) { + changes.push({ id: 'doc_' + i, seq: 1, changes: { code: 'here' } }); + }); + + var response = JSON.stringify({ + last_seq: 1, + results: changes + }); + + Actions.initChanges({ databaseName: 'test' }); + + // to keep the test speedy, override the default value (1000) + Stores.changesStore.setMaxChanges(maxChanges); + + Actions.updateChanges(response); + changesEl = TestUtils.renderIntoDocument(<Changes.ChangesController />, containerEl); + }); + + afterEach(function () { + Stores.changesStore.reset(); + React.unmountComponentAtNode(containerEl); + }); + + it('should truncate the number of results with very large # of changes', function () { + // check there's no more than maxChanges results + assert.equal(maxChanges, $(changesEl.getDOMNode()).find('.change-box').length); + }); + + it('should show a message if the results are truncated', function () { + assert.equal(1, $(changesEl.getDOMNode()).find('.changes-result-limit').length); + }); + + }); + + + describe('ChangeRow', function () { + var container; + var change = { + id: '123', + seq: 5, + deleted: false, + changes: { code: 'here' } + }; + + beforeEach(function () { + container = document.createElement('div'); + }); + + afterEach(function () { + React.unmountComponentAtNode(container); + }); + + + it('clicking the toggle-json button shows the code section', function () { + var changeRow = TestUtils.renderIntoDocument(<Changes.ChangeRow change={change} databaseName="testDatabase" />, container); + + // confirm it's hidden by default + assert.equal(0, $(changeRow.getDOMNode()).find('.prettyprint').length); + + // confirm clicking it shows the element + TestUtils.Simulate.click($(changeRow.getDOMNode()).find('button.btn')[0]); + assert.equal(1, $(changeRow.getDOMNode()).find('.prettyprint').length); + }); + + it('deleted docs should not be clickable', function () { + change.deleted = true; + var changeRow = TestUtils.renderIntoDocument(<Changes.ChangeRow change={change} databaseName="testDatabase" />, container); + assert.equal(0, $(changeRow.getDOMNode()).find('a.js-doc-link').length); + }); + + it('non-deleted docs should be clickable', function () { + change.deleted = false; + var changeRow = TestUtils.renderIntoDocument(<Changes.ChangeRow change={change} databaseName="testDatabase" />, container); + assert.equal(1, $(changeRow.getDOMNode()).find('a.js-doc-link').length); + }); + }); + +}); http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/deaf53c9/app/addons/documents/changes/tests/changes.storesSpec.js ---------------------------------------------------------------------- diff --git a/app/addons/documents/changes/tests/changes.storesSpec.js b/app/addons/documents/changes/tests/changes.storesSpec.js new file mode 100644 index 0000000..fedfb13 --- /dev/null +++ b/app/addons/documents/changes/tests/changes.storesSpec.js @@ -0,0 +1,107 @@ +// 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/documents/changes/stores', + 'testUtils' +], function (app, FauxtonAPI, Stores, utils) { + FauxtonAPI.router = new FauxtonAPI.Router([]); + + var assert = utils.assert; + + + describe('ChangesStore', function () { + + afterEach(function () { + Stores.changesStore.reset(); + }); + + it('toggleTabVisibility() changes state in store', function () { + assert.ok(Stores.changesStore.isTabVisible() === false); + Stores.changesStore.toggleTabVisibility(); + assert.ok(Stores.changesStore.isTabVisible() === true); + }); + + it('reset() changes tab visibility to hidden', function () { + Stores.changesStore.toggleTabVisibility(); + Stores.changesStore.reset(); + assert.ok(Stores.changesStore.isTabVisible() === false); + }); + + it('addFilter() adds item in store', function () { + var filter = 'My filter'; + Stores.changesStore.addFilter(filter); + var filters = Stores.changesStore.getFilters(); + assert.ok(filters.length === 1); + assert.ok(filters[0] === filter); + }); + + it('removeFilter() removes item from store', function () { + var filter1 = 'My filter 1'; + var filter2 = 'My filter 2'; + Stores.changesStore.addFilter(filter1); + Stores.changesStore.addFilter(filter2); + Stores.changesStore.removeFilter(filter1); + + var filters = Stores.changesStore.getFilters(); + assert.ok(filters.length === 1); + assert.ok(filters[0] === filter2); + }); + + it('hasFilter() finds item in store', function () { + var filter = 'My filter'; + Stores.changesStore.addFilter(filter); + assert.ok(Stores.changesStore.hasFilter(filter) === true); + }); + + it('getDatabaseName() returns database name', function () { + var dbName = 'hoopoes'; + Stores.changesStore.initChanges({ databaseName: dbName }); + assert.equal(Stores.changesStore.getDatabaseName(), dbName); + + Stores.changesStore.reset(); + assert.equal(Stores.changesStore.getDatabaseName(), ''); + }); + + it("getChanges() should return a subset if there are a lot of changes", function () { + + // to keep the test speedy, we override the default max value + var maxChanges = 10; + var changes = []; + _.times(maxChanges + 10, function (i) { + changes.push({ id: 'doc_' + i, seq: 1, changes: {}}); + }); + Stores.changesStore.initChanges({ databaseName: "test" }); + Stores.changesStore.setMaxChanges(maxChanges); + + var seqNum = 123; + Stores.changesStore.updateChanges(seqNum, changes); + + var results = Stores.changesStore.getChanges(); + assert.equal(maxChanges, results.length); + }); + + it("tracks last sequence number", function () { + assert.equal(null, Stores.changesStore.getLastSeqNum()); + + var seqNum = 123; + Stores.changesStore.updateChanges(seqNum, []); + + // confirm it's been stored + assert.equal(seqNum, Stores.changesStore.getLastSeqNum()); + }); + + }); + +}); http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/deaf53c9/app/addons/documents/header/tests/headerSpec.react.jsx ---------------------------------------------------------------------- diff --git a/app/addons/documents/header/tests/headerSpec.react.jsx b/app/addons/documents/header/tests/headerSpec.react.jsx new file mode 100644 index 0000000..420aebe --- /dev/null +++ b/app/addons/documents/header/tests/headerSpec.react.jsx @@ -0,0 +1,112 @@ +// 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/documents/header/header.react', + 'addons/documents/header/header.stores', + 'addons/documents/header/header.actions', + + 'addons/databases/base', + 'addons/documents/resources', + 'addons/documents/index-results/actions', + 'addons/documents/index-results/stores', + + 'testUtils', + 'react' +], function (FauxtonAPI, Views, Stores, Actions, Databases, Resources, + IndexResultsActions, IndexResultsStore, utils, React) { + + var assert = utils.assert; + var restore = utils.restore; + var TestUtils = React.addons.TestUtils; + + describe('Header Controller', function () { + var container, toggleEl; + beforeEach(function () { + container = document.createElement('div'); + }); + + afterEach(function () { + React.unmountComponentAtNode(container); + }); + + it('should not include invalid calssname', function () { + toggleEl = TestUtils.renderIntoDocument(<Views.HeaderBarController />, container); + var $el = $(toggleEl.getDOMNode()).find('.control-toggle-alternative-header'); + assert.equal($(toggleEl.getDOMNode()).find('.undefined').length, 0); + }); + + it('should use the passed classname', function () { + toggleEl = TestUtils.renderIntoDocument(<Views.HeaderBarController />, container); + var $el = $(toggleEl.getDOMNode()).find('.control-toggle-alternative-header'); + TestUtils.Simulate.click($el[0]); + assert.ok($el.hasClass('js-headerbar-togglebutton-selected')); + }); + + it('should not render the alternative header if the button is not clicked', function () { + Actions.resetHeaderController(); + toggleEl = TestUtils.renderIntoDocument(<Views.HeaderBarController />, container); + var $el = $(toggleEl.getDOMNode()).find('.control-toggle-alternative-header'); + assert.equal($(toggleEl.getDOMNode()).find('.alternative-header').length, 0); + }); + + it('should render the alternative header', function () { + toggleEl = TestUtils.renderIntoDocument(<Views.HeaderBarController />, container); + var $el = $(toggleEl.getDOMNode()).find('.control-toggle-alternative-header'); + TestUtils.Simulate.click($el[0]); + assert.equal($(toggleEl.getDOMNode()).find('.alternative-header').length, 1); + }); + }); + + describe('Bulkdocument Headerbar Controller', function () { + var container, header; + beforeEach(function () { + var database = new Databases.Model({id: 'registry'}); + + database.allDocs = new Resources.AllDocs({_id: "ente"}, { + database: database, + viewMeta: {update_seq: 1}, + params: {} + }); + + //override reset so we don't loose the added doc needed for testing + database.allDocs.reset = function () {}; + + IndexResultsActions.newResultsList({ + collection: database.allDocs, + isListDeletable: false + }); + + + container = document.createElement('div'); + }); + + afterEach(function () { + React.unmountComponentAtNode(container); + restore(Actions.collapseDocuments); + }); + + it('should trigger action', function () { + var spy = sinon.spy(Actions, 'collapseDocuments'); + header = TestUtils.renderIntoDocument(<Views.BulkDocumentHeaderController />, container); + TestUtils.Simulate.click($(header.getDOMNode()).find('.control-collapse')[0]); + + assert.ok(spy.calledOnce); + }); + + it('pressing SelectAll should fill the selected items list', function () { + TestUtils.Simulate.click($(header.getDOMNode()).find('.control-select-all')[0]); + + assert.equal(IndexResultsStore.indexResultsStore.getSelectedItemsLength(), 1); + }); + }); +}); http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/deaf53c9/app/addons/documents/index-editor/tests/actionsSpec.js ---------------------------------------------------------------------- diff --git a/app/addons/documents/index-editor/tests/actionsSpec.js b/app/addons/documents/index-editor/tests/actionsSpec.js new file mode 100644 index 0000000..dec71fb --- /dev/null +++ b/app/addons/documents/index-editor/tests/actionsSpec.js @@ -0,0 +1,348 @@ +// 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/documents/index-editor/actions', + 'addons/documents/resources', + 'addons/documents/index-editor/actiontypes', + 'addons/documents/index-editor/stores', + 'testUtils', + 'addons/documents/index-results/actions', + 'addons/documents/base' +], function (FauxtonAPI, Actions, Documents, ActionTypes, Stores, testUtils, IndexResultsActions) { + var assert = testUtils.assert; + var restore = testUtils.restore; + + FauxtonAPI.router = new FauxtonAPI.Router([]); + + describe('Index Editor Actions', function () { + var database = { + safeID: function () { return 'id';} + }; + + describe('save view', function () { + var designDoc, designDocs; + beforeEach(function () { + designDoc = { + _id: '_design/test-doc', + _rev: '1-231313', + views: { + 'test-view': { + map: 'function () {};', + } + } + }; + var doc = new Documents.Doc(designDoc, {database: database}); + designDocs = new Documents.AllDocs([doc], { + params: { limit: 10 }, + database: database + }); + + designDocs = designDocs.models; + }); + + afterEach(function () { + restore(FauxtonAPI.navigate); + restore(FauxtonAPI.triggerRouteEvent); + restore(IndexResultsActions.reloadResultsList); + restore(Actions.updateDesignDoc); + }); + + it('shows a notification if no design doc id given', function () { + var spy = sinon.spy(FauxtonAPI, 'addNotification'); + + var viewInfo = { + database: database, + viewName: 'new-doc', + designDocId: undefined, + map: 'map', + reduce: '_sum', + newDesignDoc: true, + newView: true, + designDocs: designDocs + }; + + Actions.saveView(viewInfo); + assert.ok(spy.calledOnce); + FauxtonAPI.addNotification.restore(); + }); + + it('creates new design Doc for new design doc', function () { + var spy = sinon.spy(Actions.helpers, 'createNewDesignDoc'); + + var viewInfo = { + database: database, + viewName: 'new-doc', + designDocId: '_design/test-doc', + map: 'map', + reduce: '_sum', + newDesignDoc: true, + newView: true, + designDocs: designDocs + }; + + Actions.saveView(viewInfo); + assert.ok(spy.calledOnce); + }); + + it('sets the design doc with updated view', function () { + var viewInfo = { + viewName: 'test-view', + designDocId: '_design/test-doc', + map: 'map', + reduce: '_sum', + newDesignDoc: false, + newView: true, + designDocs: designDocs + }; + + Actions.saveView(viewInfo); + + var updatedDesignDoc = _.first(designDocs).dDocModel(); + assert.equal(updatedDesignDoc.get('views')['test-view'].reduce, '_sum'); + }); + + it('saves doc', function () { + var viewInfo = { + viewName: 'test-view', + designDocId: '_design/test-doc', + map: 'map', + reduce: '_sum', + newDesignDoc: false, + newView: true, + designDocs: designDocs + }; + + var updatedDesignDoc = _.first(designDocs).dDocModel(); + var spy = sinon.spy(updatedDesignDoc, 'save'); + Actions.saveView(viewInfo); + + assert.ok(spy.calledOnce); + }); + + it('updates design doc', function () { + var viewInfo = { + viewName: 'test-view', + designDocId: '_design/test-doc', + map: 'map', + reduce: '_sum', + newDesignDoc: false, + newView: false, + designDocs: designDocs, + database: { + safeID: function () { return '1';} + } + }; + + designDocs.find = function () {}; + designDocs.add = function () {}; + designDocs.dDocModel = function () {}; + + Actions.editIndex({ + database: {id: 'rockos-db'}, + newView: true, + viewName: 'test-view', + designDocs: designDocs, + designDocId: designDocs[0]._id + }); + + var promise = FauxtonAPI.Deferred(); + promise.resolve(); + + var updatedDesignDoc = _.first(designDocs).dDocModel(); + var stub = sinon.stub(updatedDesignDoc, 'save'); + stub.returns(promise); + + var spy = sinon.spy(Actions, 'updateDesignDoc'); + Actions.saveView(viewInfo); + + assert.ok(spy.calledOnce); + }); + + it('navigates to new url for new view', function () { + var spy = sinon.spy(FauxtonAPI, 'navigate'); + + var viewInfo = { + database: database, + viewName: 'test-view', + designDocId: '_design/test-doc', + map: 'map', + reduce: '_sum', + newDesignDoc: false, + newView: true, + designDocs: designDocs + }; + var designDoc = _.first(designDocs); + + designDoc.save = function () { + var promise = $.Deferred(); + promise.resolve(); + return promise; + }; + + Actions.saveView(viewInfo); + assert.ok(spy.calledOnce); + assert.ok(spy.getCall(0).args[0].match(/_view\/test-view/)); + }); + + it('triggers reload results list', function () { + var spy = sinon.spy(IndexResultsActions, 'reloadResultsList'); + + var viewInfo = { + viewName: 'test-view', + designDocId: '_design/test-doc', + map: 'map', + reduce: '_sum', + newDesignDoc: false, + newView: false, + designDocs: designDocs, + database: { + safeID: function () { + return 'foo'; + } + } + }; + var designDoc = _.first(designDocs); + + designDoc.save = function () { + var promise = $.Deferred(); + promise.resolve(); + return promise; + }; + + var stub = sinon.stub(Actions, 'updateDesignDoc'); + stub.returns(true); + + Actions.saveView(viewInfo); + assert.ok(spy.calledOnce); + }); + }); + + describe('delete view', function () { + var designDocs, database, designDoc, designDocId, viewName; + beforeEach(function () { + database = { + safeID: function () { return 'safeid';} + }; + + viewName = 'test-view'; + designDocId = '_design/test-doc'; + designDocs = new Documents.AllDocs([{ + _id: designDocId , + _rev: '1-231', + views: { + 'test-view': { + map: 'function () {};', + }, + 'test-view2': { + map: 'function () {};', + } + } + }], { + params: { limit: 10 }, + database: database + }); + designDocs = designDocs.models; + designDoc = _.first(designDocs); + + }); + + afterEach(function () { + restore(FauxtonAPI.navigate); + restore(FauxtonAPI.triggerRouteEvent); + }); + + it('removes view from design doc', function () { + + Actions.deleteView({ + viewName: viewName, + designDocId: designDocId, + database: database, + designDocs: designDocs + }); + + assert.ok(_.isUndefined(designDoc.getDdocView(viewName))); + }); + + it('saves design doc if has other views', function () { + var spy = sinon.spy(designDoc, 'save'); + + Actions.deleteView({ + viewName: viewName, + designDocId: designDocId, + database: database, + designDocs: designDocs + }); + + assert.ok(spy.calledOnce); + }); + + it('deletes design doc if has no other views', function () { + var spy = sinon.spy(designDoc, 'destroy'); + designDoc.removeDdocView('test-view2'); + + Actions.deleteView({ + viewName: viewName, + designDocId: designDocId, + database: database, + designDocs: designDocs + }); + + assert.ok(spy.calledOnce); + + }); + + it('navigates to all docs', function () { + var spy = sinon.spy(FauxtonAPI, 'navigate'); + + designDoc.save = function () { + var promise = $.Deferred(); + promise.resolve(); + return promise; + }; + + Actions.deleteView({ + viewName: viewName, + designDocId: designDocId, + database: database, + designDocs: designDocs + }); + + + assert.ok(spy.getCall(0).args[0].match(/_all_docs/)); + assert.ok(spy.calledOnce); + }); + + it('triggers design doc reload', function () { + var spy = sinon.spy(FauxtonAPI, 'triggerRouteEvent'); + + designDoc.save = function () { + var promise = $.Deferred(); + promise.resolve(); + return promise; + }; + + Actions.deleteView({ + viewName: viewName, + designDocId: designDocId, + database: database, + designDocs: designDocs + }); + + assert.ok(spy.calledOnce); + assert.equal(spy.getCall(0).args[0], 'reloadDesignDocs'); + }); + + }); + }); +}); http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/deaf53c9/app/addons/documents/index-editor/tests/storesSpec.js ---------------------------------------------------------------------- diff --git a/app/addons/documents/index-editor/tests/storesSpec.js b/app/addons/documents/index-editor/tests/storesSpec.js new file mode 100644 index 0000000..c60295c --- /dev/null +++ b/app/addons/documents/index-editor/tests/storesSpec.js @@ -0,0 +1,311 @@ +// 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/documents/index-editor/stores', + 'addons/documents/index-editor/actiontypes', + 'addons/documents/resources', + 'testUtils' +], function (FauxtonAPI, Stores, ActionTypes, Documents, testUtils) { + var assert = testUtils.assert; + var store; + var dispatchToken; + + + describe('IndexEditorStore', function () { + + beforeEach(function () { + store = new Stores.IndexEditorStore(); + dispatchToken = FauxtonAPI.dispatcher.register(store.dispatch); + }); + + afterEach(function () { + FauxtonAPI.dispatcher.unregister(dispatchToken); + }); + + describe('map editor', function () { + + describe('new view', function () { + + beforeEach(function () { + + FauxtonAPI.dispatch({ + type: ActionTypes.EDIT_NEW_INDEX, + options: { + newView: true + } + }); + }); + + it('returns default map', function () { + assert.equal(store.getMap(), 'function (doc) {\n emit(doc._id, 1);\n}'); + }); + }); + + }); + + describe('reduce editor', function () { + + describe('has custom reduce', function () { + + it('is false for no reduce', function () { + var designDoc = { + _id: '_design/test-doc', + views: { + 'test-view': { + map: 'function () {};' + } + } + }; + + var designDocs = new Documents.AllDocs([designDoc], { + params: { limit: 10 }, + database: { + safeID: function () { return 'id';} + } + }); + + FauxtonAPI.dispatch({ + type: ActionTypes.EDIT_NEW_INDEX, + options: { + newView: false, + viewName: 'test-view', + designDocs: designDocs, + designDocId: designDoc._id + } + }); + + assert.notOk(store.hasCustomReduce()); + }); + + it('is false for built in reduce', function () { + var designDoc = { + _id: '_design/test-doc', + views: { + 'test-view': { + map: 'function () {};', + reduce: '_sum' + } + } + }; + + var designDocs = new Documents.AllDocs([designDoc], { + params: { limit: 10 }, + database: { + safeID: function () { return 'id';} + } + }); + FauxtonAPI.dispatch({ + type: ActionTypes.EDIT_NEW_INDEX, + options: { + newView: false, + viewName: 'test-view', + designDocs: designDocs, + designDocId: designDoc._id + } + }); + + assert.notOk(store.hasCustomReduce()); + }); + + it('is true for custom reduce', function () { + var designDoc = { + _id: '_design/test-doc', + views: { + 'test-view': { + map: 'function () {};', + reduce: 'function (reduce) { reduce(); }' + } + } + }; + + var designDocs = new Documents.AllDocs([designDoc], { + params: { limit: 10 }, + database: { + safeID: function () { return 'id';} + } + }); + + FauxtonAPI.dispatch({ + type: ActionTypes.EDIT_NEW_INDEX, + options: { + newView: false, + viewName: 'test-view', + designDocs: designDocs, + designDocId: designDoc._id + } + }); + + assert.ok(store.hasCustomReduce()); + }); + + }); + + //show default reduce + describe('SELECT_REDUCE_CHANGE', function () { + + beforeEach(function () { + var designDoc = { + _id: '_design/test-doc', + views: { + 'test-view': { + map: 'function () {};' + } + } + }; + + var designDocs = new Documents.AllDocs([designDoc], { + params: { limit: 10 }, + database: { + safeID: function () { return 'id';} + } + }); + + FauxtonAPI.dispatch({ + type: ActionTypes.EDIT_NEW_INDEX, + options: { + newView: false, + viewName: 'test-view', + designDocs: designDocs, + designDocId: designDoc._id + } + }); + }); + + it('NONE returns null reduce', function () { + FauxtonAPI.dispatch({ + type: ActionTypes.SELECT_REDUCE_CHANGE, + reduceSelectedOption: 'NONE' + }); + assert.ok(_.isNull(store.getReduce())); + }); + + it('builtin returns bultin reduce', function () { + FauxtonAPI.dispatch({ + type: ActionTypes.SELECT_REDUCE_CHANGE, + reduceSelectedOption: '_sum' + }); + assert.equal(store.getReduce(), '_sum'); + }); + + it('custom returns custom reduce', function () { + FauxtonAPI.dispatch({ + type: ActionTypes.SELECT_REDUCE_CHANGE, + reduceSelectedOption: 'CUSTOM' + }); + assert.equal(store.getReduce(), 'function (keys, values, rereduce) {\n if (rereduce) {\n return sum(values);\n } else {\n return values.length;\n }\n}'); + }); + }); + }); + + + describe('design doc selector', function () { + var designDoc; + + beforeEach(function () { + designDoc = { + _id: '_design/test-doc', + views: { + 'test-view': { + map: 'boom' + } + } + }; + + var designDocs = new Documents.AllDocs([designDoc], { + params: { limit: 10 }, + database: { + safeID: function () { return 'id';} + } + }); + + FauxtonAPI.dispatch({ + type: ActionTypes.EDIT_INDEX, + options: { + newView: false, + viewName: 'test-view', + designDocs: designDocs, + designDocId: designDoc._id + } + }); + }); + + it('DESIGN_DOC_CHANGE changes design doc id', function () { + var designDocId = 'another-one'; + FauxtonAPI.dispatch({ + type: ActionTypes.DESIGN_DOC_CHANGE, + designDocId: designDocId, + newDesignDoc: false + }); + + assert.equal(store.getDesignDocId(), designDocId); + assert.notOk(store.isNewDesignDoc()); + }); + + it('sets new design doc on NEW_DESIGN_DOC', function () { + FauxtonAPI.dispatch({ + type: ActionTypes.NEW_DESIGN_DOC + }); + + assert.ok(store.isNewDesignDoc()); + assert.equal(store.getDesignDocId(), ''); + }); + }); + + describe('EDIT_INDEX', function () { + var designDoc, designDocs; + + beforeEach(function () { + designDoc = { + _id: '_design/test-doc', + views: { + 'test-view': { + map: 'boom' + } + } + }; + + designDocs = new Documents.AllDocs([designDoc], { + params: { limit: 10 }, + database: { + safeID: function () { return 'id';} + } + }); + + }); + + it('can set reduce for new design doc', function () { + FauxtonAPI.dispatch({ + type: ActionTypes.EDIT_INDEX, + options: { + newView: true, + newDesignDoc: true, + viewName: 'test-view', + designDocs: designDocs, + designDocId: undefined + } + }); + + FauxtonAPI.dispatch({ + type: ActionTypes.SELECT_REDUCE_CHANGE, + reduceSelectedOption: '_sum' + }); + + assert.equal(store.getReduce(), '_sum'); + }); + + }); + + }); +}); + http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/deaf53c9/app/addons/documents/index-editor/tests/viewIndex.componentsSpec.react.jsx ---------------------------------------------------------------------- diff --git a/app/addons/documents/index-editor/tests/viewIndex.componentsSpec.react.jsx b/app/addons/documents/index-editor/tests/viewIndex.componentsSpec.react.jsx new file mode 100644 index 0000000..9cac62d --- /dev/null +++ b/app/addons/documents/index-editor/tests/viewIndex.componentsSpec.react.jsx @@ -0,0 +1,268 @@ +// 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/documents/index-editor/components.react', + 'addons/documents/index-editor/stores', + 'addons/documents/index-editor/actions', + 'addons/documents/resources', + 'testUtils', + "react" +], function (FauxtonAPI, Views, Stores, Actions, Documents, utils, React) { + FauxtonAPI.router = new FauxtonAPI.Router([]); + + var assert = utils.assert; + var TestUtils = React.addons.TestUtils; + var restore = utils.restore; + + var resetStore = function (designDocs) { + designDocs = designDocs.map(function (doc) { + return Documents.Doc.prototype.parse(doc); + }); + + var ddocs = new Documents.AllDocs(designDocs, { + params: { limit: 10 }, + database: { + safeID: function () { return 'id';} + } + }); + + Actions.editIndex({ + database: {id: 'rockos-db'}, + newView: false, + viewName: 'test-view', + designDocs: ddocs, + designDocId: designDocs[0]._id + }); + }; + + describe('reduce editor', function () { + var container, reduceEl; + + beforeEach(function () { + container = document.createElement('div'); + }); + + afterEach(function () { + React.unmountComponentAtNode(container); + }); + + describe('getReduceValue', function () { + var container; + + beforeEach(function () { + container = document.createElement('div'); + $('body').append('<div id="reduce-function"></div>'); + }); + + it('returns null for none', function () { + var store = Stores.indexEditorStore; + + var designDoc = { + _id: '_design/test-doc', + views: { + 'test-view': { + map: 'function () {};', + //reduce: 'function (reduce) { reduce(); }' + } + } + }; + + resetStore([designDoc]); + + reduceEl = TestUtils.renderIntoDocument(<Views.ReduceEditor/>, container); + assert.ok(_.isNull(reduceEl.getReduceValue())); + }); + + it('returns built in for built in reduce', function () { + var store = Stores.indexEditorStore; + + var designDoc = { + _id: '_design/test-doc', + views: { + 'test-view': { + map: 'function () {};', + reduce: '_sum' + } + } + }; + + resetStore([designDoc]); + + reduceEl = TestUtils.renderIntoDocument(<Views.ReduceEditor/>, container); + assert.equal(reduceEl.getReduceValue(), '_sum'); + }); + + }); + }); + + describe('design Doc Selector', function () { + var container, selectorEl; + + beforeEach(function () { + container = document.createElement('div'); + $('body').append('<div id="map-function"></div>'); + $('body').append('<div id="editor"></div>'); + var designDoc = { + "id": "_design/test-doc", + "key": "_design/test-doc", + "value": { + "rev": "20-9e4bc8b76fd7d752d620bbe6e0ea9a80" + }, + "doc": { + "_id": "_design/test-doc", + "_rev": "20-9e4bc8b76fd7d752d620bbe6e0ea9a80", + "views": { + "test-view": { + "map": "function(doc) {\n emit(doc._id, 2);\n}" + }, + "new-view": { + "map": "function(doc) {\n if (doc.class === \"mammal\" && doc.diet === \"herbivore\")\n emit(doc._id, 1);\n}", + "reduce": "_sum" + } + }, + "language": "javascript", + "indexes": { + "newSearch": { + "analyzer": "standard", + "index": "function(doc){\n index(\"default\", doc._id);\n}" + } + } + } + }; + var mangodoc = { + "id": "_design/123mango", + "key": "_design/123mango", + "value": { + "rev": "20-9e4bc8b76fd7d752d620bbe6e0ea9a80" + }, + "doc": { + "_id": "_design/123mango", + "_rev": "20-9e4bc8b76fd7d752d620bbe6e0ea9a80", + "views": { + "test-view": { + "map": "function(doc) {\n emit(doc._id, 2);\n}" + }, + "new-view": { + "map": "function(doc) {\n if (doc.class === \"mammal\" && doc.diet === \"herbivore\")\n emit(doc._id, 1);\n}", + "reduce": "_sum" + } + }, + "language": "query", + "indexes": { + "newSearch": { + "analyzer": "standard", + "index": "function(doc){\n index(\"default\", doc._id);\n}" + } + } + } + }; + resetStore([designDoc, mangodoc]); + selectorEl = TestUtils.renderIntoDocument(<Views.DesignDocSelector/>, container); + }); + + + afterEach(function () { + restore(Actions.newDesignDoc); + restore(Actions.designDocChange); + React.unmountComponentAtNode(container); + }); + + it('calls new design doc on new selected', function () { + var spy = sinon.spy(Actions, 'newDesignDoc'); + TestUtils.Simulate.change($(selectorEl.getDOMNode()).find('#ddoc')[0], { + target: { + value: 'new' + } + }); + + assert.ok(spy.calledOnce); + }); + + it('calls design doc changed on a different design doc selected', function () { + var spy = sinon.spy(Actions, 'designDocChange'); + TestUtils.Simulate.change($(selectorEl.getDOMNode()).find('#ddoc')[0], { + target: { + value: 'another-doc' + } + }); + + assert.ok(spy.calledWith('another-doc', false)); + }); + + it('calls design doc changed on new design doc entered', function () { + var spy = sinon.spy(Actions, 'designDocChange'); + Actions.newDesignDoc(); + TestUtils.Simulate.change($(selectorEl.getDOMNode()).find('#new-ddoc')[0], { + target: { + value: 'new-doc-entered' + } + }); + + assert.ok(spy.calledWith('_design/new-doc-entered', true)); + }); + + it('does not filter usual design docs', function () { + assert.ok(/_design\/test-doc/.test($(selectorEl.getDOMNode()).text())); + }); + + it('filters mango docs', function () { + selectorEl = TestUtils.renderIntoDocument(<Views.DesignDocSelector/>, container); + assert.notOk(/_design\/123mango/.test($(selectorEl.getDOMNode()).text())); + }); + }); + + describe('Editor', function () { + var container, editorEl, reduceStub; + + beforeEach(function () { + container = document.createElement('div'); + $('body').append('<div id="map-function"></div>'); + $('body').append('<div id="editor"></div>'); + editorEl = TestUtils.renderIntoDocument(<Views.Editor/>, container); + }); + + afterEach(function () { + React.unmountComponentAtNode(container); + }); + + it('returns false on invalid map editor code', function () { + var stub = sinon.stub(editorEl.refs.mapEditor, 'hadValidCode'); + stub.returns(false); + assert.notOk(editorEl.hasValidCode()); + }); + + it('returns true on valid map editor code', function () { + var stub = sinon.stub(editorEl.refs.mapEditor, 'hadValidCode'); + stub.returns(true); + assert.ok(editorEl.hasValidCode()); + }); + + it('returns true on non-custom reduce', function () { + var stub = sinon.stub(Stores.indexEditorStore, 'hasCustomReduce'); + stub.returns(false); + assert.ok(editorEl.hasValidCode()); + }); + + it('calls changeViewName on view name change', function () { + var viewName = 'new-name'; + var spy = sinon.spy(Actions, 'changeViewName'); + var el = $(editorEl.getDOMNode()).find('#index-name')[0]; + TestUtils.Simulate.change(el, { + target: { + value: viewName + } + }); + assert.ok(spy.calledWith(viewName)); + }); + }); +}); http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/deaf53c9/app/addons/documents/tests/actionsSpec.js ---------------------------------------------------------------------- diff --git a/app/addons/documents/tests/actionsSpec.js b/app/addons/documents/tests/actionsSpec.js deleted file mode 100644 index dec71fb..0000000 --- a/app/addons/documents/tests/actionsSpec.js +++ /dev/null @@ -1,348 +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([ - 'api', - 'addons/documents/index-editor/actions', - 'addons/documents/resources', - 'addons/documents/index-editor/actiontypes', - 'addons/documents/index-editor/stores', - 'testUtils', - 'addons/documents/index-results/actions', - 'addons/documents/base' -], function (FauxtonAPI, Actions, Documents, ActionTypes, Stores, testUtils, IndexResultsActions) { - var assert = testUtils.assert; - var restore = testUtils.restore; - - FauxtonAPI.router = new FauxtonAPI.Router([]); - - describe('Index Editor Actions', function () { - var database = { - safeID: function () { return 'id';} - }; - - describe('save view', function () { - var designDoc, designDocs; - beforeEach(function () { - designDoc = { - _id: '_design/test-doc', - _rev: '1-231313', - views: { - 'test-view': { - map: 'function () {};', - } - } - }; - var doc = new Documents.Doc(designDoc, {database: database}); - designDocs = new Documents.AllDocs([doc], { - params: { limit: 10 }, - database: database - }); - - designDocs = designDocs.models; - }); - - afterEach(function () { - restore(FauxtonAPI.navigate); - restore(FauxtonAPI.triggerRouteEvent); - restore(IndexResultsActions.reloadResultsList); - restore(Actions.updateDesignDoc); - }); - - it('shows a notification if no design doc id given', function () { - var spy = sinon.spy(FauxtonAPI, 'addNotification'); - - var viewInfo = { - database: database, - viewName: 'new-doc', - designDocId: undefined, - map: 'map', - reduce: '_sum', - newDesignDoc: true, - newView: true, - designDocs: designDocs - }; - - Actions.saveView(viewInfo); - assert.ok(spy.calledOnce); - FauxtonAPI.addNotification.restore(); - }); - - it('creates new design Doc for new design doc', function () { - var spy = sinon.spy(Actions.helpers, 'createNewDesignDoc'); - - var viewInfo = { - database: database, - viewName: 'new-doc', - designDocId: '_design/test-doc', - map: 'map', - reduce: '_sum', - newDesignDoc: true, - newView: true, - designDocs: designDocs - }; - - Actions.saveView(viewInfo); - assert.ok(spy.calledOnce); - }); - - it('sets the design doc with updated view', function () { - var viewInfo = { - viewName: 'test-view', - designDocId: '_design/test-doc', - map: 'map', - reduce: '_sum', - newDesignDoc: false, - newView: true, - designDocs: designDocs - }; - - Actions.saveView(viewInfo); - - var updatedDesignDoc = _.first(designDocs).dDocModel(); - assert.equal(updatedDesignDoc.get('views')['test-view'].reduce, '_sum'); - }); - - it('saves doc', function () { - var viewInfo = { - viewName: 'test-view', - designDocId: '_design/test-doc', - map: 'map', - reduce: '_sum', - newDesignDoc: false, - newView: true, - designDocs: designDocs - }; - - var updatedDesignDoc = _.first(designDocs).dDocModel(); - var spy = sinon.spy(updatedDesignDoc, 'save'); - Actions.saveView(viewInfo); - - assert.ok(spy.calledOnce); - }); - - it('updates design doc', function () { - var viewInfo = { - viewName: 'test-view', - designDocId: '_design/test-doc', - map: 'map', - reduce: '_sum', - newDesignDoc: false, - newView: false, - designDocs: designDocs, - database: { - safeID: function () { return '1';} - } - }; - - designDocs.find = function () {}; - designDocs.add = function () {}; - designDocs.dDocModel = function () {}; - - Actions.editIndex({ - database: {id: 'rockos-db'}, - newView: true, - viewName: 'test-view', - designDocs: designDocs, - designDocId: designDocs[0]._id - }); - - var promise = FauxtonAPI.Deferred(); - promise.resolve(); - - var updatedDesignDoc = _.first(designDocs).dDocModel(); - var stub = sinon.stub(updatedDesignDoc, 'save'); - stub.returns(promise); - - var spy = sinon.spy(Actions, 'updateDesignDoc'); - Actions.saveView(viewInfo); - - assert.ok(spy.calledOnce); - }); - - it('navigates to new url for new view', function () { - var spy = sinon.spy(FauxtonAPI, 'navigate'); - - var viewInfo = { - database: database, - viewName: 'test-view', - designDocId: '_design/test-doc', - map: 'map', - reduce: '_sum', - newDesignDoc: false, - newView: true, - designDocs: designDocs - }; - var designDoc = _.first(designDocs); - - designDoc.save = function () { - var promise = $.Deferred(); - promise.resolve(); - return promise; - }; - - Actions.saveView(viewInfo); - assert.ok(spy.calledOnce); - assert.ok(spy.getCall(0).args[0].match(/_view\/test-view/)); - }); - - it('triggers reload results list', function () { - var spy = sinon.spy(IndexResultsActions, 'reloadResultsList'); - - var viewInfo = { - viewName: 'test-view', - designDocId: '_design/test-doc', - map: 'map', - reduce: '_sum', - newDesignDoc: false, - newView: false, - designDocs: designDocs, - database: { - safeID: function () { - return 'foo'; - } - } - }; - var designDoc = _.first(designDocs); - - designDoc.save = function () { - var promise = $.Deferred(); - promise.resolve(); - return promise; - }; - - var stub = sinon.stub(Actions, 'updateDesignDoc'); - stub.returns(true); - - Actions.saveView(viewInfo); - assert.ok(spy.calledOnce); - }); - }); - - describe('delete view', function () { - var designDocs, database, designDoc, designDocId, viewName; - beforeEach(function () { - database = { - safeID: function () { return 'safeid';} - }; - - viewName = 'test-view'; - designDocId = '_design/test-doc'; - designDocs = new Documents.AllDocs([{ - _id: designDocId , - _rev: '1-231', - views: { - 'test-view': { - map: 'function () {};', - }, - 'test-view2': { - map: 'function () {};', - } - } - }], { - params: { limit: 10 }, - database: database - }); - designDocs = designDocs.models; - designDoc = _.first(designDocs); - - }); - - afterEach(function () { - restore(FauxtonAPI.navigate); - restore(FauxtonAPI.triggerRouteEvent); - }); - - it('removes view from design doc', function () { - - Actions.deleteView({ - viewName: viewName, - designDocId: designDocId, - database: database, - designDocs: designDocs - }); - - assert.ok(_.isUndefined(designDoc.getDdocView(viewName))); - }); - - it('saves design doc if has other views', function () { - var spy = sinon.spy(designDoc, 'save'); - - Actions.deleteView({ - viewName: viewName, - designDocId: designDocId, - database: database, - designDocs: designDocs - }); - - assert.ok(spy.calledOnce); - }); - - it('deletes design doc if has no other views', function () { - var spy = sinon.spy(designDoc, 'destroy'); - designDoc.removeDdocView('test-view2'); - - Actions.deleteView({ - viewName: viewName, - designDocId: designDocId, - database: database, - designDocs: designDocs - }); - - assert.ok(spy.calledOnce); - - }); - - it('navigates to all docs', function () { - var spy = sinon.spy(FauxtonAPI, 'navigate'); - - designDoc.save = function () { - var promise = $.Deferred(); - promise.resolve(); - return promise; - }; - - Actions.deleteView({ - viewName: viewName, - designDocId: designDocId, - database: database, - designDocs: designDocs - }); - - - assert.ok(spy.getCall(0).args[0].match(/_all_docs/)); - assert.ok(spy.calledOnce); - }); - - it('triggers design doc reload', function () { - var spy = sinon.spy(FauxtonAPI, 'triggerRouteEvent'); - - designDoc.save = function () { - var promise = $.Deferred(); - promise.resolve(); - return promise; - }; - - Actions.deleteView({ - viewName: viewName, - designDocId: designDocId, - database: database, - designDocs: designDocs - }); - - assert.ok(spy.calledOnce); - assert.equal(spy.getCall(0).args[0], 'reloadDesignDocs'); - }); - - }); - }); -}); http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/deaf53c9/app/addons/documents/tests/changes.componentsSpec.react.jsx ---------------------------------------------------------------------- diff --git a/app/addons/documents/tests/changes.componentsSpec.react.jsx b/app/addons/documents/tests/changes.componentsSpec.react.jsx deleted file mode 100644 index ecf3f35..0000000 --- a/app/addons/documents/tests/changes.componentsSpec.react.jsx +++ /dev/null @@ -1,375 +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', - 'react', - 'addons/documents/changes/components.react', - 'addons/documents/changes/stores', - 'addons/documents/changes/actions', - 'testUtils' -], function (app, FauxtonAPI, React, Changes, Stores, Actions, utils) { - FauxtonAPI.router = new FauxtonAPI.Router([]); - - var assert = utils.assert; - var TestUtils = React.addons.TestUtils; - - - // suppresses unwanted console.log()'s on missing URLs - FauxtonAPI.registerUrls('document', { - server: function (database, doc) { return app.host + '/' + database + '/' + doc; }, - app: function (database, doc) { return '/database/' + database + '/' + doc; }, - apiurl: function (database, doc) { return window.location.origin + '/' + database + '/' + doc; }, - 'web-index': function (database, doc) { return '/database/' + database + '/' + doc; } - }); - - - describe('ChangesHeader', function () { - var container, tab, spy; - - describe('Testing DOM', function () { - beforeEach(function () { - spy = sinon.spy(Actions, 'toggleTabVisibility'); - container = document.createElement('div'); - tab = TestUtils.renderIntoDocument(<Changes.ChangesHeaderController />, container); - }); - - afterEach(function () { - Stores.changesStore.reset(); - React.unmountComponentAtNode(container); - }); - - // similar as previous, except it confirms that the action gets fired, not the custom toggle func - it('calls toggleTabVisibility action on selecting a tab', function () { - TestUtils.Simulate.click($(tab.getDOMNode()).find('a')[0]); - assert.ok(spy.calledOnce); - }); - }); - }); - - describe('ChangesHeaderTab', function () { - var container, tab, toggleTabVisibility; - - beforeEach(function () { - toggleTabVisibility = sinon.spy(); - container = document.createElement('div'); - tab = TestUtils.renderIntoDocument(<Changes.ChangesHeaderTab onToggle={toggleTabVisibility} />, container); - }); - - afterEach(function () { - Stores.changesStore.reset(); - React.unmountComponentAtNode(container); - }); - - it('should call toggle function on clicking tab', function () { - TestUtils.Simulate.click($(tab.getDOMNode()).find('a')[0]); - assert.ok(toggleTabVisibility.calledOnce); - }); - }); - - - describe('ChangesTabContent', function () { - var container, changesFilterEl; - - beforeEach(function () { - container = document.createElement('div'); - changesFilterEl = TestUtils.renderIntoDocument(<Changes.ChangesTabContent />, container); - }); - - afterEach(function () { - Stores.changesStore.reset(); - React.unmountComponentAtNode(container); - }); - - it('should add filter markup', function () { - var $el = $(changesFilterEl.getDOMNode()), - submitBtn = $el.find('[type="submit"]')[0], - addItemField = $el.find('.js-changes-filter-field')[0]; - - addItemField.value = 'I wandered lonely as a filter'; - TestUtils.Simulate.change(addItemField); - TestUtils.Simulate.submit(submitBtn); - - addItemField.value = 'A second filter'; - TestUtils.Simulate.change(addItemField); - TestUtils.Simulate.submit(submitBtn); - - assert.equal(2, $el.find('.js-remove-filter').length); - }); - - it('should call addFilter action on click', function () { - var $el = $(changesFilterEl.getDOMNode()), - submitBtn = $el.find('[type="submit"]')[0], - addItemField = $el.find('.js-changes-filter-field')[0]; - - var spy = sinon.spy(Actions, 'addFilter'); - - addItemField.value = 'I wandered lonely as a filter'; - TestUtils.Simulate.change(addItemField); - TestUtils.Simulate.submit(submitBtn); - - assert.ok(spy.calledOnce); - }); - - it('should remove filter markup', function () { - var $el = $(changesFilterEl.getDOMNode()), - submitBtn = $el.find('[type="submit"]')[0], - addItemField = $el.find('.js-changes-filter-field')[0]; - - addItemField.value = 'Bloop'; - TestUtils.Simulate.change(addItemField); - TestUtils.Simulate.submit(submitBtn); - - addItemField.value = 'Flibble'; - TestUtils.Simulate.change(addItemField); - TestUtils.Simulate.submit(submitBtn); - - // clicks ALL 'remove' elements - TestUtils.Simulate.click($el.find('.js-remove-filter')[0]); - TestUtils.Simulate.click($el.find('.js-remove-filter')[0]); - - assert.equal(0, $el.find('.js-remove-filter').length); - }); - - it('should call removeFilter action on click', function () { - var $el = $(changesFilterEl.getDOMNode()), - submitBtn = $el.find('[type="submit"]')[0], - addItemField = $el.find('.js-changes-filter-field')[0]; - - var spy = sinon.spy(Actions, 'removeFilter'); - - addItemField.value = 'I wandered lonely as a filter'; - TestUtils.Simulate.change(addItemField); - TestUtils.Simulate.submit(submitBtn); - TestUtils.Simulate.click($el.find('.js-remove-filter')[0]); - - assert.ok(spy.calledOnce); - }); - - it('should not add empty filters', function () { - var $el = $(changesFilterEl.getDOMNode()), - submitBtn = $el.find('[type="submit"]')[0], - addItemField = $el.find('.js-changes-filter-field')[0]; - - addItemField.value = ''; - TestUtils.Simulate.change(addItemField); - TestUtils.Simulate.submit(submitBtn); - - assert.equal(0, $el.find('.js-remove-filter').length); - }); - - it('should not add tooltips by default', function () { - assert.equal(0, $(changesFilterEl.getDOMNode()).find('.js-remove-filter').length); - }); - - it('should not add the same filter twice', function () { - var $el = $(changesFilterEl.getDOMNode()), - submitBtn = $el.find('[type="submit"]')[0], - addItemField = $el.find('.js-changes-filter-field')[0]; - - var filter = 'I am unique in the whole wide world'; - addItemField.value = filter; - TestUtils.Simulate.change(addItemField); - TestUtils.Simulate.submit(submitBtn); - - addItemField.value = filter; - TestUtils.Simulate.change(addItemField); - TestUtils.Simulate.submit(submitBtn); - - assert.equal(1, $el.find('.js-remove-filter').length); - }); - }); - - - // tests Changes Controller; includes tests in conjunction with ChangesHeaderController - describe('ChangesController', function () { - var containerEl, headerEl, $headerEl, changesEl, $changesEl; - - var results = [ - { id: 'doc_1', seq: 4, deleted: false, changes: { code: 'here' } }, - { id: 'doc_2', seq: 1, deleted: false, changes: { code: 'here' } }, - { id: 'doc_3', seq: 6, deleted: true, changes: { code: 'here' } }, - { id: 'doc_4', seq: 7, deleted: false, changes: { code: 'here' } }, - { id: 'doc_5', seq: 1, deleted: true, changes: { code: 'here' } } - ]; - var changesResponse = JSON.stringify({ - last_seq: 123, - 'results': results - }); - - beforeEach(function () { - Actions.initChanges({ databaseName: 'testDatabase' }); - headerEl = TestUtils.renderIntoDocument(<Changes.ChangesHeaderController />, containerEl); - $headerEl = $(headerEl.getDOMNode()); - changesEl = TestUtils.renderIntoDocument(<Changes.ChangesController />, containerEl); - $changesEl = $(changesEl.getDOMNode()); - Actions.updateChanges(changesResponse); - }); - - afterEach(function () { - Stores.changesStore.reset(); - React.unmountComponentAtNode(containerEl); - }); - - - it('should list the right number of changes', function () { - assert.equal(results.length, $changesEl.find('.change-box').length); - }); - - - it('"false"/"true" filter strings should apply to change deleted status', function () { - // expand the header - TestUtils.Simulate.click($headerEl.find('a')[0]); - - // add a filter - var addItemField = $headerEl.find('.js-changes-filter-field')[0]; - var submitBtn = $headerEl.find('[type="submit"]')[0]; - addItemField.value = 'true'; - TestUtils.Simulate.change(addItemField); - TestUtils.Simulate.submit(submitBtn); - - // confirm only the two deleted items shows up and the IDs maps to the deleted rows - assert.equal(2, $changesEl.find('.change-box').length); - assert.equal('doc_3', $($changesEl.find('.js-doc-id').get(0)).html()); - assert.equal('doc_5', $($changesEl.find('.js-doc-id').get(1)).html()); - }); - - - it('confirms that a filter affects the actual search results', function () { - // expand the header - TestUtils.Simulate.click($headerEl.find('a')[0]); - - // add a filter - var addItemField = $headerEl.find('.js-changes-filter-field')[0]; - var submitBtn = $headerEl.find('[type="submit"]')[0]; - addItemField.value = '6'; // should match doc_3's sequence ID - TestUtils.Simulate.change(addItemField); - TestUtils.Simulate.submit(submitBtn); - - // confirm only one item shows up and the ID maps to what we'd expect - assert.equal(1, $changesEl.find('.change-box').length); - assert.equal('doc_3', $($changesEl.find('.js-doc-id').get(0)).html()); - }); - - - // confirms that if there are multiple filters, ALL are applied to return the subset of results that match - // all filters - it('multiple filters should all be applied to results', function () { - TestUtils.Simulate.click($headerEl.find('a')[0]); - - // add the filters - var addItemField = $headerEl.find('.js-changes-filter-field')[0]; - var submitBtn = $headerEl.find('[type="submit"]')[0]; - - // *** should match doc_1, doc_2 and doc_5 - addItemField.value = '1'; - TestUtils.Simulate.change(addItemField); - TestUtils.Simulate.submit(submitBtn); - - // *** should match doc_3 and doc_5 - addItemField.value = 'true'; - TestUtils.Simulate.change(addItemField); - TestUtils.Simulate.submit(submitBtn); - - // confirm only one item shows up and that it's doc_5 - assert.equal(1, $changesEl.find('.change-box').length); - assert.equal('doc_5', $($changesEl.find('.js-doc-id').get(0)).html()); - }); - }); - - - describe('ChangesController max results', function () { - var containerEl, changesEl; - var maxChanges = 10; - - beforeEach(function () { - - var changes = []; - _.times(maxChanges + 10, function (i) { - changes.push({ id: 'doc_' + i, seq: 1, changes: { code: 'here' } }); - }); - - var response = JSON.stringify({ - last_seq: 1, - results: changes - }); - - Actions.initChanges({ databaseName: 'test' }); - - // to keep the test speedy, override the default value (1000) - Stores.changesStore.setMaxChanges(maxChanges); - - Actions.updateChanges(response); - changesEl = TestUtils.renderIntoDocument(<Changes.ChangesController />, containerEl); - }); - - afterEach(function () { - Stores.changesStore.reset(); - React.unmountComponentAtNode(containerEl); - }); - - it('should truncate the number of results with very large # of changes', function () { - // check there's no more than maxChanges results - assert.equal(maxChanges, $(changesEl.getDOMNode()).find('.change-box').length); - }); - - it('should show a message if the results are truncated', function () { - assert.equal(1, $(changesEl.getDOMNode()).find('.changes-result-limit').length); - }); - - }); - - - describe('ChangeRow', function () { - var container; - var change = { - id: '123', - seq: 5, - deleted: false, - changes: { code: 'here' } - }; - - beforeEach(function () { - container = document.createElement('div'); - }); - - afterEach(function () { - React.unmountComponentAtNode(container); - }); - - - it('clicking the toggle-json button shows the code section', function () { - var changeRow = TestUtils.renderIntoDocument(<Changes.ChangeRow change={change} databaseName="testDatabase" />, container); - - // confirm it's hidden by default - assert.equal(0, $(changeRow.getDOMNode()).find('.prettyprint').length); - - // confirm clicking it shows the element - TestUtils.Simulate.click($(changeRow.getDOMNode()).find('button.btn')[0]); - assert.equal(1, $(changeRow.getDOMNode()).find('.prettyprint').length); - }); - - it('deleted docs should not be clickable', function () { - change.deleted = true; - var changeRow = TestUtils.renderIntoDocument(<Changes.ChangeRow change={change} databaseName="testDatabase" />, container); - assert.equal(0, $(changeRow.getDOMNode()).find('a.js-doc-link').length); - }); - - it('non-deleted docs should be clickable', function () { - change.deleted = false; - var changeRow = TestUtils.renderIntoDocument(<Changes.ChangeRow change={change} databaseName="testDatabase" />, container); - assert.equal(1, $(changeRow.getDOMNode()).find('a.js-doc-link').length); - }); - }); - -}); http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/deaf53c9/app/addons/documents/tests/changes.storesSpec.js ---------------------------------------------------------------------- diff --git a/app/addons/documents/tests/changes.storesSpec.js b/app/addons/documents/tests/changes.storesSpec.js deleted file mode 100644 index fedfb13..0000000 --- a/app/addons/documents/tests/changes.storesSpec.js +++ /dev/null @@ -1,107 +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/documents/changes/stores', - 'testUtils' -], function (app, FauxtonAPI, Stores, utils) { - FauxtonAPI.router = new FauxtonAPI.Router([]); - - var assert = utils.assert; - - - describe('ChangesStore', function () { - - afterEach(function () { - Stores.changesStore.reset(); - }); - - it('toggleTabVisibility() changes state in store', function () { - assert.ok(Stores.changesStore.isTabVisible() === false); - Stores.changesStore.toggleTabVisibility(); - assert.ok(Stores.changesStore.isTabVisible() === true); - }); - - it('reset() changes tab visibility to hidden', function () { - Stores.changesStore.toggleTabVisibility(); - Stores.changesStore.reset(); - assert.ok(Stores.changesStore.isTabVisible() === false); - }); - - it('addFilter() adds item in store', function () { - var filter = 'My filter'; - Stores.changesStore.addFilter(filter); - var filters = Stores.changesStore.getFilters(); - assert.ok(filters.length === 1); - assert.ok(filters[0] === filter); - }); - - it('removeFilter() removes item from store', function () { - var filter1 = 'My filter 1'; - var filter2 = 'My filter 2'; - Stores.changesStore.addFilter(filter1); - Stores.changesStore.addFilter(filter2); - Stores.changesStore.removeFilter(filter1); - - var filters = Stores.changesStore.getFilters(); - assert.ok(filters.length === 1); - assert.ok(filters[0] === filter2); - }); - - it('hasFilter() finds item in store', function () { - var filter = 'My filter'; - Stores.changesStore.addFilter(filter); - assert.ok(Stores.changesStore.hasFilter(filter) === true); - }); - - it('getDatabaseName() returns database name', function () { - var dbName = 'hoopoes'; - Stores.changesStore.initChanges({ databaseName: dbName }); - assert.equal(Stores.changesStore.getDatabaseName(), dbName); - - Stores.changesStore.reset(); - assert.equal(Stores.changesStore.getDatabaseName(), ''); - }); - - it("getChanges() should return a subset if there are a lot of changes", function () { - - // to keep the test speedy, we override the default max value - var maxChanges = 10; - var changes = []; - _.times(maxChanges + 10, function (i) { - changes.push({ id: 'doc_' + i, seq: 1, changes: {}}); - }); - Stores.changesStore.initChanges({ databaseName: "test" }); - Stores.changesStore.setMaxChanges(maxChanges); - - var seqNum = 123; - Stores.changesStore.updateChanges(seqNum, changes); - - var results = Stores.changesStore.getChanges(); - assert.equal(maxChanges, results.length); - }); - - it("tracks last sequence number", function () { - assert.equal(null, Stores.changesStore.getLastSeqNum()); - - var seqNum = 123; - Stores.changesStore.updateChanges(seqNum, []); - - // confirm it's been stored - assert.equal(seqNum, Stores.changesStore.getLastSeqNum()); - }); - - }); - -}); http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/deaf53c9/app/addons/documents/tests/headerSpec.react.jsx ---------------------------------------------------------------------- diff --git a/app/addons/documents/tests/headerSpec.react.jsx b/app/addons/documents/tests/headerSpec.react.jsx deleted file mode 100644 index 420aebe..0000000 --- a/app/addons/documents/tests/headerSpec.react.jsx +++ /dev/null @@ -1,112 +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([ - 'api', - 'addons/documents/header/header.react', - 'addons/documents/header/header.stores', - 'addons/documents/header/header.actions', - - 'addons/databases/base', - 'addons/documents/resources', - 'addons/documents/index-results/actions', - 'addons/documents/index-results/stores', - - 'testUtils', - 'react' -], function (FauxtonAPI, Views, Stores, Actions, Databases, Resources, - IndexResultsActions, IndexResultsStore, utils, React) { - - var assert = utils.assert; - var restore = utils.restore; - var TestUtils = React.addons.TestUtils; - - describe('Header Controller', function () { - var container, toggleEl; - beforeEach(function () { - container = document.createElement('div'); - }); - - afterEach(function () { - React.unmountComponentAtNode(container); - }); - - it('should not include invalid calssname', function () { - toggleEl = TestUtils.renderIntoDocument(<Views.HeaderBarController />, container); - var $el = $(toggleEl.getDOMNode()).find('.control-toggle-alternative-header'); - assert.equal($(toggleEl.getDOMNode()).find('.undefined').length, 0); - }); - - it('should use the passed classname', function () { - toggleEl = TestUtils.renderIntoDocument(<Views.HeaderBarController />, container); - var $el = $(toggleEl.getDOMNode()).find('.control-toggle-alternative-header'); - TestUtils.Simulate.click($el[0]); - assert.ok($el.hasClass('js-headerbar-togglebutton-selected')); - }); - - it('should not render the alternative header if the button is not clicked', function () { - Actions.resetHeaderController(); - toggleEl = TestUtils.renderIntoDocument(<Views.HeaderBarController />, container); - var $el = $(toggleEl.getDOMNode()).find('.control-toggle-alternative-header'); - assert.equal($(toggleEl.getDOMNode()).find('.alternative-header').length, 0); - }); - - it('should render the alternative header', function () { - toggleEl = TestUtils.renderIntoDocument(<Views.HeaderBarController />, container); - var $el = $(toggleEl.getDOMNode()).find('.control-toggle-alternative-header'); - TestUtils.Simulate.click($el[0]); - assert.equal($(toggleEl.getDOMNode()).find('.alternative-header').length, 1); - }); - }); - - describe('Bulkdocument Headerbar Controller', function () { - var container, header; - beforeEach(function () { - var database = new Databases.Model({id: 'registry'}); - - database.allDocs = new Resources.AllDocs({_id: "ente"}, { - database: database, - viewMeta: {update_seq: 1}, - params: {} - }); - - //override reset so we don't loose the added doc needed for testing - database.allDocs.reset = function () {}; - - IndexResultsActions.newResultsList({ - collection: database.allDocs, - isListDeletable: false - }); - - - container = document.createElement('div'); - }); - - afterEach(function () { - React.unmountComponentAtNode(container); - restore(Actions.collapseDocuments); - }); - - it('should trigger action', function () { - var spy = sinon.spy(Actions, 'collapseDocuments'); - header = TestUtils.renderIntoDocument(<Views.BulkDocumentHeaderController />, container); - TestUtils.Simulate.click($(header.getDOMNode()).find('.control-collapse')[0]); - - assert.ok(spy.calledOnce); - }); - - it('pressing SelectAll should fill the selected items list', function () { - TestUtils.Simulate.click($(header.getDOMNode()).find('.control-select-all')[0]); - - assert.equal(IndexResultsStore.indexResultsStore.getSelectedItemsLength(), 1); - }); - }); -});
