UNPKG

node-smb-server

Version:

A Pure JavaScript SMB Server Implementation

377 lines (347 loc) 14.9 kB
/* * Copyright 2016 Adobe Systems Incorporated. All rights reserved. * This file is licensed to you 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 REPRESENTATIONS * OF ANY KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ var RQCommon = require('./rq-common'); var RQProcessor = RQCommon.require(__dirname, '../../../../lib/backends/rq/rqprocessor'); var RequestQueue = RQCommon.require(__dirname, '../../../../lib/backends/rq/requestqueue'); var Path = require('path'); var URL = require('url'); describe('RQProcessor', function () { var processor, c, rq, config; beforeEach(function () { c = new RQCommon(); processor = new RQProcessor(c.testTree); config = { expiration: 0, maxRetries: 3, retryDelay: 200, frequency: 500 }; spyOn(processor, 'emit').andCallThrough(); }); describe('RQUpdated', function () { it('testItemUpdatedUploading', function (done) { var delayed = false; c.addQueuedFile('/testfile', function () { c.setPipeDelay(function (delayCb) { if (!delayed) { delayed = true; c.testTree.rq.queueRequest({ method: 'POST', path: '/testfile', localPrefix: c.localPrefix, remotePrefix: c.hostPrefix }, function (err) { delayCb(); }); } else { delayCb(); } }); processor.sync(config, function (err) { expect(err).toBeFalsy(); expect(processor.emit).toHaveBeenCalledWith('syncabort', {path: '/testfile', file: '/local/path/testfile'}); expect(processor.emit).toHaveBeenCalledWith('syncend', {path: '/testfile', file: '/local/path/testfile', method: 'POST'}); done(); }); }); }); it('testItemUpdatedNotUploading', function (done) { c.addQueuedFile('/testfile', function () { c.testTree.rq.queueRequest({ method: 'POST', path: '/testfile', localPrefix: c.localPrefix, remotePrefix: c.hostPrefix }, function (err) { expect(err).toBeFalsy(); c.expectQueuedMethod('/', 'testfile', 'PUT', function () { expect(processor.emit).not.toHaveBeenCalledWith('syncabort', {path: '/testfile', file: '/local/path/testfile'}); done(); }); }); }); }); var testPathUpdated = function (path, removePath, done) { c.addQueuedFile(path, function () { c.setPipeDelay(function (pipeCb) { c.testTree.rq.removePath(removePath, function (err) { pipeCb(); }); }); processor.sync(config, function (err) { expect(err).toBeFalsy(); expect(processor.emit).toHaveBeenCalledWith('syncabort', {path: path, file: '/local/path' + path}); expect(processor.emit).not.toHaveBeenCalledWith('syncend', {path: path, file: '/local/path' + path, method:'POST'}); done(); }); }); }; it('testPathUpdatedUploading', function (done) { testPathUpdated('/testfile', '/', done); }); it('testPathUpdatedUploadingSubPath', function (done) { testPathUpdated('/dir/testfile', '/', done); }); it('testPathUpdatedUploadingSubPathNotRoot', function (done) { testPathUpdated('/dir/testfile', '/dir', done); }); }); describe('Sync', function () { var testDotFile = function (path, name, done) { c.testTree.rq.getProcessRequest = function (expiration, maxRetries, cb) { cb(null, { path: path, name: name, method: 'DELETE', remotePrefix: c.hostPrefix, localPrefix: c.localPrefix }); }; c.testTree.rq.completeRequest = function (path, name, cb) { c.testTree.rq.getProcessRequest = function (expiration, maxRetries, getCb) { getCb(); }; cb(); }; processor.sync(config, function (err) { expect(err).toBeFalsy(); expect(processor.emit).toHaveBeenCalledWith('syncerr', {path: Path.join(path, name), file: Path.join(c.localPrefix, path, name), method: 'DELETE', err: jasmine.any(String)}); done(); }); }; var addLocalCachedFile = function (path, cb) { c.addFile(c.remoteTree, path, function () { c.testTree.open(path, function (err, file) { expect(err).toBeFalsy(); file.cacheFile(function (err) { expect(err).toBeFalsy(); cb(file); }); }); }); }; it('testSyncCreate', function (done) { c.addQueuedFile('/testfile', function () { processor.sync(config, function (err) { expect(err).toBeFalsy(); c.expectLocalFileExist('/testfile', true, false, function () { c.expectQueuedMethod('/', 'testfile', false, function () { expect(processor.emit).toHaveBeenCalledWith('syncstart', {path: '/testfile', file: '/local/path/testfile', method: 'POST'}); expect(processor.emit).toHaveBeenCalledWith('syncprogress', {path: '/testfile', file: '/local/path/testfile', read: jasmine.any(Number), total: jasmine.any(Number), rate: jasmine.any(Number)}); expect(processor.emit).toHaveBeenCalledWith('syncend', {path: '/testfile', file: '/local/path/testfile', method: 'POST'}); done(); }); }); }); }); }); it('testSyncUpdate', function (done) { addLocalCachedFile('/testfile', function (file) { file.setLength(100, function (err) { expect(err).toBeFalsy(); file.close(function (err) { expect(err).toBeFalsy(); processor.sync(config, function (err) { expect(err).toBeFalsy(); c.expectQueuedMethod('/', 'testfile', false, function () { expect(processor.emit).toHaveBeenCalledWith('syncstart', {path: '/testfile', file: '/local/path/testfile', method: 'PUT'}); expect(processor.emit).toHaveBeenCalledWith('syncprogress', {path: '/testfile', file: '/local/path/testfile', read: jasmine.any(Number), total: jasmine.any(Number), rate: jasmine.any(Number)}); expect(processor.emit).toHaveBeenCalledWith('syncend', {path: '/testfile', file: '/local/path/testfile', method: 'PUT'}); done(); }); }); }); }); }); }); it('testSyncDelete', function (done) { addLocalCachedFile('/testfile', function (file) { c.testTree.delete('/testfile', function (err) { expect(err).toBeFalsy(); processor.sync(config, function (err) { expect(err).toBeFalsy(); c.expectQueuedMethod('/', 'testfile', false, function () { expect(processor.emit).toHaveBeenCalledWith('syncstart', {path: '/testfile', file: '/local/path/testfile', method: 'DELETE'}); expect(processor.emit).not.toHaveBeenCalledWith('syncprogress', {path: '/testfile', file: '/local/path/testfile', read: jasmine.any(Number), total: jasmine.any(Number), rate: jasmine.any(Number)}); expect(processor.emit).toHaveBeenCalledWith('syncend', {path: '/testfile', file: '/local/path/testfile', method: 'DELETE'}); done(); }); }); }); }); }); it('testSyncDotFile', function (done) { testDotFile('/', '.badfile', done); }); it('testSyncDotFolder', function (done) { testDotFile('/.badfolder', 'testfile', done); }); it('testSyncErrorStatusCode', function (done) { c.registerPathStatusCode('/testfile', 500); c.addQueuedFile('/testfile', function (file) { processor.sync(config, function (err) { expect(err).toBeFalsy(); c.expectQueuedMethod('/', 'testfile', 'PUT', function () { expect(processor.emit).toHaveBeenCalledWith('syncerr', {path: '/testfile', file: Path.join(c.localPrefix, '/testfile'), method: 'POST', err: jasmine.any(String)}); c.testTree.rq.queueRequest({ method: 'DELETE', path: '/testfile', localPrefix: c.localPrefix, remotePrefix: c.hostPrefix }, function (err) { expect(err).toBeFalsy(); expect(processor.emit).not.toHaveBeenCalledWith('syncabort', {path:any(String), file:any(String)}); done(); }); }); }); }); }); it('testSyncCheckedOut', function (done) { c.registerPathStatusCode('/testfile', 423); c.addQueuedFile('/testfile', function (file) { processor.sync(config, function (err) { expect(err).toBeFalsy(); c.expectQueuedMethod('/', 'testfile', false, function () { expect(processor.emit).toHaveBeenCalledWith('syncerr', {path: '/testfile', file: '/local/path/testfile', method: 'POST', err: jasmine.any(String)}); done(); }); }); }); }); it('testSyncEncoded', function (done) { var remoteEncodedName = '/%EC%9D%B4%EB%91%90%E5%90%8F%E8%AE%80.jpg'; var remoteFileName = decodeURI(remoteEncodedName); var localFileNameOnly = decodeURI('%E1%84%8B%E1%85%B5%E1%84%83%E1%85%AE%E5%90%8F%E8%AE%80.jpg'); var localFileName = '/' + localFileNameOnly; c.addFile(c.remoteTree, remoteFileName, function () { c.addFile(c.localTree, localFileName, function () { c.testTree.open(localFileName, function (err, rqFile) { expect(err).toBeFalsy(); rqFile.setLength(10, function (err) { expect(err).toBeFalsy(); rqFile.close(function (err) { expect(err).toBeFalsy(); processor.sync(config, function (err) { expect(err).toBeFalsy(); expect(c.wasPathRequested(remoteEncodedName)).toBeTruthy(); c.expectQueuedMethod('/', localFileNameOnly, false, done); }); }); }); }); }); }); }); it('testSyncNoExist', function (done) { c.registerPathStatusCode('/testfile', 404); c.addQueuedFile('/testfile', function () { processor.sync(config, function (err) { expect(err).toBeFalsy(); c.expectQueuedMethod('/', 'testfile', 'PUT', function () { expect(processor.emit).toHaveBeenCalledWith('syncerr', { path: '/testfile', file: Path.join(c.localPrefix, '/testfile'), method: 'POST', err: jasmine.any(String) }); done(); }); }); }); }); it('testSyncDates', function (done) { c.addFile(c.remoteTree, '/test', function () { c.testTree.open('/test', function (err, file) { expect(err).toBeFalsy(); var lastModified = file.lastModified(); file.write('hello', 0, function (err) { expect(err).toBeFalsy(); setTimeout(function () { file.setLastModified(new Date().getTime()); file.close(function (err) { expect(err).toBeFalsy(); processor.sync(config, function (err) { expect(err).toBeFalsy(); c.testTree.open('/test', function (err, newFile) { expect(err).toBeFalsy(); expect(file.created()).toEqual(newFile.created()); expect(file.lastModified()).toEqual(newFile.lastModified()); expect(file.lastChanged()).toEqual(newFile.lastChanged()); done(); }); }); }); }, 10); }); }); }); }); it('testCacheFileAfterSync', function (done) { c.addQueuedFile('/testfile', function () { processor.sync(config, function (err) { expect(err).toBeFalsy(); expect(c.getPathMethodRequestCount('/testfile', 'POST')).toEqual(1); c.testTree.open('/testfile', function (err, file) { expect(err).toBeFalsy(); file.cacheFile(function (err) { expect(err).toBeFalsy(); expect(c.getPathMethodRequestCount('/testfile', 'GET')).toEqual(0); done(); }); }); }); }); }); }); describe('StartStop', function () { it('testStartStop', function (done) { c.addQueuedFile('/testfile', function (file) { c.addCachedFile('/testdelete', function () { c.testTree.delete('/testdelete', function (err) { expect(err).toBeFalsy(); c.testTree.rq.incrementRetryCount('/', 'testdelete', 400, function (err) { expect(err).toBeFalsy(); processor.start(config); setTimeout(function () { processor.stop(); expect(processor.emit).toHaveBeenCalledWith('syncstart', {path: '/testfile', file: '/local/path/testfile', method: 'POST'}); expect(processor.emit).toHaveBeenCalledWith('syncend', {path: '/testfile', file: '/local/path/testfile', method: 'POST'}); expect(processor.emit).toHaveBeenCalledWith('syncstart', {path: '/testdelete', file: '/local/path/testdelete', method: 'DELETE'}); expect(processor.emit).toHaveBeenCalledWith('syncend', {path: '/testdelete', file: '/local/path/testdelete', method: 'DELETE'}); done(); }, 1000); }); }); }); }); }); it('testStartStopPurgeRequests', function (done) { c.addQueuedFile('/testfile', function (file) { config.maxRetries = 0; processor.start(config); setTimeout(function () { processor.stop(); expect(processor.emit).toHaveBeenCalledWith('purged', any(Object)); expect(processor.emit).not.toHaveBeenCalledWith('syncstart', any(Object)); done(); }, 200); }); }); it('testStartStopCancelRequest', function (done) { c.addQueuedFile('/testfile', function (file) { c.setPipeDelay(function (delayCb) { processor.stop(); delayCb(); expect(processor.emit).toHaveBeenCalledWith('syncabort', {path: '/testfile', file: '/local/path/testfile'}); done(); }); processor.start(config); }); }); }); });