cos-js-sdk-v5
Version:
JavaScript SDK for [腾讯云对象存储](https://cloud.tencent.com/product/cos)
1,557 lines (1,516 loc) • 197 kB
JavaScript
/**
* @jest-environment jsdom
*/
import { describe, expect, jest, test } from '@jest/globals';
import COS from '../index.js';
import Beacon from '../demo/common/beacon.min';
import ClsClient from '../demo/common/cls.min';
// config 替换成自己的桶信息
var config = {
SecretId: process.env.SecretId,
SecretKey: process.env.SecretKey,
Bucket: process.env.Bucket, // 需提前创建并设置跨域
Region: process.env.Region,
ReplicationBucket: process.env.ReplicationBucket, // 存储桶复制时用到的桶,需提前创建并设置跨域
ReplicationRegion: process.env.ReplicationRegion, // 存储桶复制时用到的桶的地域
Uin: process.env.Uin,
StsUrl: process.env.jssdkStsUrl,
};
// mock localStroage
var localStorageMock = (function () {
var store = {};
return {
getItem: function (key) {
return store[key];
},
setItem: function (key, value) {
store[key] = value.toString();
},
clear: function () {
store = {};
},
removeItem: function (key) {
delete store[key];
},
};
})();
Object.defineProperty(window, 'localStorage', {
writable: true,
configurable: true,
value: localStorageMock,
});
function checkEnvParams() {
if (!process.env.Bucket) {
console.warn('环境变量里未找到Bucket,请检查');
return;
}
if (!process.env.Region) {
console.warn('环境变量里未找到Region,请检查');
return;
}
if (!process.env.ReplicationBucket) {
console.warn('环境变量里未找到ReplicationBucket,请检查');
return;
}
if (!process.env.ReplicationRegion) {
console.warn('环境变量里未找到ReplicationRegion,请检查');
return;
}
if (!process.env.Uin) {
console.warn('环境变量里未找到Uin,请检查');
return;
}
return true;
}
var util = {
createFile: function (options) {
var buffer = new ArrayBuffer(options.size || 0);
var arr = new Uint8Array(buffer);
for (var i = 0; i < arr.length; i++) {
arr[i] = 0;
}
var opt = {};
options.type && (opt.type = options.type);
var blob = new Blob([buffer], options);
var file = new File([blob], `file-${Date.now()}`, {
type: options.type,
lastModified: Date.now(),
lastModifiedDate: new Date(),
});
file.lastModifiedDate = new Date();
return file;
},
str2blob: function (str) {
var size = str.length;
var buffer = new ArrayBuffer(size || 0);
var arr = new Uint8Array(buffer);
for (var i = 0; i < arr.length; i++) {
arr[i] = str[i];
}
var blob = new Blob([buffer]);
return blob;
},
};
function camSafeUrlEncode(str) {
return encodeURIComponent(str)
.replace(/!/g, '%21')
.replace(/'/g, '%27')
.replace(/\(/g, '%28')
.replace(/\)/g, '%29')
.replace(/\*/g, '%2A');
}
function comparePlainObject(a, b) {
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;
}
function prepareBigObject(needHeaders) {
return new Promise(function (resolve, reject) {
// 创建测试文件
var filename = name || 'bigger.zip';
var content = util.createFile({ size: 1024 * 1024 * 10 });
var put = function () {
// 调用方法
var params = {
Bucket: config.Bucket,
Region: config.Region,
Key: filename,
Body: content,
ContentLength: content.length,
};
if (needHeaders) {
params.ContentType = 'text/html';
params.CacheControl = 'max-age=7200';
params.ContentDisposition = 'inline;filename=hello.jpg';
params.Expires = new Date().toGMTString();
params.Headers = {
'x-cos-meta-test': 'xxx',
};
}
cos.putObject(params, function (err, data) {
err ? reject(err) : resolve();
});
};
put();
});
}
var createFileSync = function (size) {
return util.createFile({ size: size });
};
var dataURItoUploadBody = function (dataURI) {
var byteString = atob(dataURI.split(',')[1]);
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ab], { type: mimeString });
};
var getAuthorization = function (options, callback) {
var authorization = COS.getAuthorization({
SecretId: process.env.SecretId,
SecretKey: process.env.SecretKey,
Method: options.Method,
Pathname: options.Pathname,
Query: options.Query,
Headers: options.Headers,
Expires: 900,
});
callback({
Authorization: authorization,
});
};
var cos = new COS({
// 必选参数
SecretId: config.SecretId,
SecretKey: config.SecretKey,
UploadCheckContentMd5: true,
UploadAddMetaMd5: true,
Protocol: 'http:',
// getAuthorization: getAuthorization,
});
console.log('config.StsUrl========', config.StsUrl);
function getSts(options) {
return new Promise((resolve, reject) => {
var url = `${config.StsUrl}/sts`; // 如果是 npm run sts.js 起的 nodejs server,使用这个
var xhr = new XMLHttpRequest();
xhr.open('get', url, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onload = function (e) {
var data,credentials;
try {
data = JSON.parse(e.target.responseText);
credentials = data.credentials;
} catch (e) {}
if (!data || !credentials) {
console.error('credentials invalid:\n' + JSON.stringify(data, null, 2));
reject();
}
resolve({
TmpSecretId: credentials.tmpSecretId,
TmpSecretKey: credentials.tmpSecretKey,
SecurityToken: credentials.sessionToken,
StartTime: data.startTime, // 时间戳,单位秒,如:1580000000,建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误
ExpiredTime: data.expiredTime, // 时间戳,单位秒,如:1580000000
});
};
xhr.send(JSON.stringify(options?.Scope));
});
}
// todo 只能这么提前获取
const sts = {};
getSts().then(data => {
Object.assign(sts, data);
});
// 使用临时密钥
var tempCOS = new COS({
getAuthorization: async function (options, callback) {
try {
const res = await getSts(options);
callback({
TmpSecretId: res.TmpSecretId,
TmpSecretKey: res.TmpSecretKey,
SecurityToken: res.SecurityToken,
StartTime: res.StartTime, // 时间戳,单位秒,如:1580000000,建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误
ExpiredTime: res.ExpiredTime, // 时间戳,单位秒,如:1580000000
ScopeLimit: true, // 细粒度控制权限需要设为 true,会限制密钥只在相同请求时重复使用
});
} catch (e) {
console.error('get sts error');
}
},
});
// 使用临时密钥(老版本使用的XCosSecurityToken)
var oldTempCOS = new COS({
// UseAccelerate: true,
getAuthorization: async function (options, callback) {
try {
const res = await getSts(options);
callback({
TmpSecretId: res.TmpSecretId,
TmpSecretKey: res.TmpSecretKey,
XCosSecurityToken: res.SecurityToken,
StartTime: res.StartTime, // 时间戳,单位秒,如:1580000000,建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误
ExpiredTime: res.ExpiredTime, // 时间戳,单位秒,如:1580000000
ScopeLimit: true, // 细粒度控制权限需要设为 true,会限制密钥只在相同请求时重复使用
});
} catch (e) {
console.error('get sts error');
}
},
});
// 后端下发 putObject 前面 Key 为 1.txt
var getSignCOS = new COS({
// UseAccelerate: true,
getAuthorization: function (options, callback) {
var url = `${config.StsUrl}/uploadSign`; // 如果是 npm run sts.js 起的 nodejs server,使用这个
var xhr = new XMLHttpRequest();
xhr.open('get', url, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onload = function (e) {
try {
var data = JSON.parse(e.target.responseText);
} catch (e) {}
if (!data) {
return console.error('credentials invalid:\n' + JSON.stringify(data, null, 2));
}
callback({
Authorization: data?.signMap?.PutObject,
});
};
xhr.send();
},
});
var getStsCOS = new COS({
// UseAccelerate: true,
getSTS: async function (options, callback) {
try {
const res = await getSts(options);
callback({
TmpSecretId: res.TmpSecretId,
TmpSecretKey: res.TmpSecretKey,
XCosSecurityToken: res.SecurityToken,
StartTime: res.StartTime, // 时间戳,单位秒,如:1580000000,建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误
ExpiredTime: res.ExpiredTime, // 时间戳,单位秒,如:1580000000
ScopeLimit: true, // 细粒度控制权限需要设为 true,会限制密钥只在相同请求时重复使用
});
} catch (e) {
console.error('get sts error');
}
},
});
// 临时密钥允许的路径
var tempCOSPrefix = 'js-sdk/test/';
var Bucket = config.Bucket;
var BucketShortName = Bucket;
var TaskId;
var AppId;
var BucketLongName = Bucket + '-' + AppId;
var match = config.Bucket.match(/^(.+)-(\d+)$/);
if (match) {
BucketLongName = config.Bucket;
BucketShortName = match[1];
AppId = match[2];
}
var group = function (name, fn) {
if (!checkEnvParams()) return;
console.log(`${name}进行中....`);
describe(name, function () {
jest.setTimeout(1 * 60 * 1000);
fn.apply(this, arguments);
});
};
var assert = {
ok: function (val) {
expect(Boolean(val)).toBeTruthy();
},
};
var base64Url =
'data:image/png;base64,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';
var dataURLtoBlob = function (dataurl) {
var arr = dataurl.split(',');
var mime = arr[0].match(/:(.*?);/)[1];
var bstr = atob(arr[1]);
var n = bstr.length;
var u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime });
};
group('init cos', function () {
const putFile = function (cosIns, done, canSuccess = true) {
var key = '1.txt';
var content = Date.now().toString();
cosIns.putObject(
{
Bucket: config.Bucket,
Region: config.Region,
Key: key,
Body: content,
Headers: {
'x-cos-test': '1',
'x-cos-meta-test': 'meta',
},
'x-cos-test2': '2',
},
function (err, data) {
assert.ok(canSuccess ? !err : err);
done();
}
);
};
test('使用AppId', function (done) {
var initCos = new COS({
SecretId: config.SecretId,
SecretKey: config.SecretKey,
AppId: AppId,
});
putFile(initCos, done);
});
test('SecretId格式错误', function (done) {
var initCos = new COS({
SecretId: config.SecretId + ' ',
SecretKey: config.SecretKey,
});
putFile(initCos, done, false);
});
test('SecretKey格式错误', function (done) {
var initCos = new COS({
SecretId: config.SecretId,
SecretKey: config.SecretKey + ' ',
});
putFile(initCos, done, false);
});
test('Timeout=6000', function (done) {
var initCos = new COS({
SecretId: config.SecretId,
SecretKey: config.SecretKey,
Timeout: 6000,
});
putFile(initCos, done);
});
test('ForcePathStyle', function (done) {
try {
var initCos = new COS({
SecretId: config.SecretId,
SecretKey: config.SecretKey,
ForcePathStyle: true,
});
putFile(initCos, done, false);
} catch (e) {
assert.ok(e.message === 'ForcePathStyle is not supported');
done();
}
});
test('getAuthorization error tmpSecretId', function (done) {
var initCos = new COS({
getAuthorization: function (options, callback) {
callback({
tmpSecretId: config.SecretId,
TmpSecretKey: config.SecretKey,
});
},
});
putFile(initCos, done, false);
});
test('getAuthorization error tmpSecretKey', function (done) {
var initCos = new COS({
getAuthorization: function (options, callback) {
callback({
TmpSecretId: config.SecretId,
tmpSecretKey: config.SecretKey,
});
},
});
putFile(initCos, done, false);
});
test('getAuthorization error', function (done) {
var initCos = new COS({
getAuthorization: function (options, callback) {
callback({
TmpSecretId: config.SecretId,
TmpSecretKey: config.SecretKey,
});
},
});
putFile(initCos, done, false);
});
test('getAuthorization 使用临时密钥 putObject', function (done) {
tempCOS.putObject(
{
Bucket: config.Bucket,
Region: config.Region,
Key: tempCOSPrefix + Date.now().toString(36),
Body: '12345',
},
function (err, data) {
assert.ok(!err);
done();
}
);
});
test('getStsCOS 使用临时密钥 putObject', function (done) {
getStsCOS.putObject(
{
Bucket: config.Bucket,
Region: config.Region,
Key: tempCOSPrefix + Date.now().toString(36),
Body: '12345',
},
function (err, data) {
assert.ok(!err);
done();
}
);
});
test('getAuthorization 使用临时密钥 sliceUploadFile', function (done) {
const file = createFileSync(20 * 1024 * 1024);
oldTempCOS.sliceUploadFile(
{
Bucket: config.Bucket,
Region: config.Region,
Key: tempCOSPrefix + Date.now().toString(36),
Body: file,
},
function (err, data) {
assert.ok(!err);
done();
}
);
});
test('getAuthorization 使用临时密钥 sliceUploadFile 没有权限', function (done) {
const file = createFileSync(20 * 1024 * 1024);
tempCOS.sliceUploadFile(
{
Bucket: config.Bucket,
Region: config.Region,
Key: Date.now().toString(36),
Body: file,
},
function (err, data) {
assert.ok(err);
done();
}
);
});
test('getStsCOS 使用下发的签名 putObject', function (done) {
getSignCOS.putObject(
{
Bucket: config.Bucket,
Region: config.Region,
Key: '1.txt',
Body: '12345',
},
function (err, data) {
assert.ok(!err);
done();
}
);
});
test('getAuthorization 使用下发的签名 sliceUploadFile 没权限', function (done) {
const file = createFileSync(20 * 1024 * 1024);
getSignCOS.sliceUploadFile(
{
Bucket: config.Bucket,
Region: config.Region,
Key: '1.txt',
Body: file,
},
function (err, data) {
assert.ok(err);
done();
}
);
});
test('推荐初始化方式 putObject 成功', function (done) {
const cos = new COS({
SecretId: sts.TmpSecretId,
SecretKey: sts.TmpSecretKey,
SecurityToken: sts.SecurityToken,
StartTime: sts.StartTime, // 时间戳,单位秒,如:1580000000,建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误
ExpiredTime: sts.ExpiredTime, // 时间戳,单位秒,如:1580000000
});
cos.putObject(
{
Bucket: config.Bucket,
Region: config.Region,
Key: tempCOSPrefix + '1.txt',
Body: '12345',
},
function (err, data) {
console.log(' putObject 成功', err || data);
assert.ok(!err);
done();
}
);
});
test('推荐初始化方式 putObject invalid StartTime', function (done) {
const cos = new COS({
SecretId: sts.TmpSecretId,
SecretKey: sts.TmpSecretKey,
SecurityToken: sts.SecurityToken,
StartTime: sts.StartTime * 1000, // 时间戳,单位秒,如:1580000000,建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误
ExpiredTime: sts.ExpiredTime, // 时间戳,单位秒,如:1580000000
});
cos.putObject(
{
Bucket: config.Bucket,
Region: config.Region,
Key: tempCOSPrefix + '1.txt',
Body: '12345',
},
function (err, data) {
assert.ok(err);
done();
}
);
});
test('推荐初始化方式 putObject invalid ExpiredTime', function (done) {
const cos = new COS({
SecretId: sts.TmpSecretId,
SecretKey: sts.TmpSecretKey,
SecurityToken: sts.SecurityToken,
StartTime: sts.StartTime, // 时间戳,单位秒,如:1580000000,建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误
ExpiredTime: sts.ExpiredTime * 1000, // 时间戳,单位秒,如:1580000000
});
cos.putObject(
{
Bucket: config.Bucket,
Region: config.Region,
Key: tempCOSPrefix + '1.txt',
Body: '12345',
},
function (err, data) {
assert.ok(err);
done();
}
);
});
test('推荐初始化方式 getObjectUrl invalid StartTime', function (done) {
const cos = new COS({
SecretId: sts.TmpSecretId,
SecretKey: sts.TmpSecretKey,
SecurityToken: sts.SecurityToken,
StartTime: sts.StartTime * 1000, // 时间戳,单位秒,如:1580000000,建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误
ExpiredTime: sts.ExpiredTime, // 时间戳,单位秒,如:1580000000
});
cos.getObjectUrl(
{
Bucket: config.Bucket,
Region: config.Region,
Key: tempCOSPrefix + '1.txt',
Expires: Date.now() * 1000,
},
function (err, data) {
console.log('getObjectUrl invalid ExpiredTime', err||data);
assert.ok(err);
done();
}
);
});
});
group('task 队列', function () {
test('putObject() 批量上传', function (done) {
var cos = new COS({
SecretId: config.SecretId,
SecretKey: config.SecretKey,
UploadQueueSize: 100,
});
var upload = function () {
var filename = '5.txt';
cos.putObject(
{
Bucket: config.Bucket,
Region: config.Region,
Key: filename,
Body: '12345',
},
function (err, data) {}
);
};
for (var i = 0; i < 120; i++) {
upload();
}
var taskList = cos.getTaskList();
const isUploading = cos.isUploadRunning();
assert.ok(isUploading);
done();
});
test('putObject(),update-list()', function (done) {
var filename = '10m.zip';
const file = createFileSync(10 * 1024 * 1024);
cos.putObject(
{
Bucket: config.Bucket,
Region: config.Region,
Key: filename,
Body: file,
},
function (err, data) {
assert.ok(!err);
done();
}
);
cos.on('task-list-update', function () {});
});
});
group('兼容性测试', function () {
test('getBucketACL 老用法', function (done) {
cos.getBucketACL(
{
Bucket: config.Bucket,
Region: config.Region,
},
function (err, data) {
assert.ok(!err);
done();
}
);
});
});
group('getService()', function () {
var cos = new COS({
// 必选参数
SecretId: config.SecretId,
SecretKey: config.SecretKey,
UploadCheckContentMd5: true,
UploadAddMetaMd5: true,
Protocol: 'http:',
ServiceDomain: 'service.cos.myqcloud.com/',
});
test('getService 老用法', function (done) {
cos.getService(function (err, data) {
assert.ok(err);
done();
});
});
test('getService 传Region', function (done) {
var cos = new COS({
SecretId: config.SecretId,
SecretKey: config.SecretKey,
});
cos.getService(
{
Region: config.Region,
},
function (err, data) {
assert.ok(err);
done();
}
);
});
test('getService 不传Region和Domain', function (done) {
var cos = new COS({
SecretId: config.SecretId,
SecretKey: config.SecretKey,
});
cos.getService({}, function (err, data) {
assert.ok(err);
done();
});
});
test('不能正常列出 Bucket', function (done) {
cos.getService(
{
Region: config.Region,
},
function (err, data) {
assert.ok(err);
done();
}
);
});
});
group('putBucket()', function () {
var NewBucket = 'test' + Date.now().toString(36) + '-' + AppId;
test('创建 bucket js sdk因为跨域会失败', function (done) {
cos.putBucket(
{
Bucket: NewBucket,
Region: config.Region,
},
function (err, data) {
assert.ok(err);
done();
}
);
});
test('正常创建 bucket BucketAZConfig js sdk因为跨域会失败', function (done) {
cos.putBucket(
{
Bucket: NewBucket,
Region: config.Region,
BucketAZConfig: {},
},
function (err, data) {
assert.ok(err);
done();
}
);
});
test('deleteBucket() deleteBucket 不存在', function (done) {
cos.deleteBucket(
{
Bucket: Date.now().toString(36) + config.Bucket,
Region: config.Region,
},
function (err, data) {
assert.ok(err, 'deleteBucket 不存在');
done();
}
);
});
});
group('mock readAsBinaryString', function () {
test('mock readAsBinaryString', function (done) {
FileReader.prototype._readAsBinaryString = FileReader.prototype.readAsBinaryString;
FileReader.prototype.readAsBinaryString = false;
var filename = '10m.zip';
var blob = util.createFile({ size: 1024 * 1024 * 10 });
var paused = false;
cos.sliceUploadFile({
Bucket: config.Bucket,
Region: config.Region,
Key: filename,
Body: blob,
onTaskReady: function (taskId) {
TaskId = taskId;
},
onProgress: function (info) {
if (!paused && info.percent > 0.6) {
cos.cancelTask(TaskId);
var hasProgress = false;
cos.sliceUploadFile(
{
Bucket: config.Bucket,
Region: config.Region,
Key: filename,
Body: blob,
onTaskReady: function (taskId) {
TaskId = taskId;
},
onProgress: function (info) {
if (info.percent === 0) return;
expect(info.percent).toBeGreaterThanOrEqual(0.3);
cos.cancelTask(TaskId);
FileReader.prototype.readAsBinaryString = FileReader.prototype._readAsBinaryString;
delete FileReader.prototype._readAsBinaryString;
done();
},
},
function (err) {
if (hasProgress) {
done();
}
}
);
}
},
});
});
});
group('getAuth()', function () {
test('getAuth()', function (done) {
var content = Date.now().toString();
var key = '1.txt';
cos.putObject(
{
Bucket: config.Bucket,
Region: config.Region,
Key: key,
Body: content,
},
function (err, data) {
if (err) {
done();
return;
}
let AuthData = cos.getAuth({
SecretId: config.SecretId,
SecretKey: config.SecretKey,
Method: 'get',
Key: key,
Scope: [
{
action: 'GetObject',
bucket: config.Bucket,
region: config.Region,
prefix: key,
},
],
});
if (typeof AuthData === 'string') {
AuthData = { Authorization: AuthData };
}
if (!AuthData.Authorization) {
AuthData.Authorization = COS.getAuthorization({
SecretId: AuthData.TmpSecretId,
SecretKey: AuthData.TmpSecretKey,
Method: 'get',
Key: key,
SystemClockOffset: cos.options.SystemClockOffset,
});
}
var link =
'http://' +
config.Bucket +
'.cos.' +
config.Region +
'.myqcloud.com' +
'/' +
camSafeUrlEncode(key).replace(/%2F/g, '/') +
'?' +
AuthData.Authorization +
(AuthData.SecurityToken ? '&x-cos-security-token=' + AuthData.SecurityToken : '');
done();
}
);
});
});
group('getObjectUrl()', function () {
test('getObjectUrl()', function (done) {
var content = Date.now().toString();
var key = '1.txt';
cos.putObject(
{
Bucket: config.Bucket,
Region: config.Region,
Key: key,
Body: content,
},
function (err, data) {
cos.getObjectUrl(
{
Bucket: config.Bucket,
Region: config.Region,
Key: key,
Query: {
a: 1,
},
Sign: true,
Expires: 8000000,
},
function (err, data) {
expect(typeof data.Url).toBe('string');
err ? done(err) : done();
}
);
tempCOS.getObjectUrl(
{
Bucket: config.Bucket,
Region: config.Region,
Key: key,
Query: {
a: 1,
},
Sign: false,
},
function (err, data) {
expect(typeof data.Url).toBe('string');
err ? done(err) : done();
}
);
}
);
});
});
group('auth check', function () {
test('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) {
err ? done(err) : done();
}
);
});
});
group('getBucket(),listObjectVersions()', function () {
test('正常获取 bucket 里的文件列表', function (done) {
cos.getBucket(
{
Bucket: config.Bucket,
Region: config.Region,
},
function (err, data) {
expect(data.Name).toBe(BucketLongName);
expect(data.Contents).toBeInstanceOf(Array);
err ? done(err) : done();
}
);
});
test('正常获取 bucket 里的文件版本列表', function (done) {
cos.listObjectVersions(
{
Bucket: config.Bucket,
Region: config.Region,
},
function (err, data) {
expect(data.Name).toBe(config.Bucket);
expect(data.Versions).toBeInstanceOf(Array);
err ? done(err) : done();
}
);
});
});
group('putObject(),cancelTask()', function () {
test('putObject(),cancelTask()', function (done) {
var filename = '10m.zip';
var alive = false;
var canceled = false;
const file = createFileSync(10 * 1024 * 1024);
cos.putObject(
{
Bucket: config.Bucket,
Region: config.Region,
Key: filename,
Body: file,
onTaskReady: function (taskId) {
TaskId = taskId;
},
onProgress: function (info) {
alive = true;
if (!canceled) {
cos.cancelTask(TaskId);
alive = false;
canceled = true;
setTimeout(function () {
expect(alive).toBe(false);
done();
}, 1200);
}
},
},
function (err, data) {
alive = true;
err ? done(err) : done();
}
);
});
});
group('putObject 测试老参数', function () {
test('putObject() options.AppId', function (done) {
var filename = '/1m.zip';
const file = createFileSync(1 * 1024 * 1024);
var cos = new COS({
SecretId: config.SecretId,
SecretKey: config.SecretKey,
AppId,
UseRawKey: true,
});
cos.putObject(
{
Bucket: BucketShortName,
Region: config.Region,
Key: filename,
Body: file,
},
function (err, data) {
assert.ok(!err);
done();
}
);
});
test('putObject() options.CompatibilityMode', function (done) {
var filename = '/1m.zip';
const file = createFileSync(1 * 1024 * 1024);
var cos = new COS({
SecretId: config.SecretId,
SecretKey: config.SecretKey,
CompatibilityMode: true,
});
cos.putObject(
{
Bucket: BucketShortName,
Region: config.Region,
Key: filename,
Body: file,
},
function (err, data) {
assert.ok(err);
done();
}
);
});
test('putObject() BucketShortName', function (done) {
var filename = '/1m.zip';
const file = createFileSync(1 * 1024 * 1024);
cos.putObject(
{
Bucket: BucketShortName,
AppId: AppId,
Region: config.Region,
Key: filename,
Body: file,
},
function (err, data) {
assert.ok(!err);
done();
}
);
});
test('putObject() error Body', function (done) {
cos.putObject(
{
Bucket: BucketShortName,
AppId: AppId,
Region: config.Region,
Key: COS.util.encodeBase64('转base64', true),
Body: { a: 1 },
},
function (err, data) {
assert.ok(err);
done();
}
);
});
test('putObject() missing Key', function (done) {
try {
cos.putObject(
{
Bucket: BucketShortName,
AppId: AppId,
Region: config.Region,
Body: file,
},
function (err, data) {}
);
} catch (e) {
assert.ok(e.message === 'file is not defined');
done();
}
});
});
group('sliceUploadFile() 完整上传文件', function () {
test('sliceUploadFile() 完整上传文件', function (done) {
var lastPercent;
var filename = '3m.zip';
var fileSize = 1024 * 1024 * 3;
var blob = createFileSync(fileSize);
cos.abortUploadTask(
{
Bucket: config.Bucket,
Region: config.Region,
Key: filename,
Level: 'file',
},
function (err, data) {
if (err) {
done();
return;
}
cos.sliceUploadFile(
{
Bucket: config.Bucket,
Region: config.Region,
Key: filename,
Body: blob,
Headers: {
'x-cos-traffic-limit': 8192000000,
},
onTaskReady: function (taskId) {
console.log(taskId);
},
onProgress: function (info) {
lastPercent = info.percent;
},
},
function (err, data) {
console.log('sliceUploadFile', err ? 'failed' : 'success');
if (err) {
done();
return;
}
cos.headObject(
{
Bucket: config.Bucket,
Region: config.Region,
Key: filename,
},
function (err, data) {
console.log('headObject', err ? 'failed' : 'success');
const success = data && data.headers && parseInt(data.headers['content-length'] || 0) === fileSize;
console.log(`data.headers['content-length']`, data.headers['content-length'], fileSize, success);
expect(success);
done();
}
);
}
);
}
);
});
test('sliceUploadFile(),pauseTask(),restartTask()', function (done) {
var filename = Date.now().toString() + '-10m.zip';
var blob = util.createFile({ size: 1024 * 1024 * 10 });
var paused = false;
var updateFn = function (info) {
var task = info.list.find((item) => item.Key === filename);
if (task && task.state === 'success') {
console.log('任务成功');
cos.off('list-update', updateFn);
assert.ok(1);
done();
}
};
cos.abortUploadTask(
{
Bucket: config.Bucket,
Region: config.Region,
Key: filename,
Level: 'file',
},
function (err, data) {
if (err) {
done();
return;
}
var TaskId;
cos.sliceUploadFile(
{
Bucket: config.Bucket,
Region: config.Region,
Key: filename,
Body: blob,
onTaskReady: function (taskId) {
TaskId = taskId;
},
onProgress: function (info) {
if (!paused && info.percent >= 0.3) {
cos.pauseTask(TaskId);
paused = true;
console.log('任务暂停');
cos.on('list-update', updateFn);
setTimeout(function () {
if (paused) {
console.log('任务重启');
cos.restartTask(TaskId);
}
}, 10);
}
},
},
function (err, data) {
assert.ok(1);
done();
}
);
}
);
});
test('sliceUploadFile(),cancelTask(),restartTask()', function (done) {
var filename = '10m.zip';
var blob = util.createFile({ size: 1024 * 1024 * 3 });
var paused = false;
cos.abortUploadTask(
{
Bucket: config.Bucket,
Region: config.Region,
Key: filename,
Level: 'file',
},
function (err, data) {
var TaskId;
cos.sliceUploadFile(
{
Bucket: config.Bucket,
Region: config.Region,
Key: filename,
Body: blob,
onTaskReady: function (taskId) {
TaskId = taskId;
},
onProgress: function (info) {
if (!paused && info.percent > 0.6) {
cos.cancelTask(TaskId);
setTimeout(function () {
cos.sliceUploadFile(
{
Bucket: config.Bucket,
Region: config.Region,
Key: filename,
Body: blob,
},
function (err, data) {
err ? done(err) : done();
}
);
}, 10);
}
},
},
function (err, data) {}
);
}
);
});
test('sliceUploadFile(),cancelTask()', function (done) {
var filename = '3m.zip';
var alive = false;
var canceled = false;
cos.sliceUploadFile(
{
Bucket: config.Bucket,
Region: config.Region,
Key: filename,
Body: util.createFile({ size: 1024 * 1024 * 3 }),
onTaskReady: function (taskId) {
TaskId = taskId;
},
onProgress: function (info) {
alive = true;
if (!canceled) {
cos.cancelTask(TaskId);
alive = false;
canceled = true;
setTimeout(function () {
done();
}, 1200);
}
},
},
function (err, data) {
alive = true;
}
);
});
});
group('sliceUploadFile() 同时上传2个文件', function () {
var filename = '30m.zip';
var blob = util.createFile({ size: 1024 * 1024 * 30 });
test('sliceUploadFile() 上传文件1', function (done) {
cos.sliceUploadFile(
{
Bucket: config.Bucket,
Region: config.Region,
Key: filename,
Body: blob,
},
function (err, data) {
assert.ok(!err);
done();
}
);
setTimeout(() => {
cos.sliceUploadFile(
{
Bucket: config.Bucket,
Region: config.Region,
Key: filename,
Body: blob,
},
function (err, data) {
assert.ok(!err);
done();
}
);
}, 2000);
});
});
group('sliceUploadFile() 续传', function () {
var filename = '30m.zip';
var blob = util.createFile({ size: 1024 * 1024 * 30 });
test('sliceUploadFile() 正常续传', function (done) {
var taskId;
cos.sliceUploadFile(
{
Bucket: config.Bucket,
Region: config.Region,
Key: filename,
Body: blob,
onTaskReady: function (id) {
taskId = id;
},
onProgress: function (progressData) {
if (progressData.percent >= 0.3) {
cos.pauseTask(taskId);
console.log('pause task');
cos.sliceUploadFile(
{
Bucket: config.Bucket,
Region: config.Region,
Key: filename,
Body: blob,
TaskReady: function (id) {
console.log('TaskReady', id);
},
},
function (err, data) {
assert.ok(!err);
done();
}
);
}
},
},
function (err, data) {}
);
});
test('sliceUploadFile() cancelTask', function (done) {
cos.sliceUploadFile(
{
Bucket: config.Bucket,
Region: config.Region,
Key: filename,
Body: blob,
onTaskReady: function (id) {
setTimeout(() => {
cos.cancelTask(id);
cos.sliceUploadFile(
{
Bucket: config.Bucket,
Region: config.Region,
Key: filename,
Body: blob,
},
function (err, data) {
assert.ok(!err);
done();
}
);
}, 2000);
},
},
function (err, data) {}
);
});
test('sliceUploadFile() 续传时远程为 0', function (done) {
var taskId;
var paused = false;
cos.sliceUploadFile(
{
Bucket: config.Bucket,
Region: config.Region,
Key: filename,
Body: blob,
onTaskReady: function (id) {
taskId = id;
},
onProgress: function (progressData) {
if (!paused && progressData.percent >= 0.3) {
cos.pauseTask(taskId);
paused = true;
setTimeout(() => {
if (paused) {
var blob = util.createFile({ size: 1024 * 1024 * 20 });
cos.sliceUploadFile(
{
Bucket: config.Bucket,
Region: config.Region,
Key: filename,
Body: blob,
},
function (err, data) {
assert.ok(!err);
done();
}
);
}
}, 1000);
}
},
},
function (err, data) {}
);
});
});
group('abortUploadTask()', function () {
test('abortUploadTask(),Level=task', function (done) {
var filename = '1m.zip';
cos.multipartInit(
{
Bucket: config.Bucket,
Region: config.Region,
Key: filename,
},
function (err, data) {
cos.abortUploadTask(
{
Bucket: config.Bucket,
Region: config.Region,
Key: filename,
Level: 'task',
UploadId: data.UploadId,
},
function (err, data) {
var nameExist = false;
data.successList.forEach(function (item) {
if (filename === item.Key) {
nameExist = true;
}
});
assert.ok(data.successList.length >= 1);
assert.ok(nameExist);
err ? done(err) : done();
}
);
}
);
});
test('abortUploadTask(),Level=file', function (done) {
var filename = '1m.zip';
var blob = util.createFile({ size: 1024 * 1024 });
cos.sliceUploadFile({
Bucket: config.Bucket,
Region: config.Region,
Key: filename,
Body: blob,
onTaskReady: function (taskId) {
TaskId = taskId;
},
onProgress: function (info) {
cos.cancelTask(TaskId);
cos.abortUploadTask(
{
Bucket: config.Bucket,
Region: config.Region,
Level: 'file',
Key: filename,
},
function (err, data) {
assert.ok(data.successList.length >= 1);
assert.ok(data.successList[0] && data.successList[0].Key === filename);
err ? done(err) : done();
}
);
},
});
});
test('abortUploadTask(),Level=bucket', function (done) {
var filename = '1m.zip';
var blob = util.createFile({ size: 1024 * 1024 * 10 });
cos.sliceUploadFile({
Bucket: config.Bucket,
Region: config.Region,
Key: filename,
Body: blob,
Headers: {
'x-cos-traffic-limit': 838860800,
},
onTaskReady: function (taskId) {
TaskId = taskId;
},
onProgress: function (info) {
cos.cancelTask(TaskId);
cos.abortUploadTask(
{
Bucket: config.Bucket,
Region: config.Region,
Level: 'bucket',
},
function (err, data) {
var nameExist = false;
data.successList.forEach(function (item) {
if (filename === item.Key) {
nameExist = true;
}
});
assert.ok(data.successList.length >= 1);
assert.ok(nameExist);
err ? done(err) : done();
}
);
},
});
});
});
group('headBucket()', function () {
test('headBu