var fs = require('fs'); var path = require('path'); var COS = require('../index'); var request = require('request'); var util = require('../demo/util'); var config = require('../demo/config'); var Writable = require('stream').Writable; if (process.env.AppId) { config = { SecretId: process.env.SecretId, SecretKey: process.env.SecretKey, Bucket: process.env.Bucket, // Bucket 格式:test-1250000000 Region: process.env.Region } } var cos = new COS({ SecretId: config.SecretId, SecretKey: config.SecretKey, ChunkParallelLimit: 10, IgnoreRegionFormat: true, Protocol: 'http:', ServiceDomain: 'http://cos.default.xxx.com', Domain: 'http://{{Bucket}}-{{AppId}}.cos.{{Region}}.xxx.com', }); var AppId = config.AppId; var Bucket = config.Bucket; var BucketShortName = Bucket; var BucketLongName = Bucket + '-' + AppId; var match = config.Bucket.match(/^(.+)-(\d+)$/); if (match) { BucketLongName = config.Bucket; // Bucket 格式:test-1250000000 BucketShortName = match[1]; AppId = match[2]; } var assert = require("assert"); assert.ok = assert; function prepareBucket() { return new Promise(function (resolve, reject) { cos.putBucket({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region }, function (err, data) { resolve(); }); }); } function prepareBigObject() { return new Promise(function (resolve, reject) { // 创建测试文件 var filename = 'bigger.zip'; var filepath = path.resolve(__dirname, filename); var put = function () { // 调用方法 cos.putObject({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, Key: filename, Body: fs.createReadStream(filepath), ContentLength: fs.statSync(filepath).size, }, function (err, data) { err ? reject(err) : resolve() }); }; if (fs.existsSync(filepath)) { put(); } else { util.createFile(filepath, 1024 * 1024 * 10, put); } }); } function comparePlainObject(a, b) { a instanceof Array && a.sort(); b instanceof Array && b.sort(); // var sep = '||||||'; // if (a instanceof Array && b instanceof Array) { // return a.join(sep) === b.join(sep); // } if (Object.keys(a).length !== Object.keys(b).length) { return false; } for (var key in a) { if (typeof a[key] === 'object' && typeof b[key] === 'object') { if (!comparePlainObject(a[key], b[key])) { return false; } } else if (a[key] != b[key]) { return false; } } return true; } describe('getService()', function () { this.timeout(60000); it('能正常列出 Bucket', function (done) { prepareBucket().then(function () { cos.getService(function (err, data) { var hasBucket = false; data.Buckets && data.Buckets.forEach(function (item) { if (item.Name === BucketLongName && (item.Location === config.Region || !item.Location)) { hasBucket = true; } }); assert.equal(true, hasBucket); done(); }); }).catch(function () { }); }); }); describe('getAuth()', function () { this.timeout(60000); it('通过获取签名能正常获取文件', function (done) { var content = Date.now().toString(); var key = '1.txt'; prepareBucket().then(function () { cos.putObject({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, Key: key, Body: Buffer.from(content) }, function (err, data) { var auth = cos.getAuth({ Method: 'get', Key: key }); var link = 'http://' + BucketLongName + '.cos.' + config.Region + '.yun.ccb.com/' + key + '?sign=' + encodeURIComponent(auth); request(link, function (err, response, body) { assert.ok(response.statusCode === 200); assert.ok(body === content); done(); }); }); }).catch(function () { }); }); }); describe('auth check', function () { this.timeout(60000); it('auth check !\'$()*', function (done) { cos.getBucket({ Bucket: config.Bucket, Region: config.Region, Prefix: 'aksjhdlash sajlhj!@#$%^&*()_+=-[]{}\';:"/.<>?.,??sadasd#/.,/~`', Headers: { // !'$()* // 包含这几个特殊字符就出错 'x-cos-test': 'aksjhdlash sajlhj!@#$%^&*()_+=-[]{}\';:\"/.<>?.,??sadasd#/.,/~`', }, }, function (err, data) { assert.ok(!err); done(); }); }); }); describe('putBucket()', function () { this.timeout(60000); var NewBucket = 'test-put-bucket-' + AppId; it('正常创建 bucket', function (done) { cos.putBucket({ Bucket: NewBucket, Region: config.Region }, function (err, data) { assert.equal(NewBucket + '.cos.' + config.Region + '.yun.ccb.com', data.Location); cos.headBucket({ Bucket: NewBucket, Region: config.Region }, function (err, data) { assert.ok(data); cos.deleteBucket({ Bucket: NewBucket, Region: config.Region }, function (err, data) { done(); }); }); }); }); }); describe('getBucket()', function () { this.timeout(60000); it('正常获取 bucket 里的文件列表', function (done) { prepareBucket().then(function () { cos.getBucket({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region }, function (err, data) { assert.equal(true, data.Name === BucketLongName); assert.equal(data.Contents.constructor, Array); done(); }); }).catch(function () { assert.equal(false); done(); }); }); }); describe('putObject()', function () { this.timeout(60000); var filename = '1.txt'; var filepath = path.resolve(__dirname, filename); var getObjectContent = function (callback) { var objectContent = Buffer.from([]); var outputStream = new Writable({ write: function (chunk, encoding, callback) { objectContent = Buffer.concat([objectContent, chunk]); } }); setTimeout(function () { cos.getObject({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, Key: filename, Output: outputStream }, function (err, data) { var content = objectContent.toString(); callback(content); }); }, 2000); }; it('fs.createReadStream 创建 object', function (done) { var content = Date.now().toString(); fs.writeFileSync(filepath, content); var lastPercent = 0; cos.putObject({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, Key: filename, Body: fs.createReadStream(filepath), ContentLength: fs.statSync(filepath).size, onProgress: function (processData) { lastPercent = processData.percent; }, }, function (err, data) { if (err) throw err; assert.ok(data.ETag.length > 0); fs.unlinkSync(filepath); getObjectContent(function (objectContent) { assert.ok(objectContent === content); done(); // cos.putObjectCopy({ // Bucket: config.Bucket, // Bucket 格式:test-1250000000 // Region: config.Region, // //ServerSideEncryption: 'AES256', // Key: '1.copy.text', // CopySource: config.Bucket + '.cos.' + config.Region + '.yun.ccb.com/' + filename, // Bucket 格式:test-1250000000 // }, function (err, data) { // assert.ok(!err); // assert.ok(data.ETag.length > 0); // done(); // }); }); }); }); it('fs.readFileSync 创建 object', function (done) { var content = Date.now().toString(); fs.writeFileSync(filepath, content); var lastPercent = 0; cos.putObject({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, Key: filename, Body: fs.readFileSync(filepath), onProgress: function (processData) { lastPercent = processData.percent; }, }, function (err, data) { if (err) throw err; assert.ok(data.ETag.length > 0); fs.unlinkSync(filepath); getObjectContent(function (objectContent) { assert.ok(objectContent === content); done(); }); }); }); it('捕获输入流异常', function (done) { var filename = 'big.zip'; var filepath = path.resolve(__dirname, filename); var put = function () { var Body = fs.createReadStream(filepath); setTimeout(function () { Body.emit('error', new Error('some error')) }, 1000); cos.putObject({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, Key: filename, Body: Body, ContentLength: fs.statSync(filepath).size, }, function (err, data) { fs.unlinkSync(filepath); done(); }); }; if (fs.existsSync(filepath)) { put(); } else { util.createFile(filepath, 5 << 20, put); } }); it('putObject(),buffer', function (done) { var content = Buffer.from('中文_' + Date.now()); cos.putObject({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, Key: '1.txt', Body: content, }, function (err, data) { var ETag = data.ETag; assert.ok(!err && ETag); cos.getObject({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, Key: filename }, function (err, data) { assert.ok(data.Body && data.Body.toString() === content.toString() && (data.headers && data.headers.etag) === ETag); done(); }); }); }); it('putObject(),buffer,empty', function (done) { var content = Buffer.from(''); cos.putObject({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, Key: '1.txt', Body: content, }, function (err, data) { var ETag = data.ETag; assert.ok(!err && ETag); cos.getObject({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, Key: filename }, function (err, data) { assert.ok(data.Body && data.Body.toString() === content.toString() && (data.headers && data.headers.etag) === ETag); done(); }); }); }); it('putObject(),string', function (done) { var content = '中文_' + Date.now(); cos.putObject({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, Key: '1.txt', Body: content, }, function (err, data) { var ETag = data.ETag; assert.ok(!err && ETag); cos.getObject({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, Key: filename }, function (err, data) { assert.ok(data.Body && data.Body.toString() === content.toString() && (data.headers && data.headers.etag) === ETag); done(); }); }); }); it('putObject(),string,empty', function (done) { var content = ''; cos.putObject({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, Key: '1.txt', Body: content, }, function (err, data) { var ETag = data.ETag; assert.ok(!err && ETag); cos.getObject({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, Key: filename }, function (err, data) { assert.ok(data.Body && data.Body.toString() === content && (data.headers && data.headers.etag) === ETag); done(); }); }); }); }); describe('getObject()', function () { this.timeout(60000); it('stream', function (done) { var key = '1.txt'; var objectContent = Buffer.from([]); var outputStream = new Writable({ write: function (chunk, encoding, callback) { objectContent = Buffer.concat([objectContent, chunk]); } }); var content = Date.now().toString(36); cos.putObject({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, Key: key, Body: Buffer.from(content) }, function (err, data) { setTimeout(function () { cos.getObject({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, Key: key, Output: outputStream }, function (err, data) { if (err) throw err; objectContent = objectContent.toString(); assert.ok(data.headers['content-length'] === '' + content.length); assert.ok(objectContent === content); cos.headObject({ Bucket: config.Bucket, Region: config.Region, Key: key }, function (err, data) { assert.ok(!err); done(); }); }); }, 2000); }); }); it('body', function (done) { var key = '1.txt'; var content = Date.now().toString(); cos.putObject({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, Key: key, Body: Buffer.from(content) }, function (err, data) { setTimeout(function () { cos.getObject({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, Key: key }, function (err, data) { if (err) throw err; var objectContent = data.Body.toString(); assert.ok(data.headers['content-length'] === '' + content.length); assert.ok(objectContent === content); done(); }); }, 2000); }); }); }); describe('putObjectCopy()', function () { this.timeout(60000); var fileName = '1.txt'; it('正常复制 object', function (done) { cos.putObjectCopy({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, Key: '1.copy.txt', CopySource: config.Bucket + '.cos.' + config.Region + '.yun.ccb.com/' + fileName, }, function (err, data) { assert.ok(!err); assert.ok(data.ETag.length > 0); done(); }); }); it('捕获 object 异常', function (done) { var errFileName = '12345.txt'; cos.putObjectCopy({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, Key: '1.copy.txt', CopySource: config.Bucket + '.cos.' + config.Region + '.yun.ccb.com/' + errFileName, }, function (err, data) { assert.equal(true, err.statusCode === 404); assert.equal(true, err.error.Code === 'NoSuchKey') done(); }); }); }); describe('sliceCopyFile()', function () { this.timeout(60000); var fileName = 'bigger.zip'; var filepath = path.resolve(__dirname, fileName); var Key = 'bigger.copy.zip'; it('正常分片复制 object', function (done) { prepareBigObject().then(function () { cos.sliceCopyFile({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, Key: Key, CopySource: config.Bucket + '.cos.' + config.Region + '.yun.ccb.com/'+ fileName, SliceSize: 5 * 1024 * 1024, },function (err, data) { if (err) throw err; assert.ok(data.ETag.length > 0); fs.unlinkSync(filepath); done(); }); }).catch(function (err) { assert.equal(false); done(); }); }); it('单片复制 object', function (done) { prepareBigObject().then(function () { cos.sliceCopyFile({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, Key: Key, CopySource: config.Bucket + '.cos.' + config.Region + '.yun.ccb.com/'+ fileName, SliceSize: 10 * 1024 * 1024, },function (err,data) { if (err) throw err; assert.ok(data.ETag.length > 0); fs.unlinkSync(filepath); done(); }); }).catch(function () { assert.equal(false); done(); }); }); }); describe('sliceUploadFile()', function () { this.timeout(120000); it('正常分片上传 object', function (done) { var filename = '3mb.zip'; var filepath = path.resolve(__dirname, filename); var put = function () { var lastPercent = 0; cos.sliceUploadFile({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, Key: filename, FilePath: filepath, SliceSize: 1024 * 1024, AsyncLimit: 5, onProgress: function (progressData) { lastPercent = progressData.percent; }, }, function (err, data) { assert.equal(true, data.ETag.length > 0 && lastPercent === 1); fs.unlinkSync(filepath); done(); }); }; if (fs.existsSync(filepath)) { put(); } else { util.createFile(filepath, 3 * 1024 * 1024, put); } }); }); (function () { var AccessControlPolicy = { "Owner": { "ID": 'qcs::cam::uin/100004603008:uin/100004603008' // 100004603008 是 QQ 号 }, "Grants": [{ "Grantee": { "ID": "qcs::cam::uin/100004603008:uin/100004603008", // 100004603008 是 QQ 号 }, "Permission": "READ" }] }; var AccessControlPolicy2 = { "Owner": { "ID": 'qcs::cam::uin/100004603008:uin/100004603008' // 100004603008 是 QQ 号 }, "Grant": { "Grantee": { "ID": "qcs::cam::uin/100004603008:uin/100004603008", // 100004603008 是 QQ 号 }, "Permission": "READ" } }; describe('BucketAcl', function () { this.timeout(60000); it('putBucketAcl() header ACL:private', function (done) { cos.putBucketAcl({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, ACL: 'private' }, function (err, data) { assert.ok(!err); cos.getBucketAcl({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region }, function (err, data) { AccessControlPolicy.Owner.ID = data.Owner.ID; AccessControlPolicy2.Owner.ID = data.Owner.ID; assert.ok(data.ACL === 'private' || data.ACL === 'default'); done(); }); }); }); it('putBucketAcl() header ACL:public-read', function (done) { cos.putBucketAcl({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, ACL: 'public-read', }, function (err, data) { assert.ok(!err); cos.getBucketAcl({Bucket: config.Bucket, Region: config.Region}, function (err, data) { // Bucket 格式:test-1250000000 assert.ok(data.ACL === 'public-read'); done(); }); }); }); it('putBucketAcl() header ACL:public-read-write', function (done) { cos.putBucketAcl({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, ACL: 'public-read-write', }, function (err, data) { assert.ok(!err); cos.getBucketAcl({Bucket: config.Bucket, Region: config.Region}, function (err, data) { // Bucket 格式:test-1250000000 assert.ok(data.ACL === 'public-read-write'); done(); }); }); }); it('putBucketAcl() header GrantRead:1001,1002', function (done) { var GrantRead = 'id="qcs::cam::uin/1001:uin/1001", id="qcs::cam::uin/1002:uin/1002"'; cos.putBucketAcl({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, GrantRead: GrantRead, }, function (err, data) { assert.ok(!err); cos.getBucketAcl({Bucket: config.Bucket, Region: config.Region}, function (err, data) { // Bucket 格式:test-1250000000 assert.ok(data.GrantRead = GrantRead); done(); }); }); }); it('putBucketAcl() header GrantWrite:1001,1002', function (done) { var GrantWrite = 'id="qcs::cam::uin/1001:uin/1001", id="qcs::cam::uin/1002:uin/1002"'; cos.putBucketAcl({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, GrantWrite: GrantWrite, }, function (err, data) { assert.ok(!err); cos.getBucketAcl({Bucket: config.Bucket, Region: config.Region}, function (err, data) { // Bucket 格式:test-1250000000 assert.ok(data.GrantWrite = GrantWrite); done(); }); }); }); it('putBucketAcl() header GrantFullControl:1001,1002', function (done) { var GrantFullControl = 'id="qcs::cam::uin/1001:uin/1001", id="qcs::cam::uin/1002:uin/1002"'; cos.putBucketAcl({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, GrantFullControl: GrantFullControl, }, function (err, data) { assert.ok(!err); cos.getBucketAcl({Bucket: config.Bucket, Region: config.Region}, function (err, data) { // Bucket 格式:test-1250000000 assert.ok(data.GrantFullControl = GrantFullControl); done(); }); }); }); it('putBucketAcl() header ACL:public-read, GrantFullControl:1001,1002', function (done) { var GrantFullControl = 'id="qcs::cam::uin/1001:uin/1001", id="qcs::cam::uin/1002:uin/1002"'; cos.putBucketAcl({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, GrantFullControl: GrantFullControl, ACL: 'public-read', }, function (err, data) { assert.ok(!err); cos.getBucketAcl({Bucket: config.Bucket, Region: config.Region}, function (err, data) { // Bucket 格式:test-1250000000 assert.ok(data.GrantFullControl = GrantFullControl); assert.ok(data.ACL === 'public-read'); done(); }); }); }); it('putBucketAcl() xml', function (done) { cos.putBucketAcl({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, AccessControlPolicy: AccessControlPolicy, }, function (err, data) { assert.ok(!err); cos.getBucketAcl({Bucket: config.Bucket, Region: config.Region}, function (err, data) { // Bucket 格式:test-1250000000 assert.ok(data.Grants.length === 1); assert.ok(data.Grants[0] && data.Grants[0].Grantee.ID === 'qcs::cam::uin/100004603008:uin/100004603008', '设置 AccessControlPolicy ID 正确'); assert.ok(data.Grants[0] && data.Grants[0].Permission === 'READ', '设置 AccessControlPolicy Permission 正确'); done(); }); }); }); it('putBucketAcl() xml2', function (done) { cos.putBucketAcl({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, AccessControlPolicy: AccessControlPolicy2, }, function (err, data) { assert.ok(!err); cos.getBucketAcl({Bucket: config.Bucket, Region: config.Region}, function (err, data) { // Bucket 格式:test-1250000000 assert.ok(data.Grants.length === 1); assert.ok(data.Grants[0] && data.Grants[0].Grantee.ID === 'qcs::cam::uin/100004603008:uin/100004603008'); assert.ok(data.Grants[0] && data.Grants[0].Permission === 'READ'); done(); }); }); }); it('putBucketAcl() decodeAcl', function (done) { cos.getBucketAcl({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region }, function (err, data) { cos.putBucketAcl({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, GrantFullControl: data.GrantFullControl, GrantWrite: data.GrantWrite, GrantRead: data.GrantRead, ACL: data.ACL, }, function (err, data) { assert.ok(data); done(); }); }); }); }); })(); (function () { var AccessControlPolicy = { "Owner": { "ID": 'qcs::cam::uin/100004603008:uin/100004603008' // 100004603008 是 QQ 号 }, "Grants": [{ "Grantee": { "ID": "qcs::cam::uin/100004603008:uin/100004603008", // 100004603008 是 QQ 号 }, "Permission": "READ" }] }; var AccessControlPolicy2 = { "Owner": { "ID": 'qcs::cam::uin/100004603008:uin/100004603008' // 100004603008 是 QQ 号 }, "Grant": { "Grantee": { "ID": "qcs::cam::uin/100004603008:uin/100004603008", // 100004603008 是 QQ 号 }, "Permission": "READ" } }; describe('ObjectAcl', function () { this.timeout(60000); it('putObjectAcl() header ACL:private', function (done) { cos.putObject({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, Key: '1.txt', Body: Buffer.from('hello!'), }, function (err, data) { assert.ok(!err); cos.putObjectAcl({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, ACL: 'private', Key: '1.txt', }, function (err, data) { assert.ok(!err, 'putObjectAcl 成功'); cos.getObjectAcl({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, Key: '1.txt' }, function (err, data) { assert.ok(data.ACL = 'private'); AccessControlPolicy.Owner.ID = data.Owner.ID; AccessControlPolicy2.Owner.ID = data.Owner.ID; assert.ok(data.Grants.length === 1); done(); }); }); }); }); it('putObjectAcl() header ACL:default', function (done) { cos.putObjectAcl({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, ACL: 'default', Key: '1.txt', }, function (err, data) { assert.ok(!err, 'putObjectAcl 成功'); cos.getObjectAcl({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, Key: '1.txt' }, function (err, data) { assert.ok(data.ACL = 'default'); done(); }); }); }); it('putObjectAcl() header ACL:public-read', function (done) { cos.putObjectAcl({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, ACL: 'public-read', Key: '1.txt', }, function (err, data) { assert.ok(!err, 'putObjectAcl 成功'); cos.getObjectAcl({Bucket: config.Bucket, Region: config.Region, Key: '1.txt'}, function (err, data) { // Bucket 格式:test-1250000000 assert.ok(data.ACL = 'public-read'); done(); }); }); }); it('putObjectAcl() header ACL:public-read-write', function (done) { cos.putObjectAcl({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, ACL: 'public-read-write', Key: '1.txt', }, function (err, data) { assert.ok(!err, 'putObjectAcl 成功'); cos.getObjectAcl({Bucket: config.Bucket, Region: config.Region, Key: '1.txt'}, function (err, data) { // Bucket 格式:test-1250000000 assert.ok(data.ACL = 'public-read-write'); done(); }); }); }); it('putObjectAcl() header GrantRead:1001,1002', function (done) { var GrantRead = 'id="qcs::cam::uin/1001:uin/1001",id="qcs::cam::uin/1002:uin/1002"'; cos.putObjectAcl({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, GrantRead: GrantRead, Key: '1.txt', }, function (err, data) { assert.ok(!err, 'putObjectAcl 成功'); cos.getObjectAcl({Bucket: config.Bucket, Region: config.Region, Key: '1.txt'}, function (err, data) { // Bucket 格式:test-1250000000 assert.ok(data.GrantRead = GrantRead); done(); }); }); }); it('putObjectAcl() header GrantWrite:1001,1002', function (done) { var GrantWrite = 'id="qcs::cam::uin/1001:uin/1001", id="qcs::cam::uin/1002:uin/1002"'; cos.putObjectAcl({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, GrantWrite: GrantWrite, Key: '1.txt', }, function (err, data) { assert.ok(!err, 'putObjectAcl 成功'); cos.getObjectAcl({Bucket: config.Bucket, Region: config.Region, Key: '1.txt'}, function (err, data) { // Bucket 格式:test-1250000000 assert.ok(data.GrantWrite = GrantWrite); done(); }); }); }); it('putObjectAcl() header GrantFullControl:1001,1002', function (done) { var GrantFullControl = 'id="qcs::cam::uin/1001:uin/1001", id="qcs::cam::uin/1002:uin/1002"'; cos.putObjectAcl({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, GrantFullControl: GrantFullControl, Key: '1.txt', }, function (err, data) { assert.ok(!err, 'putObjectAcl 成功'); cos.getObjectAcl({Bucket: config.Bucket, Region: config.Region, Key: '1.txt'}, function (err, data) { // Bucket 格式:test-1250000000 assert.ok(data.GrantFullControl = GrantFullControl); done(); }); }); }); it('putObjectAcl() header ACL:public-read, GrantRead:1001,1002', function (done) { var GrantFullControl = 'id="qcs::cam::uin/1001:uin/1001", id="qcs::cam::uin/1002:uin/1002"'; cos.putObjectAcl({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, GrantFullControl: GrantFullControl, ACL: 'public-read', Key: '1.txt', }, function (err, data) { assert.ok(!err, 'putObjectAcl 成功'); cos.getObjectAcl({Bucket: config.Bucket, Region: config.Region, Key: '1.txt'}, function (err, data) { // Bucket 格式:test-1250000000 assert.ok(data.GrantFullControl = GrantFullControl); assert.ok(data.ACL = 'public-read'); done(); }); }); }); it('putObjectAcl() xml', function (done) { cos.putObjectAcl({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, AccessControlPolicy: AccessControlPolicy, Key: '1.txt', }, function (err, data) { assert.ok(!err, 'putObjectAcl 成功'); cos.getBucketAcl({Bucket: config.Bucket, Region: config.Region, Key: '1.txt'}, function (err, data) { // Bucket 格式:test-1250000000 assert.ok(data.Grants.length === 1); assert.ok(data.Grants[0] && data.Grants[0].Grantee.ID === 'qcs::cam::uin/100004603008:uin/100004603008', '设置 AccessControlPolicy ID 正确'); assert.ok(data.Grants[0] && data.Grants[0].Permission === 'READ', '设置 AccessControlPolicy Permission 正确'); done(); }); }); }); it('putObjectAcl() xml2', function (done) { cos.putObjectAcl({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, AccessControlPolicy: AccessControlPolicy2, Key: '1.txt', }, function (err, data) { assert.ok(!err, 'putObjectAcl 成功'); cos.getObjectAcl({ Bucket: config.Bucket, Region: config.Region, Key: '1.txt' }, function (err, data) { // Bucket 格式:test-1250000000 assert.ok(data.Grants.length === 1); assert.ok(data.Grants[0] && data.Grants[0].Grantee.ID === 'qcs::cam::uin/100004603008:uin/100004603008', 'ID 正确'); assert.ok(data.Grants[0] && data.Grants[0].Permission === 'READ', 'Permission 正确'); done(); }); }); }); it('putObjectAcl() decodeAcl', function (done) { cos.getObjectAcl({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, Key: '1.txt' }, function (err, data) { cos.putObjectAcl({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, Key: '1.txt', GrantFullControl: data.GrantFullControl, GrantWrite: data.GrantWrite, GrantRead: data.GrantRead, ACL: data.ACL, }, function (err, data) { assert.ok(data); done(); }); }); }); }); })(); describe('BucketCors', function () { this.timeout(60000); var CORSRules = [{ "AllowedOrigins": ["*"], "AllowedMethods": ["GET", "POST", "PUT", "DELETE", "HEAD"], "AllowedHeaders": ["*"], "ExposeHeaders": ["ETag", "Content-Length", "x-cos-acl", "x-cos-version-id", "x-cos-request-id", "x-cos-delete-marker", "x-cos-server-side-encryption"], "MaxAgeSeconds": "5" }]; var CORSRulesMulti = [{ "AllowedOrigins": ["*"], "AllowedMethods": ["GET", "POST", "PUT", "DELETE", "HEAD"], "AllowedHeaders": ["*"], "ExposeHeaders": ["ETag", "Content-Length", "x-cos-acl", "x-cos-version-id", "x-cos-request-id", "x-cos-delete-marker", "x-cos-server-side-encryption"], "MaxAgeSeconds": "5" }, { "AllowedOrigins": ["http://qq.com", "http://qcloud.com"], "AllowedMethods": ["GET", "POST", "PUT", "DELETE", "HEAD"], "AllowedHeaders": ["*"], "ExposeHeaders": ["ETag", "Content-Length", "x-cos-acl", "x-cos-version-id", "x-cos-request-id", "x-cos-delete-marker", "x-cos-server-side-encryption"], "MaxAgeSeconds": "5" }]; it('deleteBucketCors()', function (done) { cos.deleteBucketCors({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region }, function (err, data) { assert.ok(!err); setTimeout(function () { cos.getBucketCors({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region }, function (err, data) { assert.ok(err && err.statusCode === 404); done(); }); }, 2000); }); }); it('putBucketCors(),getBucketCors()', function (done) { CORSRules[0].AllowedHeaders[CORSRules[0].AllowedHeaders.length - 1] = 'test-' + Date.now().toString(36); cos.putBucketCors({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, CORSConfiguration: { CORSRules: CORSRules } }, function (err, data) { assert.ok(!err); setTimeout(function () { cos.getBucketCors({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region }, function (err, data) { assert.ok(comparePlainObject(CORSRules, data.CORSRules)); done(); }); }, 2000); }); }); it('putBucketCors() old', function (done) { var testVal = 'test-' + Date.now().toString(36); CORSRules[0].AllowedHeaders.push(testVal); cos.putBucketCors({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, CORSConfiguration: { CORSRules: CORSRules } }, function (err, data) { assert.ok(!err); setTimeout(function () { cos.getBucketCors({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region }, function (err, data) { assert.ok(comparePlainObject(CORSRules, data.CORSRules)); done(); }); }, 2000); }); }); it('putBucketCors() old', function (done) { CORSRules[0].AllowedHeaders[CORSRules[0].AllowedHeaders.length - 1] = 'test-' + Date.now().toString(36); cos.putBucketCors({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, CORSRules: CORSRules }, function (err, data) { assert.ok(!err); setTimeout(function () { cos.getBucketCors({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region }, function (err, data) { assert.ok(comparePlainObject(CORSRules, data.CORSRules)); done(); }); }, 2000); }); }); it('putBucketCors() multi', function (done) { cos.putBucketCors({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, CORSConfiguration: { CORSRules: CORSRulesMulti } }, function (err, data) { assert.ok(!err); setTimeout(function () { cos.getBucketCors({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region }, function (err, data) { assert.ok(comparePlainObject(CORSRulesMulti, data.CORSRules)); done(); }); }, 2000); }); }); }); (function () { var Rules = [{ 'ID': '1', 'Filter': { 'Prefix': 'test_' + Date.now().toString(36), }, 'Status': 'Enabled', 'Transition': { 'Date': '2018-07-29T16:00:00.000Z', 'StorageClass': 'STANDARD_IA' } }]; var RulesMulti = [{ 'ID': '1', 'Filter': { 'Prefix': 'test1_' + Date.now().toString(36), }, 'Status': 'Enabled', 'Transition': { 'Date': '2018-07-29T16:00:00.000Z', 'StorageClass': 'STANDARD_IA' } }, { 'ID': '2', 'Filter': { 'Prefix': 'test2_' + Date.now().toString(36), }, 'Status': 'Enabled', 'Transition': { 'Date': '2018-07-29T16:00:00.000Z', 'StorageClass': 'STANDARD_IA' } }]; describe('BucketLifecycle', function () { this.timeout(60000); it('deleteBucketLifecycle()', function (done) { cos.deleteBucketLifecycle({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region }, function (err, data) { assert.ok(!err); setTimeout(function () { cos.getBucketLifecycle({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region }, function (err, data) { assert.ok(comparePlainObject([], data.Rules)); done(); }); }, 2000); }); }); it('putBucketLifecycle(),getBucketLifecycle()', function (done) { Rules[0].Filter.Prefix = 'test_' + Date.now().toString(36); cos.putBucketLifecycle({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, LifecycleConfiguration: { Rules: Rules } }, function (err, data) { assert.ok(!err); setTimeout(function () { cos.getBucketLifecycle({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region }, function (err, data) { assert.ok(comparePlainObject(Rules, data && data.Rules)); done(); }); }, 2000); }); }); it('putBucketLifecycle() multi', function (done) { Rules[0].Filter.Prefix = 'test_' + Date.now().toString(36); cos.putBucketLifecycle({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region, LifecycleConfiguration: { Rules: RulesMulti } }, function (err, data) { assert.ok(!err); setTimeout(function () { cos.getBucketLifecycle({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: config.Region }, function (err, data) { assert.ok(comparePlainObject(RulesMulti, data.Rules)); done(); }); }, 2000); }); }); }); })(); describe('params check', function () { it('Region', function (done) { cos.headBucket({ Bucket: config.Bucket, // Bucket 格式:test-1250000000 Region: 'gz' }, function (err, data) { assert.ok(err); done(); }); }); }); describe('Key 特殊字符处理', function () { it('Key 特殊字符处理', function (done) { var Key = '中文→↓←→↖↗↙↘! $&\'()+,-.0123456789=@ABCDEFGHIJKLMNOPQRSTUV?WXYZ[]^_`abcdefghijklmnopqrstuvwxyz{}~.jpg'; cos.putObject({ Bucket: config.Bucket, Region: config.Region, Key: Key, Body: 'hello', }, function (err, data) { assert.ok(!err); cos.deleteObject({ Bucket: config.Bucket, Region: config.Region, Key: Key, Body: 'hello', }, function (err, data) { assert.ok(!err); cos.deleteMultipleObject({ Bucket: config.Bucket, Region: config.Region, Objects: { Key: Key, }, }, function (err, data) { assert.ok(!err); done(); }); }); }); }); }); describe('Bucket 格式有误', function () { it('Bucket 带有中文', function (done) { cos.headBucket({ Bucket: '中文-1250000000', Region: config.Region, }, function (err, data) { // assert.ok(err && err.error === 'Bucket should format as "test-1250000000".'); done(); }); }); it('Bucket 带有 /', function (done) { cos.headBucket({ Bucket: 'te/st-1250000000', Region: config.Region, }, function (err, data) { assert.ok(err && err.error === 'Bucket should format as "test-1250000000".'); done(); }); }); it('Bucket 带有 .', function (done) { cos.headBucket({ Bucket: 'te.st-1250000000', Region: config.Region, }, function (err, data) { assert.ok(err && err.error === 'Bucket should format as "test-1250000000".'); done(); }); }); it('Bucket 带有 :', function (done) { cos.headBucket({ Bucket: 'te:st-1250000000', Region: config.Region, }, function (err, data) { assert.ok(err && err.error === 'Bucket should format as "test-1250000000".'); done(); }); }); }); describe('Region 格式有误', function () { it('Region 带有中文', function (done) { cos.headBucket({ Bucket: 'test-1250000000', Region: '中文', }, function (err, data) { assert.ok(err && err.error === 'Region format error.'); done(); }); }); it('Region 带有 /', function (done) { cos.headBucket({ Bucket: 'test-1250000000', Region: 'test/', }, function (err, data) { assert.ok(err && err.error === 'Region format error.'); done(); }); }); it('Region 带有 :', function (done) { cos.headBucket({ Bucket: 'te:st-1250000000', Region: 'test:', }, function (err, data) { assert.ok(err && err.error === 'Region format error.'); done(); }); }); });