From 85df7a5893668bf196eec8b512fc8c3d3b31e9f8 Mon Sep 17 00:00:00 2001 From: "zhengzuoyu.zzy" Date: Thu, 15 Aug 2024 19:18:52 +0800 Subject: [PATCH] fix: queries sort in signatureUrl and add cases --- README.md | 188 ++++++++--------- lib/browser/managed-upload.js | 10 +- lib/browser/object.js | 9 +- lib/common/bucket/putBucketLifecycle.js | 30 +-- lib/common/multipart.js | 10 +- lib/common/signUtils.js | 10 +- lib/managed-upload.js | 10 +- lib/object.js | 10 +- task/browser-test-build.js | 2 +- test/browser/browser.test.js | 18 +- test/config.js | 4 +- test/node/bucket.test.js | 269 ++++++++++++++++++------ test/node/callback.test.js | 28 +-- test/node/multipart.test.js | 21 +- test/node/multiversion.test.js | 203 +++++++++++++++++- test/node/object.test.js | 20 +- test/node/rtmp.test.js | 53 ++--- 17 files changed, 600 insertions(+), 295 deletions(-) diff --git a/README.md b/README.md index 39420d69..d64afd89 100644 --- a/README.md +++ b/README.md @@ -1760,22 +1760,22 @@ store.put('ossdemo/demo.txt', filepath).then((result) => { console.log(result); }); -{ - name: 'ossdemo/demo.txt', - res: { - status: 200, - headers: { - date: 'Tue, 17 Feb 2015 13:28:17 GMT', - 'content-length': '0', - connection: 'close', - etag: '"BF7A03DA01440845BC5D487B369BC168"', - server: 'AliyunOSS', - 'x-oss-request-id': '54E341F1707AA0275E829244' - }, - size: 0, - rt: 92 - } -} +// { +// name: 'ossdemo/demo.txt', +// res: { +// status: 200, +// headers: { +// date: 'Tue, 17 Feb 2015 13:28:17 GMT', +// 'content-length': '0', +// connection: 'close', +// etag: '"BF7A03DA01440845BC5D487B369BC168"', +// server: 'AliyunOSS', +// 'x-oss-request-id': '54E341F1707AA0275E829244' +// }, +// size: 0, +// rt: 92 +// } +// } ``` - Add an object through content buffer @@ -1785,23 +1785,23 @@ store.put('ossdemo/buffer', Buffer.from('foo content')).then((result) => { console.log(result); }); -{ - name: 'ossdemo/buffer', - url: 'http://demo.oss-cn-hangzhou.aliyuncs.com/ossdemo/buffer', - res: { - status: 200, - headers: { - date: 'Tue, 17 Feb 2015 13:28:17 GMT', - 'content-length': '0', - connection: 'close', - etag: '"xxx"', - server: 'AliyunOSS', - 'x-oss-request-id': '54E341F1707AA0275E829243' - }, - size: 0, - rt: 92 - } -} +// { +// name: 'ossdemo/buffer', +// url: 'http://demo.oss-cn-hangzhou.aliyuncs.com/ossdemo/buffer', +// res: { +// status: 200, +// headers: { +// date: 'Tue, 17 Feb 2015 13:28:17 GMT', +// 'content-length': '0', +// connection: 'close', +// etag: '"xxx"', +// server: 'AliyunOSS', +// 'x-oss-request-id': '54E341F1707AA0275E829243' +// }, +// size: 0, +// rt: 92 +// } +// } ``` - Add an object through readstream @@ -1812,23 +1812,23 @@ store.put('ossdemo/readstream.txt', fs.createReadStream(filepath)).then((result) console.log(result); }); -{ - name: 'ossdemo/readstream.txt', - url: 'http://demo.oss-cn-hangzhou.aliyuncs.com/ossdemo/readstream.txt', - res: { - status: 200, - headers: { - date: 'Tue, 17 Feb 2015 13:28:17 GMT', - 'content-length': '0', - connection: 'close', - etag: '"BF7A03DA01440845BC5D487B369BC168"', - server: 'AliyunOSS', - 'x-oss-request-id': '54E341F1707AA0275E829242' - }, - size: 0, - rt: 92 - } -} +// { +// name: 'ossdemo/readstream.txt', +// url: 'http://demo.oss-cn-hangzhou.aliyuncs.com/ossdemo/readstream.txt', +// res: { +// status: 200, +// headers: { +// date: 'Tue, 17 Feb 2015 13:28:17 GMT', +// 'content-length': '0', +// connection: 'close', +// etag: '"BF7A03DA01440845BC5D487B369BC168"', +// server: 'AliyunOSS', +// 'x-oss-request-id': '54E341F1707AA0275E829242' +// }, +// size: 0, +// rt: 92 +// } +// } ``` ### .putStream(name, stream[, options]) @@ -1883,23 +1883,23 @@ store.putStream('ossdemo/readstream.txt', fs.createReadStream(filepath)).then((r console.log(result); }); -{ - name: 'ossdemo/readstream.txt', - url: 'http://demo.oss-cn-hangzhou.aliyuncs.com/ossdemo/readstream.txt', - res: { - status: 200, - headers: { - date: 'Tue, 17 Feb 2015 13:28:17 GMT', - 'content-length': '0', - connection: 'close', - etag: '"BF7A03DA01440845BC5D487B369BC168"', - server: 'AliyunOSS', - 'x-oss-request-id': '54E341F1707AA0275E829242' - }, - size: 0, - rt: 92 - } -} +// { +// name: 'ossdemo/readstream.txt', +// url: 'http://demo.oss-cn-hangzhou.aliyuncs.com/ossdemo/readstream.txt', +// res: { +// status: 200, +// headers: { +// date: 'Tue, 17 Feb 2015 13:28:17 GMT', +// 'content-length': '0', +// connection: 'close', +// etag: '"BF7A03DA01440845BC5D487B369BC168"', +// server: 'AliyunOSS', +// 'x-oss-request-id': '54E341F1707AA0275E829242' +// }, +// size: 0, +// rt: 92 +// } +// } ``` ### .append(name, file[, options]) @@ -2020,14 +2020,14 @@ await this.store.put('ossdemo/head-meta', Buffer.from('foo'), { const object = await this.store.head('ossdemo/head-meta'); console.log(object); -{ - status: 200, - meta: { - uid: '1', - path: 'foo/demo.txt' - }, - res: { ... } -} +// { +// status: 200, +// meta: { +// uid: '1', +// path: 'foo/demo.txt' +// }, +// res: { ... } +// } ``` - Head a not exists object @@ -2065,10 +2065,10 @@ await this.store.put('ossdemo/object-meta', Buffer.from('foo')); const object = await this.store.getObjectMeta('ossdemo/object-meta'); console.log(object); -{ - status: 200, - res: { ... } -} +// { +// status: 200, +// res: { ... } +// } ``` ### .get(name[, file, options]) @@ -3341,7 +3341,7 @@ parameters: - file {String|File(only support Browser)|Blob(only support Browser)|Buffer} file path or HTML5 Web File or web Blob or content buffer - [options] {Object} optional args - [parallel] {Number} the number of parts to be uploaded in parallel - - [partSize] {Number} the suggested size for each part, defalut `1024 * 1024`(1MB), minimum `100 * 1024`(100KB) + - [partSize] {Number} the suggested size for each part, default `1024 * 1024`(1MB), minimum `100 * 1024`(100KB) - [progress] {Function} function | async | Promise, the progress callback called after each successful upload of one part, it will be given three parameters: (percentage {Number}, checkpoint {Object}, res {Object}) @@ -3452,7 +3452,6 @@ const result2 = await store.multipartUpload('object', '/tmp/file', { > tips: abort multipartUpload support on node and browser ```js - //start upload let abortCheckpoint; store.multipartUpload('object', '/tmp/file', { @@ -3461,17 +3460,16 @@ store.multipartUpload('object', '/tmp/file', { } }).then(res => { // do something -}.catch(err => { +}).catch(err => { //if abort will catch abort event if (err.name === 'abort') { // handle abort console.log('error: ', err.message) } -})) +}); // abort -store.abortMultipartUpload(abortCheckpoint.name, abortCheckpoint.uploadId) - +store.abortMultipartUpload(abortCheckpoint.name, abortCheckpoint.uploadId); ``` - multipartUpload with cancel @@ -3624,8 +3622,7 @@ console.log(result); - multipartUploadCopy with abort ```js - -//start upload +// start upload let abortCheckpoint; store.multipartUploadCopy('object', { sourceKey: 'sourceKey', @@ -3636,18 +3633,17 @@ store.multipartUploadCopy('object', { } }).then(res => { // do something -}.catch(err => { +}).catch(err => { //if abort will catch abort event if (err.name === 'abort') { // handle abort console.log('error: ', err.message) } -})) - -//the other event to abort, for example: click event -//to abort upload must use the same client instance -store.abortMultipartUpload(abortCheckpoint.name, abortCheckpoint.uploadId) +}); +// the other event to abort, for example: click event +// to abort upload must use the same client instance +store.abortMultipartUpload(abortCheckpoint.name, abortCheckpoint.uploadId); ``` - multipartUploadCopy with cancel @@ -4245,7 +4241,7 @@ const oss = require('ali-oss'); const imgClient = oss.ImageClient({ accessKeyId: 'your access key', accessKeySecret: 'your access secret', - bucket: 'my_image_bucket' + bucket: 'my_image_bucket', imageHost: 'thumbnail.myimageservice.com' }); ``` @@ -4616,9 +4612,7 @@ Success will return full signature url. example: ```js -const url = imgClient.signatureUrl(' -'); -// http://thumbnail.myimageservice.com/demo.jpg@200w_200h?OSSAccessKeyId=uZxyLARzYZtGwHKY&Expires=1427803849&Signature=JSPRe06%2FjQpQSj5zlx2ld1V%2B35I%3D +const url = imgClient.signatureUrl('name'); ``` ## Cluster Mode diff --git a/lib/browser/managed-upload.js b/lib/browser/managed-upload.js index 8bfe25bf..61d21419 100644 --- a/lib/browser/managed-upload.js +++ b/lib/browser/managed-upload.js @@ -18,13 +18,13 @@ const proto = exports; * @param {String} name * @param {String|File|Buffer} file * @param {Object} options - * {Object} options.callback The callback parameter is composed of a JSON string encoded in Base64 + * {Object} [options.callback] The callback parameter is composed of a JSON string encoded in Base64 * {String} options.callback.url the OSS sends a callback request to this URL - * {String} options.callback.host The host header value for initiating callback requests + * {String} [options.callback.host] The host header value for initiating callback requests * {String} options.callback.body The value of the request body when a callback is initiated - * {String} options.callback.contentType The Content-Type of the callback requests initiatiated - * {Boolean} options.callback.callbackSNI Do you want to send the Server Name Indication - * {Object} options.callback.customValue Custom parameters are a map of key-values, e.g: + * {String} [options.callback.contentType] The Content-Type of the callback requests initiated + * {Boolean} [options.callback.callbackSNI] Whether OSS sends SNI to the origin address specified by callbackUrl when a callback request is initiated from the client + * {Object} [options.callback.customValue] Custom parameters are a map of key-values, e.g: * customValue = { * key1: 'value1', * key2: 'value2' diff --git a/lib/browser/object.js b/lib/browser/object.js index eccf4472..30cfb1bc 100644 --- a/lib/browser/object.js +++ b/lib/browser/object.js @@ -44,12 +44,13 @@ proto.append = async function append(name, file, options) { * @param {String} name the object key * @param {Mixed} file String(file path)/Buffer/ReadableStream * @param {Object} options - * {Object} options.callback The callback parameter is composed of a JSON string encoded in Base64 + * {Object} [options.callback] The callback parameter is composed of a JSON string encoded in Base64 * {String} options.callback.url the OSS sends a callback request to this URL - * {String} options.callback.host The host header value for initiating callback requests + * {String} [options.callback.host] The host header value for initiating callback requests * {String} options.callback.body The value of the request body when a callback is initiated - * {String} options.callback.contentType The Content-Type of the callback requests initiatiated - * {Object} options.callback.customValue Custom parameters are a map of key-values, e.g: + * {String} [options.callback.contentType] The Content-Type of the callback requests initiated + * {Boolean} [options.callback.callbackSNI] Whether OSS sends SNI to the origin address specified by callbackUrl when a callback request is initiated from the client + * {Object} [options.callback.customValue] Custom parameters are a map of key-values, e.g: * customValue = { * key1: 'value1', * key2: 'value2' diff --git a/lib/common/bucket/putBucketLifecycle.js b/lib/common/bucket/putBucketLifecycle.js index 838d80b9..f3e601b1 100644 --- a/lib/common/bucket/putBucketLifecycle.js +++ b/lib/common/bucket/putBucketLifecycle.js @@ -66,7 +66,7 @@ function checkDaysAndDate(obj, key) { const { days, createdBeforeDate } = obj; if (!days && !createdBeforeDate) { throw new Error(`${key} must includes days or createdBeforeDate`); - } else if (days && !/^[1-9][0-9]*$/.test(days)) { + } else if (days && (isArray(days) || !/^[1-9][0-9]*$/.test(days))) { throw new Error('days must be a positive integer'); } else if (createdBeforeDate && !/\d{4}-\d{2}-\d{2}T00:00:00.000Z/.test(createdBeforeDate)) { throw new Error('createdBeforeDate must be date and conform to iso8601 format'); @@ -77,7 +77,7 @@ function checkNoncurrentDays(obj, key) { const { noncurrentDays } = obj; if (!noncurrentDays) { throw new Error(`${key} must includes noncurrentDays`); - } else if (noncurrentDays && !/^[1-9][0-9]*$/.test(noncurrentDays)) { + } else if (noncurrentDays && (isArray(noncurrentDays) || !/^[1-9][0-9]*$/.test(noncurrentDays))) { throw new Error('noncurrentDays must be a positive integer'); } } @@ -106,7 +106,19 @@ function checkRule(rule) { if (rule.prefix === undefined) throw new Error('Rule must includes prefix'); - if (!['Enabled', 'Disabled'].includes(rule.status)) throw new Error('Status must be Enabled or Disabled'); + if (!['Enabled', 'Disabled'].includes(rule.status)) throw new Error('Status must be Enabled or Disabled'); + + if ( + !rule.expiration && + !rule.noncurrentVersionExpiration && + !rule.abortMultipartUpload && + !rule.transition && + !rule.noncurrentVersionTransition + ) { + throw new Error( + 'Rule must includes expiration or noncurrentVersionExpiration or abortMultipartUpload or transition or noncurrentVersionTransition' + ); + } if (rule.transition) { checkStorageClass(rule.transition.storageClass); @@ -125,18 +137,6 @@ function checkRule(rule) { checkDaysAndDate(rule.abortMultipartUpload, 'AbortMultipartUpload'); } - if ( - !rule.expiration && - !rule.noncurrentVersionExpiration && - !rule.abortMultipartUpload && - !rule.transition && - !rule.noncurrentVersionTransition - ) { - throw new Error( - 'Rule must includes expiration or noncurrentVersionExpiration or abortMultipartUpload or transition or noncurrentVersionTransition' - ); - } - if (rule.noncurrentVersionTransition) { checkStorageClass(rule.noncurrentVersionTransition.storageClass); checkNoncurrentDays(rule.noncurrentVersionTransition, 'NoncurrentVersionTransition'); diff --git a/lib/common/multipart.js b/lib/common/multipart.js index da4da338..716c4852 100644 --- a/lib/common/multipart.js +++ b/lib/common/multipart.js @@ -160,13 +160,13 @@ proto.uploadPart = async function uploadPart(name, uploadId, partNo, file, start * {Integer} number partNo * {String} etag part etag uploadPartCopy result.res.header.etag * @param {Object} options - * {Object} options.callback The callback parameter is composed of a JSON string encoded in Base64 + * {Object} [options.callback] The callback parameter is composed of a JSON string encoded in Base64 * {String} options.callback.url the OSS sends a callback request to this URL - * {String} options.callback.host The host header value for initiating callback requests + * {String} [options.callback.host] The host header value for initiating callback requests * {String} options.callback.body The value of the request body when a callback is initiated - * {String} options.callback.contentType The Content-Type of the callback requests initiatiated - * {Boolean} options.callback.callbackSNI Do you want to send the Server Name Indication - * {Object} options.callback.customValue Custom parameters are a map of key-values, e.g: + * {String} [options.callback.contentType] The Content-Type of the callback requests initiated + * {Boolean} [options.callback.callbackSNI] Whether OSS sends SNI to the origin address specified by callbackUrl when a callback request is initiated from the client + * {Object} [options.callback.customValue] Custom parameters are a map of key-values, e.g: * customValue = { * key1: 'value1', * key2: 'value2' diff --git a/lib/common/signUtils.js b/lib/common/signUtils.js index 69800cfd..2781b2e6 100644 --- a/lib/common/signUtils.js +++ b/lib/common/signUtils.js @@ -20,14 +20,6 @@ exports.buildCanonicalizedResource = function buildCanonicalizedResource(resourc parameters.sort(); canonicalizedResource += separatorString + parameters.join('&'); } else if (parameters) { - const compareFunc = (entry1, entry2) => { - if (entry1[0] > entry2[0]) { - return 1; - } else if (entry1[0] < entry2[0]) { - return -1; - } - return 0; - }; const processFunc = key => { canonicalizedResource += separatorString + key; if (parameters[key] || parameters[key] === 0) { @@ -35,7 +27,7 @@ exports.buildCanonicalizedResource = function buildCanonicalizedResource(resourc } separatorString = '&'; }; - Object.keys(parameters).sort(compareFunc).forEach(processFunc); + Object.keys(parameters).sort().forEach(processFunc); } return canonicalizedResource; diff --git a/lib/managed-upload.js b/lib/managed-upload.js index 5cae4c0c..45c62eb1 100644 --- a/lib/managed-upload.js +++ b/lib/managed-upload.js @@ -19,13 +19,13 @@ const proto = exports; * @param {String} name * @param {String|File|Buffer} file * @param {Object} options - * {Object} options.callback The callback parameter is composed of a JSON string encoded in Base64 + * {Object} [options.callback] The callback parameter is composed of a JSON string encoded in Base64 * {String} options.callback.url the OSS sends a callback request to this URL - * {String} options.callback.host The host header value for initiating callback requests + * {String} [options.callback.host] The host header value for initiating callback requests * {String} options.callback.body The value of the request body when a callback is initiated - * {String} options.callback.contentType The Content-Type of the callback requests initiatiated - * {Boolean} options.callback.callbackSNI Do you want to send the Server Name Indication - * {Object} options.callback.customValue Custom parameters are a map of key-values, e.g: + * {String} [options.callback.contentType] The Content-Type of the callback requests initiated + * {Boolean} [options.callback.callbackSNI] Whether OSS sends SNI to the origin address specified by callbackUrl when a callback request is initiated from the client + * {Object} [options.callback.customValue] Custom parameters are a map of key-values, e.g: * customValue = { * key1: 'value1', * key2: 'value2' diff --git a/lib/object.js b/lib/object.js index 91e4a746..25d81faa 100644 --- a/lib/object.js +++ b/lib/object.js @@ -43,13 +43,13 @@ proto.append = async function append(name, file, options) { * @param {String} name the object key * @param {Mixed} file String(file path)/Buffer/ReadableStream * @param {Object} options - * {Object} options.callback The callback parameter is composed of a JSON string encoded in Base64 + * {Object} [options.callback] The callback parameter is composed of a JSON string encoded in Base64 * {String} options.callback.url the OSS sends a callback request to this URL - * {String} options.callback.host The host header value for initiating callback requests + * {String} [options.callback.host] The host header value for initiating callback requests * {String} options.callback.body The value of the request body when a callback is initiated - * {String} options.callback.contentType The Content-Type of the callback requests initiatiated - * {Boolean} options.callback.callbackSNI Do you want to send the Server Name Indication - * {Object} options.callback.customValue Custom parameters are a map of key-values, e.g: + * {String} [options.callback.contentType] The Content-Type of the callback requests initiated + * {Boolean} [options.callback.callbackSNI] Whether OSS sends SNI to the origin address specified by callbackUrl when a callback request is initiated from the client + * {Object} [options.callback.customValue] Custom parameters are a map of key-values, e.g: * customValue = { * key1: 'value1', * key2: 'value2' diff --git a/task/browser-test-build.js b/task/browser-test-build.js index 0bf20289..63f758e7 100644 --- a/task/browser-test-build.js +++ b/task/browser-test-build.js @@ -40,7 +40,7 @@ function build(options, callback) { stsConfFile, JSON.stringify( Object.assign({}, stsConf, { - callbackServer: env.ALI_SDK_CALLBACK_IP, + // callbackServer: env.ALI_SDK_CALLBACK_IP, bucket: conf.bucket, region: conf.region }) diff --git a/test/browser/browser.test.js b/test/browser/browser.test.js index 43498415..ad9a8abb 100644 --- a/test/browser/browser.test.js +++ b/test/browser/browser.test.js @@ -1189,12 +1189,17 @@ describe('browser', () => { it('should signature url with response limitation', async () => { const response = { - 'content-type': 'xml', - 'content-language': 'zh-cn' + 'content-disposition': 'a.js', + 'cache-control': 'no-cache' }; const url = store.signatureUrl(name, { response }); - assert(url.indexOf('response-content-type=xml') !== -1); - assert(url.indexOf('response-content-language=zh-cn') !== -1); + const res = await urllib.request(url, { + method: 'GET' + }); + + assert.strictEqual(res.status, 200); + assert.strictEqual(res.headers['cache-control'], 'no-cache'); + assert.strictEqual(res.headers['content-disposition'], 'a.js'); }); it('should signature url with custom host ok', () => { @@ -1838,7 +1843,6 @@ describe('browser', () => { // /* eslint no-template-curly-in-string: [0] */ // body: 'bucket=${bucket}&object=${object}&var1=${x:var1}', // contentType: 'application/x-www-form-urlencoded', - // callbackSNI: true, // customValue: { // var1: 'value1', // var2: 'value2' @@ -1847,7 +1851,7 @@ describe('browser', () => { // }); // assert.equal(result.res.status, 200); - // assert.equal(result.data.object, name); + // assert.equal(result.data.Status, 'OK'); // }); // TODO fix callback server @@ -1872,7 +1876,7 @@ describe('browser', () => { // } // }); // assert.equal(result.res.status, 200); - // assert.equal(result.data.object, name); + // assert.equal(result.data.Status, 'OK'); // }); // TODO fix callback server diff --git a/test/config.js b/test/config.js index 712c29c1..886f52a4 100644 --- a/test/config.js +++ b/test/config.js @@ -18,8 +18,8 @@ config.sts = { roleArn: env.ALI_SDK_STS_ROLE, bucket: env.ALI_SDK_STS_BUCKET, // endpoint: env.ONCI ? 'https://sts.aliyuncs.com/' : undefined, - maxSocket: 50, - callbackServer: env.ALI_SDK_CALLBACK_IP + maxSocket: 50 + // callbackServer: env.ALI_SDK_CALLBACK_IP }; config.metaSyncTime = env.ONCI ? '1s' : '1000ms'; diff --git a/test/node/bucket.test.js b/test/node/bucket.test.js index 83d1c428..d2b88671 100644 --- a/test/node/bucket.test.js +++ b/test/node/bucket.test.js @@ -764,27 +764,21 @@ describe('test/bucket.test.js', () => { }); describe('putBucketLifecycle()', () => { - it('should put the lifecycle throw error', async () => { + it('should the type of rules be Array', async () => { try { - await store.putBucketLifecycle(bucket, [ - { - id: 'expiration1', - prefix: 'logs/', - status: 'Enabled', - day: 1 - } - ]); + await store.putBucketLifecycle(bucket, { + id: 'expiration1', + prefix: 'test', + status: 'Enabled' + }); assert.fail('expected an error to be thrown'); } catch (e) { - assert.equal( - e.message, - 'Rule must includes expiration or noncurrentVersionExpiration or abortMultipartUpload or transition or noncurrentVersionTransition' - ); + assert.strictEqual(e.message, 'rules must be Array'); } }); it('should put the lifecycle with old api', async () => { - const putresult1 = await store.putBucketLifecycle(bucket, [ + const res1 = await store.putBucketLifecycle(bucket, [ { id: 'expiration1', prefix: 'logs/', @@ -793,9 +787,9 @@ describe('test/bucket.test.js', () => { } ]); - assert.equal(putresult1.res.status, 200); + assert.strictEqual(res1.res.status, 200); - const putresult2 = await store.putBucketLifecycle(bucket, [ + const res2 = await store.putBucketLifecycle(bucket, [ { id: 'expiration2', prefix: 'logs/', @@ -803,11 +797,11 @@ describe('test/bucket.test.js', () => { date: '2020-02-18T00:00:00.000Z' } ]); - assert.equal(putresult2.res.status, 200); + assert.strictEqual(res2.res.status, 200); }); it('should put the lifecycle with expiration and id', async () => { - const putresult1 = await store.putBucketLifecycle(bucket, [ + const res1 = await store.putBucketLifecycle(bucket, [ { id: 'expiration1', prefix: 'logs/', @@ -817,12 +811,12 @@ describe('test/bucket.test.js', () => { } } ]); - assert.equal(putresult1.res.status, 200); + assert.strictEqual(res1.res.status, 200); const getBucketLifecycle = await store.getBucketLifecycle(bucket); assert(getBucketLifecycle.rules.length > 0 && getBucketLifecycle.rules.find(v => v.id === 'expiration1')); - const putresult2 = await store.putBucketLifecycle(bucket, [ + const res2 = await store.putBucketLifecycle(bucket, [ { id: 'expiration2', prefix: 'logs/', @@ -832,11 +826,11 @@ describe('test/bucket.test.js', () => { } } ]); - assert.equal(putresult2.res.status, 200); + assert.strictEqual(res2.res.status, 200); }); it('should put the lifecycle with AbortMultipartUpload', async () => { - const putresult1 = await store.putBucketLifecycle(bucket, [ + const res1 = await store.putBucketLifecycle(bucket, [ { id: 'abortMultipartUpload1', prefix: 'logs/', @@ -846,9 +840,9 @@ describe('test/bucket.test.js', () => { } } ]); - assert.equal(putresult1.res.status, 200); + assert.strictEqual(res1.res.status, 200); - const putresult2 = await store.putBucketLifecycle(bucket, [ + const res2 = await store.putBucketLifecycle(bucket, [ { id: 'abortMultipartUpload2', prefix: 'logs/', @@ -858,25 +852,26 @@ describe('test/bucket.test.js', () => { } } ]); - assert.equal(putresult2.res.status, 200); + assert.strictEqual(res2.res.status, 200); }); it('should put the lifecycle with empty prefix (whole bucket)', async () => { - const putresult = await store.putBucketLifecycle(bucket, [ + const res = await store.putBucketLifecycle(bucket, [ { id: 'abortMultipartUpload1', - prefix: '', // empty prefix (whole bucket) + prefix: '', status: 'Enabled', abortMultipartUpload: { days: 1 } } ]); - assert.equal(putresult.res.status, 200); + + assert.strictEqual(res.res.status, 200); }); it('should put the lifecycle with Transition', async () => { - const putresult1 = await store.putBucketLifecycle(bucket, [ + const res1 = await store.putBucketLifecycle(bucket, [ { id: 'transition', prefix: 'logs/', @@ -894,9 +889,9 @@ describe('test/bucket.test.js', () => { } } ]); - assert.equal(putresult1.res.status, 200); + assert.strictEqual(res1.res.status, 200); - const putresult2 = await store.putBucketLifecycle(bucket, [ + const res2 = await store.putBucketLifecycle(bucket, [ { id: 'transition', prefix: 'logs/', @@ -911,8 +906,9 @@ describe('test/bucket.test.js', () => { } } ]); - assert.equal(putresult2.res.status, 200); - const putresult3 = await store.putBucketLifecycle(bucket, [ + assert.strictEqual(res2.res.status, 200); + + const res3 = await store.putBucketLifecycle(bucket, [ { id: 'transition3', prefix: 'logs/', @@ -927,9 +923,10 @@ describe('test/bucket.test.js', () => { } } ]); - assert.equal(putresult3.res.status, 200); + assert.strictEqual(res3.res.status, 200); + // Regions that need to support DeepColdArchive - const putresult4 = await store.putBucketLifecycle(bucket, [ + const res4 = await store.putBucketLifecycle(bucket, [ { id: 'transition4', prefix: 'logs/', @@ -944,11 +941,11 @@ describe('test/bucket.test.js', () => { } } ]); - assert.equal(putresult4.res.status, 200); + assert.strictEqual(res4.res.status, 200); }); it('should put the lifecycle with expiration and Tag', async () => { - const putresult1 = await store.putBucketLifecycle(bucket, [ + const res1 = await store.putBucketLifecycle(bucket, [ { id: 'tag1', prefix: 'logs/', @@ -962,9 +959,9 @@ describe('test/bucket.test.js', () => { } } ]); - assert.equal(putresult1.res.status, 200); + assert.strictEqual(res1.res.status, 200); - const putresult2 = await store.putBucketLifecycle(bucket, [ + const res2 = await store.putBucketLifecycle(bucket, [ { id: 'tag2', prefix: 'logs/', @@ -978,9 +975,9 @@ describe('test/bucket.test.js', () => { } } ]); - assert.equal(putresult2.res.status, 200); + assert.strictEqual(res2.res.status, 200); - const putresult3 = await store.putBucketLifecycle(bucket, [ + const res3 = await store.putBucketLifecycle(bucket, [ { id: 'tag2', prefix: 'logs/', @@ -1000,7 +997,7 @@ describe('test/bucket.test.js', () => { ] } ]); - assert.equal(putresult3.res.status, 200); + assert.strictEqual(res3.res.status, 200); }); it('should throw error when id more than 255 bytes ', async () => { @@ -1009,8 +1006,11 @@ describe('test/bucket.test.js', () => { await store.putBucketLifecycle(bucket, [ { id: testID, - prefix: 'testid/', - status: 'Enabled' + prefix: '', + status: 'Disabled', + expiration: { + days: 1 + } } ]); assert(false); @@ -1038,20 +1038,27 @@ describe('test/bucket.test.js', () => { await store.putBucketLifecycle(bucket, [ { id: 'status', - prefix: 'fix/', - status: 'test' + prefix: '', + status: 'test', + expiration: { + days: 1 + } } ]); assert(false); } catch (error) { assert(error.message.includes('Enabled or Disabled')); } + try { await store.putBucketLifecycle(bucket, [ { id: 'status', - prefix: 'fix/', - status: '' + prefix: '', + status: '', + expiration: { + days: 1 + } } ]); assert(false); @@ -1060,7 +1067,7 @@ describe('test/bucket.test.js', () => { } }); - it('should throw error when storageClass is not Archive or IA', async () => { + it('should throw error when storageClass is not an illegal value', async () => { try { await store.putBucketLifecycle(bucket, [ { @@ -1132,6 +1139,57 @@ describe('test/bucket.test.js', () => { } catch (error) { assert(error.message.includes(errorMessage)); } + + try { + await store.putBucketLifecycle(bucket, [ + { + id: 'transition', + prefix: 'fix/', + status: 'Enabled', + transition: { + days: true, + storageClass: 'Archive' + } + } + ]); + assert(false); + } catch (error) { + assert(error.message.includes(errorMessage)); + } + + try { + await store.putBucketLifecycle(bucket, [ + { + id: 'transition', + prefix: 'fix/', + status: 'Enabled', + transition: { + days: [1], + storageClass: 'Archive' + } + } + ]); + assert(false); + } catch (error) { + assert(error.message.includes(errorMessage)); + } + + try { + await store.putBucketLifecycle(bucket, [ + { + id: 'transition', + prefix: 'fix/', + status: 'Enabled', + transition: { + days: -1, + storageClass: 'Archive' + } + } + ]); + assert(false); + } catch (error) { + assert(error.message.includes(errorMessage)); + } }); it('should throw error when createdBeforeDate of transition is not iso8601 format', async () => { @@ -1257,18 +1315,21 @@ describe('test/bucket.test.js', () => { } }); - it('should throw error when rule have no expiration or abortMultipartUpload', async () => { - const errorMessage = 'expiration or noncurrentVersionExpiration or abortMultipartUpload'; + it('should throw error when rule have no expiration or noncurrentVersionExpiration or abortMultipartUpload or transition or noncurrentVersionTransition', async () => { try { await store.putBucketLifecycle(bucket, [ { - prefix: 'expirationAndAbortMultipartUpload/', + id: 'expiration1', + prefix: '', status: 'Enabled' } ]); - assert(false); - } catch (error) { - assert(error.message.includes(errorMessage)); + assert.fail('expected an error to be thrown'); + } catch (e) { + assert.strictEqual( + e.message, + 'Rule must includes expiration or noncurrentVersionExpiration or abortMultipartUpload or transition or noncurrentVersionTransition' + ); } }); @@ -1291,16 +1352,66 @@ describe('test/bucket.test.js', () => { } } ]); - assert(false); + assert.fail('Expects to throw an error'); } catch (error) { assert(error.message.includes(errorMessage)); } }); + + it('should type of tag is Array or Object', async () => { + try { + await store.putBucketLifecycle(bucket, [ + { + prefix: '', + status: 'Enabled', + expiration: { + days: 1 + }, + tag: 1 + } + ]); + assert.fail('Expects to throw an error'); + } catch (error) { + assert.strictEqual(error.message, 'tag must be Object or Array'); + } + + try { + await store.putBucketLifecycle(bucket, [ + { + prefix: '', + status: 'Enabled', + expiration: { + days: 1 + }, + tag: true + } + ]); + assert.fail('Expects to throw an error'); + } catch (error) { + assert.strictEqual(error.message, 'tag must be Object or Array'); + } + + try { + await store.putBucketLifecycle(bucket, [ + { + prefix: '', + status: 'Enabled', + expiration: { + days: 1 + }, + tag: 'a' + } + ]); + assert.fail('Expects to throw an error'); + } catch (error) { + assert.strictEqual(error.message, 'tag must be Object or Array'); + } + }); }); describe('getBucketLifecycle()', () => { it('should get the lifecycle', async () => { - const putresult = await store.putBucketLifecycle(bucket, [ + const res = await store.putBucketLifecycle(bucket, [ { id: 'get_test', prefix: 'logs/', @@ -1320,17 +1431,51 @@ describe('test/bucket.test.js', () => { ] } ]); - assert.equal(putresult.res.status, 200); + assert.strictEqual(res.res.status, 200); const getBucketLifecycle = await store.getBucketLifecycle(bucket); assert(getBucketLifecycle.rules.length > 0); - assert.equal(getBucketLifecycle.res.status, 200); + assert.strictEqual(getBucketLifecycle.res.status, 200); + }); + + it('should get the lifecycle with one tag', async () => { + const putRes = await store.putBucketLifecycle( + bucket, + [ + { + id: 'get_test', + prefix: '', + status: 'Enabled', + expiration: { + days: 1 + }, + tag: [ + { + key: 'test2', + value: '2' + } + ] + } + ], + { + headers: { + 'x-oss-allow-same-action-overlap': 'true' + } + } + ); + assert.strictEqual(putRes.res.status, 200); + + const getRes = await store.getBucketLifecycle(bucket); + + assert.strictEqual(getRes.res.status, 200); + assert(getRes.rules.length > 0); + assert(getRes.rules[0].tag.length === 1); }); }); describe('deleteBucketLifecycle()', () => { it('should delete the lifecycle', async () => { - const putresult = await store.putBucketLifecycle(bucket, [ + const putResult = await store.putBucketLifecycle(bucket, [ { id: 'delete', prefix: 'logs/', @@ -1350,11 +1495,11 @@ describe('test/bucket.test.js', () => { ] } ]); - assert.equal(putresult.res.status, 200); + assert.strictEqual(putResult.res.status, 200); // delete it const deleteResult = await store.deleteBucketLifecycle(bucket); - assert.equal(deleteResult.res.status, 204); + assert.strictEqual(deleteResult.res.status, 204); }); }); diff --git a/test/node/callback.test.js b/test/node/callback.test.js index d961317d..f514087b 100644 --- a/test/node/callback.test.js +++ b/test/node/callback.test.js @@ -1,4 +1,3 @@ -// /* eslint-disable @typescript-eslint/no-require-imports */ // // TODO callback server is disable // const fs = require('fs'); // const assert = require('assert'); @@ -8,11 +7,6 @@ // const config = require('../config').oss; // const mm = require('mm'); -// /* -// * temp test callback -// * multipartUpload -// * put -// */ // describe.only('test/callback.test.js', () => { // const { prefix } = utils; // let store; @@ -27,10 +21,6 @@ // store.useBucket(bucket, bucketRegion); // }); -// after(async () => { -// // await utils.cleanBucket(store, bucket, bucketRegion); -// }); - // describe('upload callback', () => { // afterEach(mm.restore); // it('should multipart upload parse response with callback false', async () => { @@ -55,8 +45,7 @@ // } // }); // assert.equal(result.res.status, 200); -// const { sni } = result.data; -// assert.equal(sni, false); +// assert.equal(result.data.Status, 'OK'); // }); // it('should multipart upload parse response with callback', async () => { @@ -81,10 +70,7 @@ // } // }); // assert.equal(result.res.status, 200); -// const { sni, var1: va, object: obj } = result.data; -// assert.equal(sni, host); -// assert.equal(var1, va); -// assert.equal(obj, name); +// assert.equal(result.data.Status, 'OK'); // }); // it('should multipart upload copy with callback', async () => { @@ -120,7 +106,7 @@ // ); // assert.equal(result.res.status, 200); -// assert.equal(result.data.object, copyName); +// assert.equal(result.data.Status, 'OK'); // }); // it('should multipart upload with no more 100k file parse response with callback', async () => { @@ -142,7 +128,7 @@ // } // }); // assert.equal(result.res.status, 200); -// assert.equal(result.data.object, name); +// assert.equal(result.data.Status, 'OK'); // }); // it('should putStream parse response with callback', async () => { @@ -162,7 +148,7 @@ // }); // assert.equal(result.res.status, 200); -// assert.equal(result.data.object, name); +// assert.equal(result.data.Status, 'OK'); // }); // it('should put parse response with callback', async () => { @@ -182,7 +168,7 @@ // }); // assert.equal(result.res.status, 200); -// assert.equal(result.data.object, name); +// assert.equal(result.data.Status, 'OK'); // }); // it('should multipart upload with no more 100k file use header x-oss-callback', async () => { @@ -200,7 +186,7 @@ // } // }); // assert.equal(result.res.status, 200); -// assert.equal(result.data.object, name); +// assert.equal(result.data.Status, 'OK'); // }); // }); // }); diff --git a/test/node/multipart.test.js b/test/node/multipart.test.js index a4d18adf..8d52b1d1 100644 --- a/test/node/multipart.test.js +++ b/test/node/multipart.test.js @@ -972,19 +972,18 @@ describe('test/multipart.test.js', () => { const fileName = await utils.createTempFile(`multipart-upload-file-${Date.now()}`, 1024 * 1024); const name = `${prefix}multipart/upload-file-${Date.now()}`; const name1 = `${prefix}multipart/upload-file-1-${Date.now()}`; + try { - const p1 = store.multipartUpload(name, fileName); - const p2 = store.multipartUpload(name1, fileName).catch(error => { - console.log('info >', error.message); - }); - await Promise.all([p1, p2]); - } catch (e) {} + await Promise.all([store.multipartUpload(name, fileName), store.multipartUpload(name1, fileName)]); + assert.fail('Expects to throw an error'); + } catch (e) { + assert(e.message.includes('mock upload part fail.')); + } + mm.restore(); - const p3 = store.multipartUpload(name, fileName); - const p4 = store.multipartUpload(name1, fileName).catch(error => { - console.log('info >', error.message); - }); - await Promise.all([p3, p4]); + + await Promise.all([store.multipartUpload(name, fileName), store.multipartUpload(name1, fileName)]); + assert.strictEqual(store.multipartUploadStreams.length, 0); }); diff --git a/test/node/multiversion.test.js b/test/node/multiversion.test.js index 8af82d61..4c8bfb91 100644 --- a/test/node/multiversion.test.js +++ b/test/node/multiversion.test.js @@ -58,6 +58,36 @@ describe('test/multiversion.test.js', () => { assert(false, err.message); } }); + + it('should set bucket version valid', async () => { + try { + await store.putBucketVersioning(bucket, 'Start'); + assert.fail('Expects to throw an error'); + } catch (err) { + assert.strictEqual(err.message, 'status must be Enabled or Suspended'); + } + + try { + await store.putBucketVersioning(bucket, 'Close'); + assert.fail('Expects to throw an error'); + } catch (err) { + assert.strictEqual(err.message, 'status must be Enabled or Suspended'); + } + + try { + await store.putBucketVersioning(bucket, true); + assert.fail('Expects to throw an error'); + } catch (err) { + assert.strictEqual(err.message, 'status must be Enabled or Suspended'); + } + + try { + await store.putBucketVersioning(bucket, 1); + assert.fail('Expects to throw an error'); + } catch (err) { + assert.strictEqual(err.message, 'status must be Enabled or Suspended'); + } + }); }); describe('getBucketVersions()', () => { @@ -119,7 +149,7 @@ describe('test/multiversion.test.js', () => { describe('putBucketLifecycle() getBucketLifecycle()', async () => { it('should putBucketLifecycle with noncurrentVersionExpiration', async () => { - const putresult1 = await store.putBucketLifecycle( + const res = await store.putBucketLifecycle( bucket, [ { @@ -133,7 +163,7 @@ describe('test/multiversion.test.js', () => { } }, { - prefix: 'logss/', + prefix: 'logs2/', status: 'Enabled', noncurrentVersionExpiration: { noncurrentDays: 1 @@ -145,13 +175,13 @@ describe('test/multiversion.test.js', () => { } ); await utils.sleep(ms(metaSyncTime)); - assert.strictEqual(putresult1.res.status, 200); + assert.strictEqual(res.res.status, 200); const { rules } = await store.getBucketLifecycle(bucket); assert.strictEqual(rules[0].noncurrentVersionExpiration.noncurrentDays, '1'); }); it('should putBucketLifecycle with expiredObjectDeleteMarker', async () => { - const putresult1 = await store.putBucketLifecycle(bucket, [ + const res = await store.putBucketLifecycle(bucket, [ { id: 'expiration1', prefix: 'logs/', @@ -164,14 +194,50 @@ describe('test/multiversion.test.js', () => { } } ]); - assert.equal(putresult1.res.status, 200); + + assert.strictEqual(res.res.status, 200); await utils.sleep(2000); + const { rules } = await store.getBucketLifecycle(bucket); assert.strictEqual(rules[0].expiration.expiredObjectDeleteMarker, 'true'); }); + it('should expiredObjectDeleteMarker cannot be used with days or createdBeforeDate', async () => { + try { + await store.putBucketLifecycle(bucket, [ + { + prefix: '', + status: 'Enabled', + expiration: { + expiredObjectDeleteMarker: 'true', + days: 1 + } + } + ]); + assert.fail('Expects to throw an error'); + } catch (e) { + assert.strictEqual(e.message, 'expiredObjectDeleteMarker cannot be used with days or createdBeforeDate'); + } + + try { + await store.putBucketLifecycle(bucket, [ + { + prefix: '', + status: 'Enabled', + expiration: { + expiredObjectDeleteMarker: 'true', + createdBeforeDate: '2020-02-18T00:00:00.000Z' + } + } + ]); + assert.fail('Expects to throw an error'); + } catch (e) { + assert.strictEqual(e.message, 'expiredObjectDeleteMarker cannot be used with days or createdBeforeDate'); + } + }); + it('should putBucketLifecycle with noncurrentVersionTransition', async () => { - const putresult = await store.putBucketLifecycle( + const res = await store.putBucketLifecycle( bucket, [ { @@ -186,7 +252,7 @@ describe('test/multiversion.test.js', () => { prefix: 'log/', status: 'Enabled', noncurrentVersionTransition: { - noncurrentDays: '10', + noncurrentDays: '20', storageClass: 'Archive' } }, @@ -194,7 +260,7 @@ describe('test/multiversion.test.js', () => { prefix: 'log/', status: 'Enabled', noncurrentVersionTransition: { - noncurrentDays: '10', + noncurrentDays: '30', storageClass: 'ColdArchive' } }, @@ -202,14 +268,19 @@ describe('test/multiversion.test.js', () => { prefix: 'log/', status: 'Enabled', noncurrentVersionTransition: { - noncurrentDays: '10', + noncurrentDays: '40', storageClass: 'DeepColdArchive' } } ], - { headers: { 'x-oss-allow-same-action-overlap': 'true' } } + { + headers: { + 'x-oss-allow-same-action-overlap': 'true' + } + } ); - assert.equal(putresult.res.status, 200); + + assert.strictEqual(res.res.status, 200); await utils.sleep(1000); const { rules } = await store.getBucketLifecycle(bucket); @@ -221,6 +292,116 @@ describe('test/multiversion.test.js', () => { assert(noncurrentDays === '10' && storageClass === 'IA' && rules.length === 4); }); + + it('should noncurrentVersionExpiration and noncurrentVersionTransition include noncurrentDays', async () => { + try { + await store.putBucketLifecycle(bucket, [ + { + prefix: '', + status: 'Enabled', + noncurrentVersionExpiration: {} + } + ]); + assert.fail('Expects to throw an error'); + } catch (e) { + assert.strictEqual(e.message, 'NoncurrentVersionExpiration must includes noncurrentDays'); + } + + try { + await store.putBucketLifecycle(bucket, [ + { + prefix: '', + status: 'Enabled', + noncurrentVersionTransition: { + noncurrentDays: null, + storageClass: 'Archive' + } + } + ]); + assert.fail('Expects to throw an error'); + } catch (e) { + assert.strictEqual(e.message, 'NoncurrentVersionTransition must includes noncurrentDays'); + } + }); + + it('should noncurrentDays be valid', async () => { + try { + await store.putBucketLifecycle(bucket, [ + { + prefix: '', + status: 'Enabled', + noncurrentVersionExpiration: { + noncurrentDays: '2.0' + } + } + ]); + assert.fail('Expects to throw an error'); + } catch (e) { + assert.strictEqual(e.message, 'noncurrentDays must be a positive integer'); + } + + try { + await store.putBucketLifecycle(bucket, [ + { + prefix: '', + status: 'Enabled', + noncurrentVersionExpiration: { + noncurrentDays: 'a' + } + } + ]); + assert.fail('Expects to throw an error'); + } catch (e) { + assert.strictEqual(e.message, 'noncurrentDays must be a positive integer'); + } + + try { + await store.putBucketLifecycle(bucket, [ + { + prefix: '', + status: 'Enabled', + noncurrentVersionExpiration: { + noncurrentDays: [1] + } + } + ]); + assert.fail('Expects to throw an error'); + } catch (e) { + assert.strictEqual(e.message, 'noncurrentDays must be a positive integer'); + } + + try { + await store.putBucketLifecycle(bucket, [ + { + prefix: '', + status: 'Enabled', + noncurrentVersionTransition: { + noncurrentDays: true, + storageClass: 'Archive' + } + } + ]); + assert.fail('Expects to throw an error'); + } catch (e) { + assert.strictEqual(e.message, 'noncurrentDays must be a positive integer'); + } + + try { + await store.putBucketLifecycle(bucket, [ + { + prefix: '', + status: 'Enabled', + noncurrentVersionTransition: { + noncurrentDays: -1, + storageClass: 'Archive' + } + } + ]); + assert.fail('Expects to throw an error'); + } catch (e) { + assert.strictEqual(e.message, 'noncurrentDays must be a positive integer'); + } + }); }); describe('copy()', () => { diff --git a/test/node/object.test.js b/test/node/object.test.js index 992b7bd0..c4fb99f1 100644 --- a/test/node/object.test.js +++ b/test/node/object.test.js @@ -170,6 +170,7 @@ describe('test/object.test.js', () => { readerStream.destroy(); }); await store.putStream(name, readerStream); + assert.fail('Expects to throw an error'); } catch (error) { assert.strictEqual(error.status, -1); } @@ -1080,11 +1081,10 @@ describe('test/object.test.js', () => { }); describe('signatureUrl(), asyncSignatureUrl() and signatureUrlV4()', () => { - let name; - let needEscapeName; + const name = `${prefix}ali-sdk/oss/signatureUrl.js`; + const needEscapeName = `${prefix}ali-sdk/oss/%3get+meta-signatureUrl.js`; const testSignatureObjectName = `?{测}\r\n[试];,/?:@&=+$<中>-_.!~*'(文)"¥#%!(字)^ \`符|\\${prefix}test.txt`; before(async () => { - name = `${prefix}ali-sdk/oss/signatureUrl.js`; let object = await store.put(name, __filename, { meta: { uid: 1, @@ -1094,7 +1094,6 @@ describe('test/object.test.js', () => { }); assert.equal(typeof object.res.headers['x-oss-request-id'], 'string'); - needEscapeName = `${prefix}ali-sdk/oss/%3get+meta-signatureUrl.js`; object = await store.put(needEscapeName, __filename, { meta: { uid: 1, @@ -1149,14 +1148,17 @@ describe('test/object.test.js', () => { ); }); - it('should signature url with response limitation', () => { + it('should signature url with response limitation', async () => { const response = { - 'content-type': 'xml', - 'content-language': 'zh-cn' + 'content-disposition': 'a.js', + 'cache-control': 'no-cache' }; const url = store.signatureUrl(name, { response }); - assert(url.indexOf('response-content-type=xml') !== -1); - assert(url.indexOf('response-content-language=zh-cn') !== -1); + const res = await axios.get(url); + + assert.strictEqual(res.status, 200); + assert.strictEqual(res.headers['cache-control'], 'no-cache'); + assert.strictEqual(res.headers['content-disposition'], 'a.js'); }); it('should signature url with options contains other parameters', async () => { diff --git a/test/node/rtmp.test.js b/test/node/rtmp.test.js index ae539ec2..57e6b480 100644 --- a/test/node/rtmp.test.js +++ b/test/node/rtmp.test.js @@ -21,8 +21,17 @@ describe('test/rtmp.test.js', () => { let store; let bucket; let bucketRegion; - let cid; - let conf; + const cid = 'channel-1'; + const conf = { + Description: 'this is channel 1', + Status: 'enabled', + Target: { + Type: 'HLS', + FragDuration: '10', + FragCount: '5', + PlaylistName: 'playlist.m3u8' + } + }; [ { authorizationV4: false @@ -38,20 +47,8 @@ describe('test/rtmp.test.js', () => { store.useBucket(bucket); const result = await store.putBucket(bucket, bucketRegion); - assert.equal(result.bucket, bucket); - assert.equal(result.res.status, 200); - - cid = 'channel-1'; - conf = { - Description: 'this is channel 1', - Status: 'enabled', - Target: { - Type: 'HLS', - FragDuration: '10', - FragCount: '5', - PlaylistName: 'playlist.m3u8' - } - }; + assert.strictEqual(result.bucket, bucket); + assert.strictEqual(result.res.status, 200); }); // github CI will remove buckets @@ -65,25 +62,25 @@ describe('test/rtmp.test.js', () => { const tempConf = conf; let result = await store.putChannel(tempCid, tempConf); - assert.equal(result.res.status, 200); + assert.strictEqual(result.res.status, 200); assert(is.array(result.publishUrls)); assert(result.publishUrls.length > 0); assert(is.array(result.playUrls)); assert(result.playUrls.length > 0); result = await store.getChannel(tempCid); - assert.equal(result.res.status, 200); - assert.deepEqual(result.data, conf); + assert.strictEqual(result.res.status, 200); + assert.deepStrictEqual(result.data, conf); result = await store.deleteChannel(tempCid); - assert.equal(result.res.status, 204); + assert.strictEqual(result.res.status, 204); await utils.throws( async () => { await store.getChannel(tempCid); }, err => { - assert.equal(err.status, 404); + assert.strictEqual(err.status, 404); } ); }); @@ -219,9 +216,13 @@ describe('test/rtmp.test.js', () => { endTime: Math.floor(now / 1000) }); - assert.equal(result.res.status, 200); + assert.strictEqual(result.res.status, 200); + // todo verify file } catch (err) { - console.error(err); + // todo remove catch error + assert.strictEqual(err.status, 400); + assert.strictEqual(err.code, 'InvalidArgument'); + assert.strictEqual(err.ecCode, '0044-00000308'); } }); }); @@ -233,7 +234,7 @@ describe('test/rtmp.test.js', () => { const getRtmpUrlConf = conf; getRtmpUrlConf.Description = 'this is live channel 5'; const result = await store.putChannel(getRtmpUrlCid, getRtmpUrlConf); - assert.equal(result.res.status, 200); + assert.strictEqual(result.res.status, 200); }); after(async () => { @@ -248,8 +249,8 @@ describe('test/rtmp.test.js', () => { }, expires: 3600 }); - console.log(url); - // verify the url is ok used by OBS or ffmpeg + assert(url.includes(getRtmpUrlCid) && url.includes(name)); + // todo verify the url is ok used by OBS or ffmpeg }); }); });