diff --git a/client/dom/index.js b/client/dom/index.js index 23515bdf..9113ffe4 100644 --- a/client/dom/index.js +++ b/client/dom/index.js @@ -14,13 +14,14 @@ const RESTful = require('./rest'); const IO = require('./io'); const Storage = require('./storage'); const Dialog = require('./dialog'); +const renameCurrent = require('./operations/rename-current'); -const currentFile = require('./current-file'); +const CurrentFile = require('./current-file'); const DOMTree = require('./dom-tree'); const DOM = { ...DOMTree, - ...currentFile, + ...CurrentFile, ...new CmdProto(), }; @@ -671,44 +672,7 @@ function CmdProto() { * * @currentFile */ - this.renameCurrent = async (current) => { - const {Dialog} = DOM; - - if (!DOM.isCurrentFile(current)) - current = DOM.getCurrentFile(); - - const from = DOM.getCurrentName(current); - - if (from === '..') - return Dialog.alert.noFiles(); - - const [cancel, to] = await Dialog.prompt('Rename', from); - - if (cancel) - return; - - const isExist = !!DOM.getCurrentByName(to); - const dirPath = DOM.getCurrentDirPath(); - - if (from === to) - return; - - const files = { - from : dirPath + from, - to : dirPath + to, - }; - - const [e] = await RESTful.mv(files); - - if (e) - return; - - DOM.setCurrentName(to, current); - Storage.remove(dirPath); - - if (isExist) - CloudCmd.refresh(); - }; + this.renameCurrent = renameCurrent; /** * unified way to scrollIntoViewIfNeeded diff --git a/client/dom/operations/rename-current.js b/client/dom/operations/rename-current.js new file mode 100644 index 00000000..401a4378 --- /dev/null +++ b/client/dom/operations/rename-current.js @@ -0,0 +1,63 @@ +'use strict'; + +/* global CloudCmd */ + +const capitalize = require('just-capitalize'); + +const Dialog = require('../dialog'); +const Storage = require('../storage'); +const RESTful = require('../rest'); +const { + isCurrentFile, + getCurrentName, + getCurrentFile, + getCurrentByName, + getCurrentType, + getCurrentDirPath, + setCurrentName, +} = require('../current-file'); + +module.exports = async (current) => { + if (!isCurrentFile(current)) + current = getCurrentFile(); + + const from = getCurrentName(current); + + if (from === '..') + return Dialog.alert.noFiles(); + + const [cancel, to] = await Dialog.prompt('Rename', from); + + if (cancel) + return; + + const nextFile = getCurrentByName(to); + + if (nextFile) { + const type = getCurrentType(nextFile); + const msg = `${capitalize(type)} "${to}" already exists. Proceed?`; + const [cancel] = await Dialog.confirm(msg); + + if (cancel) + return; + } + + if (from === to) + return; + + const dirPath = getCurrentDirPath(); + const files = { + from : dirPath + from, + to : dirPath + to, + }; + + const [e] = await RESTful.mv(files); + + if (e) + return; + + setCurrentName(to, current); + + Storage.remove(dirPath); + CloudCmd.refresh(); +}; diff --git a/client/dom/operations/rename-current.spec.js b/client/dom/operations/rename-current.spec.js new file mode 100644 index 00000000..c90a29c8 --- /dev/null +++ b/client/dom/operations/rename-current.spec.js @@ -0,0 +1,97 @@ +'use strict'; + +const test = require('supertape'); +const stub = require('@cloudcmd/stub'); +const mockRequire = require('mock-require'); + +const {reRequire} = mockRequire; + +test('cloudcmd: client: dom: renameCurrent: isCurrentFile', async (t) => { + const current = {}; + const isCurrentFile = stub(); + + mockRequire('../dialog', stubDialog()); + mockRequire('../current-file', stubCurrentFile({ + isCurrentFile, + })); + + const renameCurrent = reRequire('./rename-current'); + await renameCurrent(current); + + t.ok(isCurrentFile.calledWith(current), 'should call isCurrentFile'); + t.end(); +}); + +test('cloudcmd: client: dom: renameCurrent: file exist', async (t) => { + const current = {}; + const name = 'hello'; + const {CloudCmd} = global; + + const CloudCmdStub = { + refresh: stub(), + }; + + global.CloudCmd = CloudCmdStub; + + const prompt = stub().returns([null, name]); + const confirm = stub().returns([true]); + + const getCurrentByName = stub().returns(current); + const getCurrentType = stub().returns('directory'); + + mockRequire('../dialog', stubDialog({ + confirm, + prompt, + })); + + mockRequire('../current-file', stubCurrentFile({ + getCurrentByName, + getCurrentType, + })); + + const renameCurrent = reRequire('./rename-current'); + await renameCurrent(); + + const expected = 'Directory "hello" already exists. Proceed?'; + global.CloudCmd = CloudCmd; + + t.ok(confirm.calledWith(expected), 'should call confirm'); + t.end(); +}); + +const stubDialog = (fns = {}) => { + const { + alert = stub().returns([]), + confirm = stub().returns([]), + prompt = stub().returns([]), + } = fns; + + return { + alert, + confirm, + prompt, + }; +}; + +const stubCurrentFile = (fns = {}) => { + const { + isCurrentFile = stub(), + getCurrentName = stub(), + getCurrentFile = stub(), + getCurrentByName = stub(), + getCurrentType = stub(), + getCurrentDirPath = stub(), + setCurrentName = stub(), + } = fns; + + return { + isCurrentFile, + getCurrentName, + getCurrentFile, + getCurrentByName, + getCurrentType, + getCurrentDirPath, + setCurrentName, + }; +}; + diff --git a/package.json b/package.json index a9138114..1b13568b 100644 --- a/package.json +++ b/package.json @@ -188,6 +188,7 @@ "html-looks-like": "^1.0.2", "html-webpack-plugin": "^4.0.1", "inherits": "^2.0.3", + "just-capitalize": "^1.0.0", "just-pascal-case": "^1.1.0", "limier": "^3.0.0", "load.js": "^3.0.0",