|
@@ -1,235 +0,0 @@
|
|
|
-/* eslint-disable
|
|
|
|
|
- no-return-assign,
|
|
|
|
|
-*/
|
|
|
|
|
-// TODO: This file was created by bulk-decaffeinate.
|
|
|
|
|
-// Fix any style issues and re-enable lint.
|
|
|
|
|
-/*
|
|
|
|
|
- * decaffeinate suggestions:
|
|
|
|
|
- * DS102: Remove unnecessary code created because of implicit returns
|
|
|
|
|
- * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
|
|
|
|
- */
|
|
|
|
|
-const SandboxedModule = require('sandboxed-module')
|
|
|
|
|
-const sinon = require('sinon')
|
|
|
|
|
-const { expect } = require('chai')
|
|
|
|
|
-const modulePath = require('path').join(__dirname, '../../../app/js/UrlFetcher')
|
|
|
|
|
-const { EventEmitter } = require('events')
|
|
|
|
|
-
|
|
|
|
|
-describe('UrlFetcher', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- this.callback = sinon.stub()
|
|
|
|
|
- this.url = 'https://www.example.com/file/here?query=string'
|
|
|
|
|
- return (this.UrlFetcher = SandboxedModule.require(modulePath, {
|
|
|
|
|
- requires: {
|
|
|
|
|
- request: {
|
|
|
|
|
- defaults: (this.defaults = sinon.stub().returns((this.request = {}))),
|
|
|
|
|
- },
|
|
|
|
|
- fs: (this.fs = {
|
|
|
|
|
- rename: sinon.stub().yields(),
|
|
|
|
|
- unlink: sinon.stub().yields(),
|
|
|
|
|
- }),
|
|
|
|
|
- '@overleaf/settings': (this.settings = {
|
|
|
|
|
- apis: {
|
|
|
|
|
- clsiPerf: {
|
|
|
|
|
- host: 'localhost:3043',
|
|
|
|
|
- },
|
|
|
|
|
- },
|
|
|
|
|
- }),
|
|
|
|
|
- },
|
|
|
|
|
- }))
|
|
|
|
|
- })
|
|
|
|
|
- describe('pipeUrlToFileWithRetry', function () {
|
|
|
|
|
- this.beforeEach(function () {
|
|
|
|
|
- this.UrlFetcher.pipeUrlToFile = sinon.stub()
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should call pipeUrlToFile', function (done) {
|
|
|
|
|
- this.UrlFetcher.pipeUrlToFile.callsArgWith(2)
|
|
|
|
|
- this.UrlFetcher.pipeUrlToFileWithRetry(this.url, this.path, err => {
|
|
|
|
|
- expect(err).to.equal(undefined)
|
|
|
|
|
- this.UrlFetcher.pipeUrlToFile.called.should.equal(true)
|
|
|
|
|
- done()
|
|
|
|
|
- })
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should call pipeUrlToFile multiple times on error', function (done) {
|
|
|
|
|
- const error = new Error("couldn't download file")
|
|
|
|
|
- this.UrlFetcher.pipeUrlToFile.callsArgWith(2, error)
|
|
|
|
|
- this.UrlFetcher.pipeUrlToFileWithRetry(this.url, this.path, err => {
|
|
|
|
|
- expect(err).to.equal(error)
|
|
|
|
|
- this.UrlFetcher.pipeUrlToFile.callCount.should.equal(3)
|
|
|
|
|
- done()
|
|
|
|
|
- })
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should call pipeUrlToFile twice if only 1 error', function (done) {
|
|
|
|
|
- this.UrlFetcher.pipeUrlToFile.onCall(0).callsArgWith(2, 'error')
|
|
|
|
|
- this.UrlFetcher.pipeUrlToFile.onCall(1).callsArgWith(2)
|
|
|
|
|
- this.UrlFetcher.pipeUrlToFileWithRetry(this.url, this.path, err => {
|
|
|
|
|
- expect(err).to.equal(undefined)
|
|
|
|
|
- this.UrlFetcher.pipeUrlToFile.callCount.should.equal(2)
|
|
|
|
|
- done()
|
|
|
|
|
- })
|
|
|
|
|
- })
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- describe('pipeUrlToFile', function () {
|
|
|
|
|
- it('should turn off the cookie jar in request', function () {
|
|
|
|
|
- return this.defaults.calledWith({ jar: false }).should.equal(true)
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- describe('rewrite url domain if filestoreDomainOveride is set', function () {
|
|
|
|
|
- beforeEach(function () {
|
|
|
|
|
- this.path = '/path/to/file/on/disk'
|
|
|
|
|
- this.request.get = sinon
|
|
|
|
|
- .stub()
|
|
|
|
|
- .returns((this.urlStream = new EventEmitter()))
|
|
|
|
|
- this.urlStream.pipe = sinon.stub()
|
|
|
|
|
- this.urlStream.pause = sinon.stub()
|
|
|
|
|
- this.urlStream.resume = sinon.stub()
|
|
|
|
|
- this.fs.createWriteStream = sinon
|
|
|
|
|
- .stub()
|
|
|
|
|
- .returns((this.fileStream = new EventEmitter()))
|
|
|
|
|
- return (this.fs.unlink = (file, callback) => callback())
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should use the normal domain when override not set', function (done) {
|
|
|
|
|
- this.UrlFetcher.pipeUrlToFile(this.url, this.path, () => {
|
|
|
|
|
- this.request.get.args[0][0].url.should.equal(this.url)
|
|
|
|
|
- return done()
|
|
|
|
|
- })
|
|
|
|
|
- this.res = { statusCode: 200 }
|
|
|
|
|
- this.urlStream.emit('response', this.res)
|
|
|
|
|
- this.urlStream.emit('end')
|
|
|
|
|
- return this.fileStream.emit('finish')
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should not use override clsiPerf domain when filestoreDomainOveride is set', function (done) {
|
|
|
|
|
- this.settings.filestoreDomainOveride = '192.11.11.11'
|
|
|
|
|
- const url = 'http://localhost:3043/file/here?query=string'
|
|
|
|
|
- this.UrlFetcher.pipeUrlToFile(url, this.path, () => {
|
|
|
|
|
- this.request.get.args[0][0].url.should.equal(url)
|
|
|
|
|
- done()
|
|
|
|
|
- })
|
|
|
|
|
- this.res = { statusCode: 200 }
|
|
|
|
|
- this.urlStream.emit('response', this.res)
|
|
|
|
|
- this.urlStream.emit('end')
|
|
|
|
|
- this.fileStream.emit('finish')
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- return it('should use override domain when filestoreDomainOveride is set', function (done) {
|
|
|
|
|
- this.settings.filestoreDomainOveride = '192.11.11.11'
|
|
|
|
|
- this.UrlFetcher.pipeUrlToFile(this.url, this.path, () => {
|
|
|
|
|
- this.request.get.args[0][0].url.should.equal(
|
|
|
|
|
- '192.11.11.11/file/here?query=string'
|
|
|
|
|
- )
|
|
|
|
|
- return done()
|
|
|
|
|
- })
|
|
|
|
|
- this.res = { statusCode: 200 }
|
|
|
|
|
- this.urlStream.emit('response', this.res)
|
|
|
|
|
- this.urlStream.emit('end')
|
|
|
|
|
- return this.fileStream.emit('finish')
|
|
|
|
|
- })
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- return describe('pipeUrlToFile', function () {
|
|
|
|
|
- beforeEach(function (done) {
|
|
|
|
|
- this.path = '/path/to/file/on/disk'
|
|
|
|
|
- this.request.get = sinon
|
|
|
|
|
- .stub()
|
|
|
|
|
- .returns((this.urlStream = new EventEmitter()))
|
|
|
|
|
- this.urlStream.pipe = sinon.stub()
|
|
|
|
|
- this.urlStream.pause = sinon.stub()
|
|
|
|
|
- this.urlStream.resume = sinon.stub()
|
|
|
|
|
- this.fs.createWriteStream = sinon
|
|
|
|
|
- .stub()
|
|
|
|
|
- .returns((this.fileStream = new EventEmitter()))
|
|
|
|
|
- this.fs.unlink = (file, callback) => callback()
|
|
|
|
|
- return done()
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- describe('successfully', function () {
|
|
|
|
|
- beforeEach(function (done) {
|
|
|
|
|
- this.UrlFetcher.pipeUrlToFile(this.url, this.path, () => {
|
|
|
|
|
- this.callback()
|
|
|
|
|
- return done()
|
|
|
|
|
- })
|
|
|
|
|
- this.res = { statusCode: 200 }
|
|
|
|
|
- this.urlStream.emit('response', this.res)
|
|
|
|
|
- this.urlStream.emit('end')
|
|
|
|
|
- return this.fileStream.emit('finish')
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should request the URL', function () {
|
|
|
|
|
- return this.request.get
|
|
|
|
|
- .calledWith(sinon.match({ url: this.url }))
|
|
|
|
|
- .should.equal(true)
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should open the atomic file for writing', function () {
|
|
|
|
|
- return this.fs.createWriteStream
|
|
|
|
|
- .calledWith(this.path + '~')
|
|
|
|
|
- .should.equal(true)
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should move the atomic file to the target', function () {
|
|
|
|
|
- return this.fs.rename
|
|
|
|
|
- .calledWith(this.path + '~', this.path)
|
|
|
|
|
- .should.equal(true)
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should pipe the URL to the file', function () {
|
|
|
|
|
- return this.urlStream.pipe
|
|
|
|
|
- .calledWith(this.fileStream)
|
|
|
|
|
- .should.equal(true)
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- return it('should call the callback', function () {
|
|
|
|
|
- return this.callback.called.should.equal(true)
|
|
|
|
|
- })
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- describe('with non success status code', function () {
|
|
|
|
|
- beforeEach(function (done) {
|
|
|
|
|
- this.UrlFetcher.pipeUrlToFile(this.url, this.path, err => {
|
|
|
|
|
- this.callback(err)
|
|
|
|
|
- return done()
|
|
|
|
|
- })
|
|
|
|
|
- this.res = { statusCode: 404 }
|
|
|
|
|
- this.urlStream.emit('response', this.res)
|
|
|
|
|
- return this.urlStream.emit('end')
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should call the callback with an error', function () {
|
|
|
|
|
- this.callback.calledWith(sinon.match(Error)).should.equal(true)
|
|
|
|
|
-
|
|
|
|
|
- const message = this.callback.args[0][0].message
|
|
|
|
|
- expect(message).to.include(
|
|
|
|
|
- 'URL returned non-success status code: 404'
|
|
|
|
|
- )
|
|
|
|
|
- })
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- return describe('with error', function () {
|
|
|
|
|
- beforeEach(function (done) {
|
|
|
|
|
- this.UrlFetcher.pipeUrlToFile(this.url, this.path, err => {
|
|
|
|
|
- this.callback(err)
|
|
|
|
|
- return done()
|
|
|
|
|
- })
|
|
|
|
|
- return this.urlStream.emit(
|
|
|
|
|
- 'error',
|
|
|
|
|
- (this.error = new Error('something went wrong'))
|
|
|
|
|
- )
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- it('should call the callback with the error', function () {
|
|
|
|
|
- return this.callback.calledWith(this.error).should.equal(true)
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- return it('should only call the callback once, even if end is called', function () {
|
|
|
|
|
- this.urlStream.emit('end')
|
|
|
|
|
- return this.callback.calledOnce.should.equal(true)
|
|
|
|
|
- })
|
|
|
|
|
- })
|
|
|
|
|
- })
|
|
|
|
|
- })
|
|
|
|
|
-})
|
|
|