features/s3/step_definitions/objects.js (279 lines of code) (raw):
module.exports = function () {
this.When(/^I put "([^"]*)" to the(?: invalid)? key "([^"]*)"$/, function(data, key, next) {
var params = {Bucket: this.sharedBucket, Key: key, Body: data};
this.request('s3', 'putObject', params, next, false);
});
this.When(/^I get the object "([^"]*)"$/, function(key, next) {
var params = {Bucket: this.sharedBucket, Key: key};
this.request('s3', 'getObject', params, next, false);
});
this.When(/^I put (?:a |an )(empty|small|large|\d+KB|\d+MB) buffer to the key "([^"]*)"$/, function(size, key, next) {
var body = this.createBuffer(size);
var params = {Bucket: this.sharedBucket, Key: key, Body: body};
this.request('s3', 'putObject', params, next);
});
this.When(/^I put (?:a |an )(empty|small|large) file to the key "([^"]*)"$/, function(size, key, next) {
var fs = require('fs');
var filename = this.createFile(size, key);
var params = {Bucket: this.sharedBucket, Key: key, Body: fs.createReadStream(filename)};
this.request('s3', 'putObject', params, next);
});
this.When(/^I put "([^"]*)" to the key "([^"]*)" with ContentLength (\d+)$/, function(contents, key, contentLength, next) {
var params = {Bucket: this.sharedBucket, Key: key, Body: contents, ContentLength: parseInt(contentLength)};
this.s3nochecksums = new this.AWS.S3({computeChecksums: false});
this.request('s3nochecksums', 'putObject', params, next);
});
this.Then(/^the object "([^"]*)" should contain "([^"]*)"$/, function(key, contents, next) {
this.assert.equal(this.data.Body.toString().replace('\n', ''), contents);
next();
});
this.Then(/^the HTTP response should have a content length of (\d+)$/, function(contentLength, next) {
this.assert.equal(this.response.httpResponse.body.length, parseInt(contentLength));
next();
});
this.When(/^I copy the object "([^"]*)" to "([^"]*)"$/, function(key1, key2, next) {
var params = {
Bucket: this.sharedBucket, Key: key2, CopySource: '/' + this.sharedBucket + '/' + key1
};
this.request('s3', 'copyObject', params, next);
});
this.When(/^I delete the object "([^"]*)"$/, function(key, next) {
var params = {Bucket: this.sharedBucket, Key: key};
this.request('s3', 'deleteObject', params, next);
});
this.Then(/^the object "([^"]*)" should (not )?exist$/, function(key, shouldNotExist, next) {
var params = { Bucket: this.sharedBucket, Key: key };
this.eventually(next, function (retry) {
retry.condition = function() {
if (shouldNotExist) {
return this.error && this.error.code === 'NotFound';
} else {
return !this.error;
}
};
this.request('s3', 'headObject', params, retry, false);
});
});
this.When(/^I stream key "([^"]*)"$/, function(key, callback) {
var params = {Bucket: this.sharedBucket, Key: key};
var world = this;
this.result = '';
var s = this.service.getObject(params).createReadStream();
setTimeout(function() {
s.on('end', function() { callback(); });
s.on('data', function(d) { world.result += d.toString(); });
}, 2000); // delay streaming to ensure it is buffered
});
this.When(/^I stream2 key "([^"]*)"$/, function(key, callback) {
if (!require('stream').Readable) return callback();
var params = {Bucket: this.sharedBucket, Key: key};
var world = this;
this.result = '';
var stream = this.service.getObject(params).createReadStream();
setTimeout(function() {
stream.on('end', function() { callback(); });
stream.on('readable', function() {
var v = stream.read(); if (v) world.result += v;
});
}, 2000); // delay streaming to ensure it is buffered
});
this.Then(/^the streamed data should contain "([^"]*)"$/, function(data, callback) {
this.assert.equal(this.result.replace('\n', ''), data);
callback();
});
this.Then(/^the streamed data content length should equal (\d+)$/, function(length, callback) {
this.assert.equal(this.result.length, length);
callback();
});
this.When(/^I get a pre\-signed URL to GET the key "([^"]*)"$/, function(key, callback) {
var world = this;
this.s3.getSignedUrl('getObject', {Bucket: this.sharedBucket, Key: key}, function(err, url) {
world.signedUrl = url;
callback();
});
});
this.When(/^I access the URL via HTTP GET$/, function(callback) {
var world = this;
this.data = '';
require('https').get(this.signedUrl, function (res) {
res.on('data', function (chunk) {
world.data += chunk.toString();
}).on('end', callback);
}).on('error', callback.fail);
});
this.Given(/^I get a pre\-signed URL to PUT the key "([^"]*)"(?: with data "([^"]*)")?$/, function(key, body, callback) {
var world = this;
var params = {Bucket: this.sharedBucket, Key: key};
if (body) params.Body = body;
this.s3.getSignedUrl('putObject', params, function(err, url) {
world.signedUrl = url;
callback();
});
});
this.Given(/^I access the URL via HTTP PUT with data "([^"]*)"$/, function(body, callback) {
var world = this;
this.data = '';
var data = body;
var options = require('url').parse(this.signedUrl);
options.method = 'PUT';
options.headers = {'Content-Length': data.length};
require('https').request(options, function (res) {
res.on('data', function (chunk) {
world.data += chunk.toString();
}).on('end', callback);
}).on('error', callback.fail).end(data);
});
this.Given(
/^I create a presigned form to POST the key "([^"]*)" with the data "([^"]*)"$/,
function (key, data, callback) {
var world = this;
var boundary = this.postBoundary = '----WebKitFormBoundaryLL0mBKIuuLUKr7be';
var conditions = [
['content-length-range', data.length - 1, data.length + 1]
],
params = {
Bucket: this.sharedBucket,
Fields: {key: key},
Conditions: conditions
};
this.s3.createPresignedPost(params, function(err, postData) {
var body = Object.keys(postData.fields).reduce(function(body, fieldName) {
body += '--' + boundary + '\r\n';
body += 'Content-Disposition: form-data; name="' + fieldName + '"\r\n\r\n';
return body + postData.fields[fieldName] + '\r\n';
}, '');
body += '--' + world.postBoundary + '\r\n';
body += 'Content-Disposition: form-data; name="file"; filename="' + key + '"\r\n';
body += 'Content-Type: text/plain\r\n\r\n';
body += data + '\r\n';
body += '--' + world.postBoundary + '\r\n';
body += 'Content-Disposition: form-data; name="submit"\r\n';
body += 'Content-Type: text/plain\r\n\r\n';
body += 'submit\r\n';
body += '--' + world.postBoundary + '--\r\n';
world.postBody = body;
world.postAction = postData.url;
callback();
});
}
);
this.Given(/^I POST the form$/, function (callback) {
var world = this;
var options = require('url').parse(this.postAction);
options.method = 'POST';
options.headers = {
'Content-Type': 'multipart/form-data; boundary=' + this.postBoundary,
'Content-Length': this.postBody.length
};
require('https').request(options, function(res) {
res.on('data', function (chunk) {
world.data += chunk.toString();
}).on('end', callback);
})
.on('error', callback.fail)
.end(this.postBody);
});
this.Then(/^the HTTP response should equal "([^"]*)"$/, function(data, callback) {
this.assert.equal(this.data, data);
callback();
});
this.Then(/^the HTTP response should contain "([^"]*|)"$/, function(data, callback) {
this.assert.match(this.data, data);
callback();
});
this.Given(/^I setup the listObjects request for the bucket$/, function(callback) {
this.params = { Bucket: this.sharedBucket };
callback();
});
// progress events
this.When(/^I put (?:a |an )(empty|small|large|\d+KB|\d+MB) buffer to the key "([^"]*)" with progress events$/, function(size, key, callback) {
var self = this;
var body = self.createBuffer(size);
this.progress = [];
var req = this.s3.putObject({Bucket: this.sharedBucket, Key: key, Body: body});
req.on('httpUploadProgress', function (p) { self.progress.push(p); });
req.send(callback);
});
this.Then(/^more than (\d+) "([^"]*)" event should fire$/, function(numEvents, eventName, callback) {
this.assert.compare(this.progress.length, '>', numEvents);
callback();
});
this.Then(/^the "([^"]*)" value of the progress event should equal (\d+)MB$/, function(prop, mb, callback) {
this.assert.equal(this.progress[0][prop], mb * 1024 * 1024);
callback();
});
this.Then(/^the "([^"]*)" value of the first progress event should be greater than (\d+) bytes$/, function(prop, bytes, callback) {
this.assert.compare(this.progress[0][prop], '>', bytes);
callback();
});
this.When(/^I read the key "([^"]*)" with progress events$/, function(key, callback) {
var self = this;
this.progress = [];
var req = this.s3.getObject({Bucket: this.sharedBucket, Key: key});
req.on('httpDownloadProgress', function (p) { self.progress.push(p); });
req.send(callback);
});
this.When(/^I put "([^"]*)" to the private key "([^"]*)"$/, function(data, key, next) {
var params = {Bucket: this.sharedBucket, Key: key, Body: data, ACL: 'private'};
this.request('s3', 'putObject', params, next);
});
this.When(/^I put "([^"]*)" to the key "([^"]*)" with an AES key$/, function(data, key, next) {
var params = {
Bucket: this.sharedBucket,
Key: key,
Body: data,
SSECustomerAlgorithm: 'AES256',
SSECustomerKey: 'aaaabbbbccccddddaaaabbbbccccdddd'
};
this.request('s3', 'putObject', params, next);
});
this.When(/^I read the object "([^"]*)" with the AES key$/, function(key, next) {
var params = {
Bucket: this.sharedBucket,
Key: key,
SSECustomerAlgorithm: 'AES256',
SSECustomerKey: 'aaaabbbbccccddddaaaabbbbccccdddd'
};
this.request('s3', 'getObject', params, next);
});
this.Given(/^I generate the MD5 checksum of "([^"]*)"$/, function(data, next) {
this.sentContentMD5 = this.AWS.util.crypto.md5(data, 'base64');
next();
});
this.Then(/^the MD5 checksum of the response data should equal the generated checksum$/, function(next) {
var receivedContentMD5 = this.AWS.util.crypto.md5(this.data.Body.toString(), 'base64');
this.assert.equal(receivedContentMD5, this.sentContentMD5);
next();
});
this.Given(/^an empty bucket$/, function(next) {
var self = this;
var params = { Bucket: this.sharedBucket };
self.s3.listObjects(params, function(err, data) {
if (err) return next(err);
if (data.Contents.length > 0) {
params.Delete = { Objects: [] };
data.Contents.forEach(function (item) {
params.Delete.Objects.push({Key: item.Key});
});
self.request('s3', 'deleteObjects', params, next);
} else {
next();
}
});
});
this.Given(/^I use signatureVersion "([^"]*)"$/, function(signatureVersion, next) {
this.s3Slashes = new this.AWS.S3({signatureVersion: signatureVersion});
next();
});
this.When(/^I put "([^"]*)" to the key "([^"]*)" with bucket suffix "([^"]*)"$/, function(data, key, suffix, next) {
var world = this;
var params = {
Bucket: this.sharedBucket + suffix,
Key: key,
Body: data
};
this.s3Slashes.putObject(params, function(err, data) {
world.assert.equal(!!err, false);
next();
});
});
};