diff --git a/app/addons/documents/index-editor/tests/actionsSpec.js b/app/addons/documents/index-editor/__tests__/actions.test.js similarity index 70% rename from app/addons/documents/index-editor/tests/actionsSpec.js rename to app/addons/documents/index-editor/__tests__/actions.test.js index 4b09038d8..080fe7b80 100644 --- a/app/addons/documents/index-editor/tests/actionsSpec.js +++ b/app/addons/documents/index-editor/__tests__/actions.test.js @@ -58,15 +58,11 @@ describe('Index Editor Actions', function () { it('saves design doc if has other views', function () { designDoc.save = function () { - var promise = $.Deferred(); - promise.resolve(); - return promise; + return FauxtonAPI.Promise.resolve(); }; var saveSpy = sinon.spy(designDoc, 'save'); designDocs.fetch = function () { - var promise = $.Deferred(); - promise.resolve(); - return promise; + return FauxtonAPI.Promise.resolve(); }; Actions.deleteView({ @@ -83,16 +79,12 @@ describe('Index Editor Actions', function () { designDoc.removeDdocView('test-view2'); designDoc.destroy = function () { - var promise = $.Deferred(); - promise.resolve(); - return promise; + return FauxtonAPI.Promise.resolve(); }; var destroySpy = sinon.spy(designDoc, 'destroy'); designDocs.remove = function () {}; designDocs.fetch = function () { - var promise = $.Deferred(); - promise.resolve(); - return promise; + return FauxtonAPI.Promise.resolve(); }; Actions.deleteView({ @@ -109,26 +101,49 @@ describe('Index Editor Actions', function () { var spy = sinon.spy(FauxtonAPI, 'navigate'); designDoc.save = function () { - var promise = $.Deferred(); - promise.resolve(); - return promise; + return FauxtonAPI.Promise.resolve(); }; designDocs.fetch = function () { - var promise = $.Deferred(); - promise.resolve(); - return promise; + return FauxtonAPI.Promise.resolve(); }; - Actions.deleteView({ + return Actions.deleteView({ indexName: viewName, database: database, designDocs: designDocs, designDoc: designDoc, isOnIndex: true + }).then(() => { + assert.ok(spy.getCall(0).args[0].match(/_all_docs/)); + assert.ok(spy.calledOnce); }); + }); - assert.ok(spy.getCall(0).args[0].match(/_all_docs/)); - assert.ok(spy.calledOnce); + it('saves design doc if it has no view section', function () { + const ddoc = { _id: designDocId }; + const ddocModel = new Documents.Doc(ddoc, { database: database }); + + ddocModel.setDdocView('testview', '() => {}', '() => {}'); + assert.deepEqual(ddocModel.get('views'), { + testview: { + map: '() => {}', + reduce: '() => {}' + } + }); + assert.equal(ddocModel.get('language'), 'javascript'); }); + it('removes old view only when editting', function () { + const viewInfo = { + newView: false, + originalDesignDocName: 'test', + designDocId: 'test', + originalViewName: 'foo', + viewName: 'bar' + }; + assert.isTrue(Actions.shouldRemoveDdocView(viewInfo)); + + viewInfo.newView = true; + assert.isFalse(Actions.shouldRemoveDdocView(viewInfo)); + }); }); }); diff --git a/app/addons/documents/index-editor/actions.js b/app/addons/documents/index-editor/actions.js index 451a9e053..2f02396d8 100644 --- a/app/addons/documents/index-editor/actions.js +++ b/app/addons/documents/index-editor/actions.js @@ -60,6 +60,12 @@ function fetchDesignDocsBeforeEdit (options) { }); } +function shouldRemoveDdocView(viewInfo) { + return !viewInfo.newView && + viewInfo.originalDesignDocName === viewInfo.designDocId && + viewInfo.originalViewName !== viewInfo.viewName; +} + function saveView (viewInfo) { var designDoc = viewInfo.designDoc; designDoc.setDdocView(viewInfo.viewName, viewInfo.map, viewInfo.reduce); @@ -71,7 +77,7 @@ function saveView (viewInfo) { }); // if the view name just changed and it's in the SAME design doc, remove the old one before saving the doc - if (viewInfo.originalDesignDocName === viewInfo.designDocId && viewInfo.originalViewName !== viewInfo.viewName) { + if (shouldRemoveDdocView(viewInfo)) { designDoc.removeDdocView(viewInfo.originalViewName); } @@ -137,7 +143,7 @@ function deleteView (options) { FauxtonAPI.dispatch({ type: SidebarActionTypes.SIDEBAR_HIDE_DELETE_INDEX_MODAL }); } - safeDeleteIndex(options.designDoc, options.designDocs, 'views', options.indexName, { onSuccess: onSuccess }); + return safeDeleteIndex(options.designDoc, options.designDocs, 'views', options.indexName, { onSuccess: onSuccess }); } function cloneView (params) { @@ -253,7 +259,7 @@ function safeDeleteIndex (designDoc, designDocs, indexPropName, indexName, optio promise = designDoc.destroy(); deleteDesignDoc = true; } - promise.then(function () { + return promise.then(function () { if (deleteDesignDoc) { designDocs.remove(designDoc.id); } @@ -299,6 +305,7 @@ export default { editIndex: editIndex, clearIndex: clearIndex, fetchDesignDocsBeforeEdit: fetchDesignDocsBeforeEdit, + shouldRemoveDdocView: shouldRemoveDdocView, saveView: saveView, addDesignDoc: addDesignDoc, deleteView: deleteView, diff --git a/app/addons/documents/shared-resources.js b/app/addons/documents/shared-resources.js index 9bc1465d0..0f2516020 100644 --- a/app/addons/documents/shared-resources.js +++ b/app/addons/documents/shared-resources.js @@ -103,8 +103,13 @@ Documents.Doc = FauxtonAPI.Model.extend({ return false; } - var views = this.get('views'), - tempView = views[view] || {}; + let views = this.get('views'); + // handles instances where the ddoc is empty (created manually) + if (!views) { + views = {}; + this.set({language: "javascript"}); + } + const tempView = views[view] || {}; if (reduce) { tempView.reduce = reduce; diff --git a/test/dev.js b/test/dev.js index c897a856c..effdd8b1c 100644 --- a/test/dev.js +++ b/test/dev.js @@ -13,7 +13,7 @@ // This will search for files ending in .test.js and require them // so that they are added to the webpack bundle -var context = require.context('../app/addons/documents/index-results/testse', true, /[Ss]pec/); +var context = require.context('../app/addons/documents/index-editor/actionsSpec', true, /[Ss]pec/); console.log('Testing files', context.keys()); context.keys().forEach(context); module.exports = context;