s3-tests.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. const assert = require('assert');
  2. const sinon = require('sinon');
  3. const proxyquire = require('proxyquire').noCallThru();
  4. function resolvedPromise(val) {
  5. return {
  6. promise: () => Promise.resolve(val)
  7. };
  8. }
  9. function rejectedPromise(err) {
  10. return {
  11. promise: () => Promise.reject(err)
  12. };
  13. }
  14. const s3Stub = {
  15. headObject: sinon.stub(),
  16. getObject: sinon.stub(),
  17. upload: sinon.stub(),
  18. deleteObject: sinon.stub()
  19. };
  20. const awsStub = {
  21. config: {
  22. update: sinon.stub()
  23. },
  24. S3: function() {
  25. return s3Stub;
  26. }
  27. };
  28. const S3Storage = proxyquire('../../server/storage/s3', {
  29. 'aws-sdk': awsStub
  30. });
  31. describe('S3Storage', function() {
  32. it('uses config.s3_bucket', function() {
  33. const s = new S3Storage({ s3_bucket: 'foo' });
  34. assert.equal(s.bucket, 'foo');
  35. });
  36. describe('length', function() {
  37. it('returns the ContentLength', async function() {
  38. s3Stub.headObject = sinon
  39. .stub()
  40. .returns(resolvedPromise({ ContentLength: 123 }));
  41. const s = new S3Storage({ s3_bucket: 'foo' });
  42. const len = await s.length('x');
  43. assert.equal(len, 123);
  44. sinon.assert.calledWithMatch(s3Stub.headObject, {
  45. Bucket: 'foo',
  46. Key: 'x'
  47. });
  48. });
  49. it('throws when id not found', async function() {
  50. const err = new Error();
  51. s3Stub.headObject = sinon.stub().returns(rejectedPromise(err));
  52. const s = new S3Storage({ s3_bucket: 'foo' });
  53. try {
  54. await s.length('x');
  55. assert.fail();
  56. } catch (e) {
  57. assert.equal(e, err);
  58. }
  59. });
  60. });
  61. describe('getStream', function() {
  62. it('returns a Stream object', function() {
  63. const stream = {};
  64. s3Stub.getObject = sinon
  65. .stub()
  66. .returns({ createReadStream: () => stream });
  67. const s = new S3Storage({ s3_bucket: 'foo' });
  68. const result = s.getStream('x');
  69. assert.equal(result, stream);
  70. sinon.assert.calledWithMatch(s3Stub.getObject, {
  71. Bucket: 'foo',
  72. Key: 'x'
  73. });
  74. });
  75. });
  76. describe('set', function() {
  77. it('calls s3.upload', async function() {
  78. const file = { on: sinon.stub() };
  79. s3Stub.upload = sinon.stub().returns(resolvedPromise());
  80. const s = new S3Storage({ s3_bucket: 'foo' });
  81. await s.set('x', file);
  82. sinon.assert.calledWithMatch(s3Stub.upload, {
  83. Bucket: 'foo',
  84. Key: 'x',
  85. Body: file
  86. });
  87. });
  88. it('aborts upload if limit is hit', async function() {
  89. const file = {
  90. on: (ev, fn) => fn()
  91. };
  92. const abort = sinon.stub();
  93. const err = new Error('limit');
  94. s3Stub.upload = sinon.stub().returns({
  95. promise: () => Promise.reject(err),
  96. abort
  97. });
  98. const s = new S3Storage({ s3_bucket: 'foo' });
  99. try {
  100. await s.set('x', file);
  101. assert.fail();
  102. } catch (e) {
  103. assert.equal(e.message, 'limit');
  104. sinon.assert.calledOnce(abort);
  105. }
  106. });
  107. it('throws when s3.upload fails', async function() {
  108. const file = {
  109. on: sinon.stub()
  110. };
  111. const err = new Error();
  112. s3Stub.upload = sinon.stub().returns(rejectedPromise(err));
  113. const s = new S3Storage({ s3_bucket: 'foo' });
  114. try {
  115. await s.set('x', file);
  116. assert.fail();
  117. } catch (e) {
  118. assert.equal(e, err);
  119. }
  120. });
  121. });
  122. describe('del', function() {
  123. it('calls s3.deleteObject', async function() {
  124. s3Stub.deleteObject = sinon.stub().returns(resolvedPromise(true));
  125. const s = new S3Storage({ s3_bucket: 'foo' });
  126. const result = await s.del('x');
  127. assert.equal(result, true);
  128. sinon.assert.calledWithMatch(s3Stub.deleteObject, {
  129. Bucket: 'foo',
  130. Key: 'x'
  131. });
  132. });
  133. });
  134. describe('ping', function() {
  135. it('calls s3.headBucket', async function() {
  136. s3Stub.headBucket = sinon.stub().returns(resolvedPromise(true));
  137. const s = new S3Storage({ s3_bucket: 'foo' });
  138. const result = await s.ping();
  139. assert.equal(result, true);
  140. sinon.assert.calledWithMatch(s3Stub.headBucket, { Bucket: 'foo' });
  141. });
  142. });
  143. });