From a9e29eee8563e18953f53fec8d07cf200d90e540 Mon Sep 17 00:00:00 2001 From: coderaiser Date: Wed, 15 Jul 2026 10:31:07 +0000 Subject: [PATCH] test: cloudcmd: coverage --- client/key/binder.spec.js | 28 +++++++++ client/key/vim/index.spec.js | 80 ++++++++++++++++++++++++++ server/cloudcmd.spec.js | 65 +++++++++++++++++++++ server/rest/index.spec.js | 107 ++++++++++++++++++++++++++++++++++- server/validate.spec.js | 24 ++++++++ 5 files changed, 303 insertions(+), 1 deletion(-) create mode 100644 client/key/binder.spec.js diff --git a/client/key/binder.spec.js b/client/key/binder.spec.js new file mode 100644 index 00000000..f9d54fdd --- /dev/null +++ b/client/key/binder.spec.js @@ -0,0 +1,28 @@ +import {test} from 'supertape'; +import {createBinder} from './binder.js'; + +test('client: key: binder: isBind: default', (t) => { + const binder = createBinder(); + + t.notOk(binder.isBind(), 'should not be bind by default'); + t.end(); +}); + +test('client: key: binder: setBind', (t) => { + const binder = createBinder(); + + binder.setBind(); + + t.ok(binder.isBind(), 'should be bind'); + t.end(); +}); + +test('client: key: binder: unsetBind', (t) => { + const binder = createBinder(); + + binder.setBind(); + binder.unsetBind(); + + t.notOk(binder.isBind(), 'should not be bind'); + t.end(); +}); diff --git a/client/key/vim/index.spec.js b/client/key/vim/index.spec.js index e1ca4eee..a10650ad 100644 --- a/client/key/vim/index.spec.js +++ b/client/key/vim/index.spec.js @@ -1,6 +1,7 @@ import {test, stub} from 'supertape'; import {getDOM, getCloudCmd} from './globals.fixture.js'; import vim, {selectFile as vimSelectFile} from './index.js'; +import * as finder from './find.js'; globalThis.DOM = getDOM(); globalThis.CloudCmd = getCloudCmd(); @@ -675,3 +676,82 @@ test('cloudcmd: client: vim: rename', async (t) => { t.calledWithNoArgs(renameCurrent); t.end(); }); + +test('cloudcmd: client: key: cc: operationCopy', (t) => { + const show = stub(); + const preventDefault = stub(); + + const Operation = { + show, + }; + + const event = { + preventDefault, + }; + + vim('c', event, { + Operation, + }); + + vim('c', event, { + Operation, + }); + + t.calledWith(show, ['copy'], 'should show copy operation'); + t.end(); +}); + +test('cloudcmd: client: key: mm: operationMove', (t) => { + const show = stub(); + const preventDefault = stub(); + + const Operation = { + show, + }; + + const event = { + preventDefault, + }; + + vim('m', event, { + Operation, + }); + + vim('m', event, { + Operation, + }); + + t.calledWith(show, ['move'], 'should show move operation'); + t.end(); +}); + +test('cloudcmd: client: key: n: findNext: real', (t) => { + const setCurrentByName = stub(); + + finder.find('a', ['alpha', 'beta', 'apple']); + + const event = {}; + + vim('n', event, { + setCurrentByName, + }); + + t.calledWith(setCurrentByName, ['beta'], 'should set current by next found name'); + t.end(); +}); + +test('cloudcmd: client: key: N: findPrevious: real', (t) => { + const setCurrentByName = stub(); + + finder.find('a', ['alpha', 'beta', 'apple']); + + const event = {}; + + vim('N', event, { + setCurrentByName, + }); + + t.calledWith(setCurrentByName, ['apple'], 'should set current by previous found name'); + t.end(); +}); + diff --git a/server/cloudcmd.spec.js b/server/cloudcmd.spec.js index a7e7589c..8b31f3b5 100644 --- a/server/cloudcmd.spec.js +++ b/server/cloudcmd.spec.js @@ -10,6 +10,7 @@ import cloudcmd, { _initAuth, _getIndexPath, } from '#server/cloudcmd'; +import {connect} from '../test/before.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); @@ -178,3 +179,67 @@ test('cloudcmd: sw', async (t) => { t.equal(status, 200, 'should return sw'); t.end(); }); + +test('cloudcmd: no params', (t) => { + const middle = cloudcmd(); + + t.ok(Array.isArray(middle), 'should return middleware list when no params passed'); + t.end(); +}); + +test('cloudcmd: listen: terminal', async (t) => { + const {done} = await connect({ + config: { + terminal: true, + }, + }); + + await done(); + + t.pass('should listen with terminal enabled'); + t.end(); +}); + +test('cloudcmd: middle: dropbox', async (t) => { + const {port, done} = await connect({ + config: { + dropbox: true, + dropboxToken: 'hello', + }, + }); + + const response = await fetch(`http://localhost:${port}/api/v1/dropbox/nonexistent`); + + await done(); + + t.ok(response.status, 'should mount dropbox route'); + t.end(); +}); + + +test('cloudcmd: logout', async (t) => { + const {status} = await request.get('/logout'); + + t.equal(status, 401, 'should return 401 for /logout'); + t.end(); +}); + +test('cloudcmd: modules', (t) => { + const middle = cloudcmd({ + modules: { + hello: () => {}, + }, + }); + + t.ok(Array.isArray(middle), 'should return middleware list with modules'); + t.end(); +}); + +test('cloudcmd: setUrl: cloudcmd.js', async (t) => { + const {status} = await request.get('/cloudcmd.js'); + + t.equal(status, 200, 'should serve cloudcmd.js'); + t.end(); +}); + + diff --git a/server/rest/index.spec.js b/server/rest/index.spec.js index 0fd64d7c..0b25b876 100644 --- a/server/rest/index.spec.js +++ b/server/rest/index.spec.js @@ -1,4 +1,4 @@ -import {test} from 'supertape'; +import {test, stub} from 'supertape'; import {tryToCatch} from 'try-to-catch'; import { _formatMsg, @@ -6,6 +6,13 @@ import { _isRootWin32, _isRootAll, _onPUT, + _UserError, + _getPackReg, + _getCMD, + _rename, + _pack, + _extract, + _getPacker, } from './index.js'; test('rest: formatMsg', (t) => { @@ -70,3 +77,101 @@ test('rest: onPUT: no callback', async (t) => { t.equal(e.message, 'callback should be a function!', 'should throw when no callback'); t.end(); }); + + +test('rest: UserError: message', (t) => { + const result = _UserError('hello'); + + t.equal(result.message, 'hello', 'should set message'); + t.end(); +}); + +test('rest: UserError: code', (t) => { + const result = _UserError('hello'); + + t.equal(result.code, 'EUSER', 'should set code'); + t.end(); +}); + +test('rest: getPackReg: zip', (t) => { + const result = _getPackReg('zip'); + + t.ok(result.test('file.zip'), 'should match .zip'); + t.end(); +}); + +test('rest: getPackReg: tar', (t) => { + const result = _getPackReg('tar'); + + t.ok(result.test('file.tar.gz'), 'should match .tar.gz'); + t.end(); +}); + +test('rest: getCMD: with slash', (t) => { + const result = _getCMD('/move'); + + t.equal(result, 'move', 'should strip leading slash'); + t.end(); +}); + +test('rest: getCMD: no slash', (t) => { + const result = _getCMD('move'); + + t.equal(result, 'move', 'should return as is'); + t.end(); +}); + +test('rest: rename: no from', async (t) => { + const callback = stub(); + + _rename('/', null, 'to', null, callback); + + const msg = '"from" should be filled'; + + t.calledWith(callback, [_UserError(msg)], 'should return UserError'); + t.end(); +}); + +test('rest: rename: no to', async (t) => { + const callback = stub(); + + _rename('/', 'from', null, null, callback); + + const msg = '"to" should be filled'; + + t.calledWith(callback, [_UserError(msg)], 'should return UserError'); + t.end(); +}); + +test('rest: rename: success', (t) => { + const callback = stub(); + const fs = { + rename: stub(), + }; + + _rename('/root', 'from', 'to', fs, callback); + + t.calledWith(fs.rename, ['/root/from', '/root/to', callback], 'should call fs.rename'); + t.end(); +}); + +test('rest: getPacker: extract', (t) => { + const result = _getPacker('extract', 'zip'); + + t.equal(typeof result, 'function', 'should return function'); + t.end(); +}); + +test('rest: getPacker: pack zip', (t) => { + const result = _getPacker('pack', 'zip'); + + t.equal(typeof result, 'function', 'should return function'); + t.end(); +}); + +test('rest: getPacker: pack tar', (t) => { + const result = _getPacker('pack', 'tar'); + + t.equal(typeof result, 'function', 'should return function'); + t.end(); +}); diff --git a/server/validate.spec.js b/server/validate.spec.js index 76243e30..d2fd1bd9 100644 --- a/server/validate.spec.js +++ b/server/validate.spec.js @@ -131,3 +131,27 @@ test('validate: theme: wrong', (t) => { t.calledWith(exit, [msg], 'should call exit'); t.end(); }); + + +test('validate: menu: not valid', (t) => { + const exit = stub(); + const msg = 'cloudcmd --menu: could be "supermenu" or "aleman" only'; + + validate.menu('hello', { + exit, + }); + + t.calledWith(exit, [msg], 'should call fn'); + t.end(); +}); + +test('validate: menu: valid', (t) => { + const exit = stub(); + + validate.menu('supermenu', { + exit, + }); + + t.notCalled(exit, 'should not call fn'); + t.end(); +});