Skip to content

Commit 299e71a

Browse files
author
Aaron Chambers
committed
Merge pull request #8 from LevelbossMike/add-tests
Add tests for lib/s3
2 parents 7ac7bed + e65b14c commit 299e71a

File tree

5 files changed

+340
-16
lines changed

5 files changed

+340
-16
lines changed

.travis.yml

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,7 @@ cache:
99
directories:
1010
- node_modules
1111

12-
env:
13-
- EMBER_TRY_SCENARIO=default
14-
- EMBER_TRY_SCENARIO=ember-release
15-
- EMBER_TRY_SCENARIO=ember-beta
16-
- EMBER_TRY_SCENARIO=ember-canary
17-
18-
matrix:
19-
fast_finish: true
20-
allow_failures:
21-
- env: EMBER_TRY_SCENARIO=ember-canary
22-
2312
before_install:
24-
- export PATH=/usr/local/phantomjs-2.0.0/bin:$PATH
2513
- "npm config set spin false"
2614
- "npm install -g npm@^2"
2715

@@ -31,4 +19,4 @@ install:
3119
- bower install
3220

3321
script:
34-
- ember try $EMBER_TRY_SCENARIO test
22+
- npm test

package.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"scripts": {
1010
"build": "ember build",
1111
"start": "ember server",
12-
"test": "ember try:testall"
12+
"test": "node tests/runner.js"
1313
},
1414
"repository": "https://github.com/LevelbossMike/ember-cli-deploy-s3-index",
1515
"engines": {
@@ -19,6 +19,8 @@
1919
"license": "MIT",
2020
"devDependencies": {
2121
"broccoli-asset-rev": "^2.1.2",
22+
"chai": "^3.3.0",
23+
"chai-as-promised": "^5.1.0",
2224
"ember-cli": "1.13.8",
2325
"ember-cli-app-version": "0.5.0",
2426
"ember-cli-content-security-policy": "0.4.0",
@@ -32,10 +34,12 @@
3234
"ember-cli-sri": "^1.0.3",
3335
"ember-cli-uglify": "^1.2.0",
3436
"ember-data": "1.13.8",
37+
"ember-disable-prototype-extensions": "^1.0.0",
3538
"ember-disable-proxy-controllers": "^1.0.0",
3639
"ember-export-application-global": "^1.0.3",
37-
"ember-disable-prototype-extensions": "^1.0.0",
38-
"ember-try": "0.0.6"
40+
"ember-try": "0.0.6",
41+
"glob": "^5.0.15",
42+
"mocha": "^2.3.3"
3943
},
4044
"keywords": [
4145
"ember-addon",

tests/runner.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
'use strict';
2+
3+
var glob = require('glob');
4+
var Mocha = require('mocha');
5+
6+
var mocha = new Mocha({
7+
reporter: 'spec'
8+
});
9+
10+
var arg = process.argv[2];
11+
var root = 'tests/';
12+
13+
function addFiles(mocha, files) {
14+
glob.sync(root + files).forEach(mocha.addFile.bind(mocha));
15+
}
16+
17+
addFiles(mocha, '/**/*-nodetest.js');
18+
19+
if (arg === 'all') {
20+
addFiles(mocha, '/**/*-nodetest-slow.js');
21+
}
22+
23+
mocha.run(function(failures) {
24+
process.on('exit', function() {
25+
process.exit(failures);
26+
});
27+
});

tests/unit/fixtures/test.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<p>Welcome to Ember!</p>

tests/unit/lib/s3-nodetest.js

Lines changed: 304 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,304 @@
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

Comments
 (0)