|
| 1 | +var assert = require('ember-cli/tests/helpers/assert'); |
| 2 | + |
| 3 | +describe('s3', function() { |
| 4 | + var S3, mockUi, s3Client, plugin, subject, options, listParams, headParams, copyParams; |
| 5 | + |
| 6 | + before(function() { |
| 7 | + S3 = require('../../../lib/s3'); |
| 8 | + }); |
| 9 | + |
| 10 | + beforeEach(function() { |
| 11 | + revisionsData = { |
| 12 | + Contents: [ |
| 13 | + { Key: 'test.html:123', LastModified: new Date('September 27, 2015 01:00:00'), ETag: '123' }, |
| 14 | + { Key: 'test.html:456', LastModified: new Date('September 27, 2015 02:00:00') , ETag: '456' } |
| 15 | + ] |
| 16 | + }; |
| 17 | + |
| 18 | + currentData = { Key: 'test.html', lastModified: new Date('September 27, 2015 01:30:00'), ETag: '123' }; |
| 19 | + |
| 20 | + s3Client = { |
| 21 | + putObject: function(params, cb) { |
| 22 | + cb(); |
| 23 | + }, |
| 24 | + |
| 25 | + listObjects: function(params, cb) { |
| 26 | + listParams = params; |
| 27 | + cb(undefined, revisionsData); |
| 28 | + }, |
| 29 | + |
| 30 | + headObject: function(params, cb) { |
| 31 | + headParams = params; |
| 32 | + cb(undefined, currentData); |
| 33 | + }, |
| 34 | + |
| 35 | + copyObject: function(params, cb) { |
| 36 | + copyParams = params; |
| 37 | + cb(); |
| 38 | + } |
| 39 | + }; |
| 40 | + mockUi = { |
| 41 | + messages: [], |
| 42 | + write: function() {}, |
| 43 | + writeLine: function(message) { |
| 44 | + this.messages.push(message); |
| 45 | + } |
| 46 | + }; |
| 47 | + plugin = { |
| 48 | + ui: mockUi, |
| 49 | + readConfig: function(propertyName) { |
| 50 | + if (propertyName === 's3Client') { |
| 51 | + return s3Client; |
| 52 | + } |
| 53 | + }, |
| 54 | + log: function(message, opts) { |
| 55 | + this.ui.write('| '); |
| 56 | + this.ui.writeLine('- ' + message); |
| 57 | + } |
| 58 | + }; |
| 59 | + subject = new S3({ |
| 60 | + plugin: plugin |
| 61 | + }); |
| 62 | + }); |
| 63 | + |
| 64 | + describe('#upload', function() { |
| 65 | + var s3Params; |
| 66 | + var filePattern = 'test.html'; |
| 67 | + var revisionKey = 'some-revision-key'; |
| 68 | + var bucket = 'some-bucket'; |
| 69 | + var prefix = 'my-app'; |
| 70 | + |
| 71 | + beforeEach(function() { |
| 72 | + options = { |
| 73 | + bucket: bucket, |
| 74 | + prefix: '', |
| 75 | + filePattern: filePattern, |
| 76 | + revisionKey: revisionKey, |
| 77 | + filePath: 'tests/unit/fixtures/test.html' |
| 78 | + }; |
| 79 | + |
| 80 | + s3Client.putObject = function(params, cb) { |
| 81 | + s3Params = params; |
| 82 | + cb(); |
| 83 | + }; |
| 84 | + }); |
| 85 | + |
| 86 | + it('resolves if upload succeeds', function() { |
| 87 | + var promise = subject.upload(options); |
| 88 | + |
| 89 | + return assert.isFulfilled(promise) |
| 90 | + .then(function() { |
| 91 | + var expectLogOutput = '- ✔ '+filePattern+':'+revisionKey; |
| 92 | + |
| 93 | + assert.equal(mockUi.messages.length, 1, 'Logs one line'); |
| 94 | + assert.equal(mockUi.messages[0], expectLogOutput, 'Upload log output correct'); |
| 95 | + }); |
| 96 | + }); |
| 97 | + |
| 98 | + it('rejects if upload fails', function() { |
| 99 | + s3Client.putObject = function(params, cb) { |
| 100 | + cb('error uploading'); |
| 101 | + }; |
| 102 | + |
| 103 | + var promise = subject.upload(options); |
| 104 | + |
| 105 | + return assert.isRejected(promise); |
| 106 | + }); |
| 107 | + |
| 108 | + it('passes expected parameters to the used s3-client', function() { |
| 109 | + |
| 110 | + var promise = subject.upload(options); |
| 111 | + |
| 112 | + return assert.isFulfilled(promise) |
| 113 | + .then(function() { |
| 114 | + var expectedKey = filePattern+':'+revisionKey; |
| 115 | + var defaultACL = 'public-read'; |
| 116 | + |
| 117 | + assert.equal(s3Params.Bucket, bucket, 'Bucket passed correctly'); |
| 118 | + assert.equal(s3Params.Key, expectedKey, 'Key passed correctly'); |
| 119 | + assert.equal(s3Params.ACL, defaultACL, 'ACL defaults to `public-read`'); |
| 120 | + assert.equal(s3Params.ContentType, 'text/html', 'contentType is set to `text/html`'); |
| 121 | + assert.equal(s3Params.CacheControl, 'max-age=0, no-cache', 'cacheControl set correctly'); |
| 122 | + }); |
| 123 | + }); |
| 124 | + |
| 125 | + it('allows `prefix` option to be passed to customize upload-path', function() { |
| 126 | + var prefix = 'my-app'; |
| 127 | + |
| 128 | + options.prefix = prefix; |
| 129 | + var promise = subject.upload(options); |
| 130 | + |
| 131 | + return assert.isFulfilled(promise) |
| 132 | + .then(function() { |
| 133 | + var expectLogOutput = '- ✔ '+prefix+'/'+filePattern+':'+revisionKey; |
| 134 | + var expectedKey = prefix+'/'+filePattern+':'+revisionKey; |
| 135 | + |
| 136 | + assert.equal(mockUi.messages[0], expectLogOutput, 'Prefix is included in log output'); |
| 137 | + assert.equal(s3Params.Key, expectedKey, 'Key (including prefix) passed correctly'); |
| 138 | + }); |
| 139 | + }); |
| 140 | + |
| 141 | + it('allows `acl` option to be passed to customize the used ACL', function() { |
| 142 | + var acl = 'authenticated-read'; |
| 143 | + |
| 144 | + options.acl = acl; |
| 145 | + var promise = subject.upload(options); |
| 146 | + |
| 147 | + return assert.isFulfilled(promise) |
| 148 | + .then(function() { |
| 149 | + var expectLogOutput = '- ✔ '+prefix+'/'+filePattern+':'+revisionKey; |
| 150 | + var expectedKey = prefix+'/'+filePattern+':'+revisionKey; |
| 151 | + |
| 152 | + assert.equal(s3Params.ACL, acl, 'acl passed correctly'); |
| 153 | + }); |
| 154 | + }); |
| 155 | + }); |
| 156 | + |
| 157 | + describe('#fetchRevisions', function() { |
| 158 | + var bucket = 'some-bucket'; |
| 159 | + var prefix = ''; |
| 160 | + var filePattern = 'test.html'; |
| 161 | + |
| 162 | + beforeEach(function() { |
| 163 | + options = { |
| 164 | + bucket: bucket, |
| 165 | + prefix: prefix, |
| 166 | + filePattern: filePattern |
| 167 | + }; |
| 168 | + }); |
| 169 | + |
| 170 | + it('returns an array of uploaded revisions in `{ revision: revisionKey, timestamp: timestamp, active: active }` format sorted by date in descending order', function() { |
| 171 | + var promise = subject.fetchRevisions(options); |
| 172 | + var expected = [ |
| 173 | + { revision: '456', timestamp: new Date('September 27, 2015 02:00:00') , active: false }, |
| 174 | + { revision: '123', timestamp: new Date('September 27, 2015 01:00:00'), active: true } |
| 175 | + ]; |
| 176 | + |
| 177 | + return assert.isFulfilled(promise) |
| 178 | + .then(function(revisionsData) { |
| 179 | + return assert.deepEqual(revisionsData, expected, 'Revisions data correct'); |
| 180 | + }); |
| 181 | + }); |
| 182 | + |
| 183 | + it('sends correct parameters for s3#listObjects and s3#headObject', function() { |
| 184 | + var expectePrefix = filePattern+':'; |
| 185 | + |
| 186 | + var promise = subject.fetchRevisions(options); |
| 187 | + |
| 188 | + return assert.isFulfilled(promise) |
| 189 | + .then(function() { |
| 190 | + assert.equal(listParams.Bucket, bucket, 'list Bucket set correctly'); |
| 191 | + assert.equal(listParams.Prefix, expectePrefix, 'list Prefix set correctly'); |
| 192 | + assert.equal(headParams.Bucket, bucket, 'head Bucket set correctly'); |
| 193 | + assert.equal(headParams.Key, filePattern, 'head Key set correctly'); |
| 194 | + }); |
| 195 | + }); |
| 196 | + |
| 197 | + it('changes parameters sent to s3#listObjects and s3#headObject when setting the `prefix`-option', function() { |
| 198 | + var prefix = 'my-app'; |
| 199 | + var expectedPrefix = 'my-app/'+filePattern+':'; |
| 200 | + var expectedKey = 'my-app/'+filePattern; |
| 201 | + |
| 202 | + options.prefix = prefix; |
| 203 | + var promise = subject.fetchRevisions(options); |
| 204 | + |
| 205 | + return assert.isFulfilled(promise) |
| 206 | + .then(function() { |
| 207 | + assert.equal(listParams.Prefix, expectedPrefix); |
| 208 | + assert.equal(headParams.Key, expectedKey); |
| 209 | + }); |
| 210 | + }); |
| 211 | + }); |
| 212 | + |
| 213 | + describe('#activate', function() { |
| 214 | + var bucket = 'some-bucket'; |
| 215 | + var prefix = ''; |
| 216 | + var filePattern = 'test.html'; |
| 217 | + |
| 218 | + beforeEach(function() { |
| 219 | + options = { |
| 220 | + bucket: bucket, |
| 221 | + prefix: prefix, |
| 222 | + filePattern: filePattern |
| 223 | + }; |
| 224 | + }); |
| 225 | + |
| 226 | + describe('with a valid revisionKey', function() { |
| 227 | + beforeEach(function() { |
| 228 | + options.revisionKey = '456'; |
| 229 | + }); |
| 230 | + |
| 231 | + it('resolves when passing an existing revisionKey', function() { |
| 232 | + var promise = subject.activate(options); |
| 233 | + |
| 234 | + return assert.isFulfilled(promise); |
| 235 | + }); |
| 236 | + |
| 237 | + it('logs to the console when activation was successful', function() { |
| 238 | + var promise = subject.activate(options); |
| 239 | + var expectedOutput = '- ✔ '+filePattern+':456 => '+filePattern; |
| 240 | + |
| 241 | + return assert.isFulfilled(promise) |
| 242 | + .then(function() { |
| 243 | + assert.equal(mockUi.messages.length, 1, 'Logs one line'); |
| 244 | + assert.equal(mockUi.messages[0], expectedOutput, 'Activation output correct'); |
| 245 | + }); |
| 246 | + }); |
| 247 | + |
| 248 | + it('passes correct parameters to s3#copyObject', function() { |
| 249 | + var promise = subject.activate(options); |
| 250 | + |
| 251 | + return assert.isFulfilled(promise) |
| 252 | + .then(function() { |
| 253 | + assert.equal(copyParams.Bucket, bucket); |
| 254 | + assert.equal(copyParams.ACL, 'public-read'); |
| 255 | + assert.equal(copyParams.CopySource, bucket+'%2F'+filePattern+'%3A456'); |
| 256 | + assert.equal(copyParams.Key, filePattern); |
| 257 | + }); |
| 258 | + }); |
| 259 | + |
| 260 | + it('allows `prefix` option to be passed to customize Key and CopySource passed to s3#copyObject', function() { |
| 261 | + var prefix = 'my-app'; |
| 262 | + revisionsData = { |
| 263 | + Contents: [ |
| 264 | + { Key: prefix+'/test.html:123', LastModified: new Date('September 27, 2015 01:00:00'), ETag: '123' }, |
| 265 | + { Key: prefix+'/test.html:456', LastModified: new Date('September 27, 2015 02:00:00') , ETag: '456' } |
| 266 | + ] |
| 267 | + }; |
| 268 | + |
| 269 | + options.prefix = prefix; |
| 270 | + var promise = subject.activate(options); |
| 271 | + |
| 272 | + return assert.isFulfilled(promise) |
| 273 | + .then(function() { |
| 274 | + assert.equal(copyParams.Key, prefix+'/'+filePattern); |
| 275 | + assert.equal(copyParams.CopySource, bucket+'%2F'+prefix+'%2F'+filePattern+'%3A456'); |
| 276 | + }); |
| 277 | + }); |
| 278 | + |
| 279 | + it('allows `acl` option to be passed to customize the used ACL', function() { |
| 280 | + var acl = 'authenticated-read'; |
| 281 | + |
| 282 | + options.acl = acl; |
| 283 | + var promise = subject.activate(options); |
| 284 | + |
| 285 | + return assert.isFulfilled(promise) |
| 286 | + .then(function() { |
| 287 | + assert.equal(copyParams.ACL, acl); |
| 288 | + }); |
| 289 | + }); |
| 290 | + }); |
| 291 | + |
| 292 | + describe('with an invalid revision key', function() { |
| 293 | + beforeEach(function() { |
| 294 | + options.revisionKey = '457'; |
| 295 | + }); |
| 296 | + |
| 297 | + it('rejects when passing an non-existing revisionKey', function() { |
| 298 | + var promise = subject.activate(options); |
| 299 | + |
| 300 | + return assert.isRejected(promise); |
| 301 | + }); |
| 302 | + }); |
| 303 | + }); |
| 304 | +}); |
0 commit comments