UNPKG

nodestream-s3

Version:
189 lines (137 loc) 4.92 kB
/** * Nodestream - S3 * * @author Robert Rossmann <robert.rossmann@me.com> * @copyright 2016 Robert Rossmann * @license BSD-3-Clause */ 'use strict' const expect = require('chai').expect const sinon = require('sinon') const stream = require('stream') const S3 = require('aws-sdk').S3 const s3proto = Object.getPrototypeOf(new S3()) const Adapter = require('../lib/nodestream-s3') describe('Adapter', function() { it('should be a class', function() { // Can't test for a class directly... 🙁 expect(Adapter).to.be.a('function') }) it('should declare its identity', function() { expect(Adapter.identity).to.be.a('string') }) it('should not throw on missing options', function() { expect(() => new Adapter()).to.not.throw() }) describe('.createWriteStream()', function() { let adapter let stubS3 beforeEach(function() { adapter = new Adapter({ bucket: 'testbucket' }) stubS3 = sinon.stub(s3proto, 'upload').callsArgWithAsync(2, null) }) afterEach(function() { stubS3.restore() }) it('should be function', function() { expect(adapter).to.have.property('createWriteStream') expect(adapter.createWriteStream).to.be.a('function') }) it('should return stream', function() { expect(adapter.createWriteStream()).to.be.instanceof(stream) }) it('should emit error when S3 uploader encounters error', function(done) { const dummyError = new Error('some shit happened') stubS3.restore() stubS3 = sinon.stub(s3proto, 'upload').callsArgWithAsync(2, dummyError) const source = adapter.createWriteStream('fake/location') source.once('error', err => { expect(err).to.equal(dummyError) return done() }) }) it('should write the file to a location relative to bucket', function() { adapter.createWriteStream('fake/location') expect(stubS3.firstCall.args[0]).to.have.property('Bucket', 'testbucket') }) it('should send the stream to the Body property on .upload()', function() { const destination = adapter.createWriteStream('fake/location') expect(stubS3.firstCall.args[0]).to.have.property('Body', destination) }) }) describe('.createReadStream()', function() { let adapter let fakeReq let stubS3 beforeEach(function() { adapter = new Adapter({ bucket: 'testbucket' }) fakeReq = { on: () => {}, createReadStream: () => {}, } stubS3 = sinon.stub(s3proto, 'getObject').returns(fakeReq) }) afterEach(function() { stubS3.restore() }) it('should be function', function() { expect(adapter).to.have.property('createReadStream') expect(adapter.createReadStream).to.be.a('function') }) it('should read the file from a location relative to root', function() { adapter.createReadStream('test.txt') expect(stubS3.firstCall.args[0]).to.have.property('Bucket', 'testbucket') }) it('should pass the second options parameter to the .getObject() function', function() { adapter.createReadStream('test.txt', { test: true }) expect(stubS3.firstCall.args[0]).to.have.property('test', true) }) it('should return a readable stream', function() { const fakeStream = new stream.PassThrough() fakeReq.createReadStream = () => fakeStream expect(adapter.createReadStream('test.txt')).to.equal(fakeStream) }) }) describe('.remove()', function() { let adapter let stubS3 beforeEach(function() { adapter = new Adapter({ bucket: 'testbucket' }) stubS3 = sinon.stub(s3proto, 'deleteObject').callsArgWith(1, null) }) afterEach(function() { stubS3.restore() }) it('should be function', function() { expect(adapter).to.have.property('remove') expect(adapter.remove).to.be.a('function') }) it('should return Promise', function() { expect(adapter.remove()).to.be.instanceof(Promise) }) it('should remove the file from a location relative to bucket', function() { adapter.remove('test.txt') expect(stubS3.firstCall.args[0]).to.have.property('Bucket', 'testbucket') }) it('should resolve when the file is removed', function(done) { adapter.remove('test.txt') .then(location => { expect(location).to.equal('test.txt') return done() }) .catch(done) }) it('should reject if the removal fails', function(done) { const dummyErr = new Error('fail!') stubS3.restore() stubS3 = sinon.stub(s3proto, 'deleteObject').callsArgWith(1, dummyErr) adapter.remove('test.txt') .then(() => done(new Error('Removal should have been rejected'))) .catch(err => { expect(err).to.be.equal(dummyErr) return done() }) .catch(done) }) }) })