Compare commits
5 Commits
developmen
...
temp/test-
Author | SHA1 | Date |
---|---|---|
williamlardier | a8da1a9290 | |
williamlardier | 77eb661b7d | |
williamlardier | ad3b41f726 | |
williamlardier | 6187054d07 | |
williamlardier | 1c2709f589 |
|
@ -37,6 +37,7 @@ const awsSubresources = [
|
||||||
'replication',
|
'replication',
|
||||||
'versions',
|
'versions',
|
||||||
'website',
|
'website',
|
||||||
|
'restore',
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function getCanonicalizedResource(request: any, clientType: string) {
|
export default function getCanonicalizedResource(request: any, clientType: string) {
|
||||||
|
|
|
@ -4,6 +4,8 @@ const constants = require('../constants');
|
||||||
const VersionIDUtils = require('../versioning/VersionID');
|
const VersionIDUtils = require('../versioning/VersionID');
|
||||||
|
|
||||||
const ObjectMDLocation = require('./ObjectMDLocation');
|
const ObjectMDLocation = require('./ObjectMDLocation');
|
||||||
|
const ObjectMDAmzRestore = require('./ObjectMDAmzRestore');
|
||||||
|
const ObjectMDArchive = require('./ObjectMDArchive');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to manage metadata object for regular s3 objects (instead of
|
* Class to manage metadata object for regular s3 objects (instead of
|
||||||
|
@ -101,6 +103,12 @@ class ObjectMD {
|
||||||
// similar to normalizing request but after checkAuth so
|
// similar to normalizing request but after checkAuth so
|
||||||
// string to sign is not impacted. This is GH Issue#89.
|
// string to sign is not impacted. This is GH Issue#89.
|
||||||
'x-amz-storage-class': 'STANDARD',
|
'x-amz-storage-class': 'STANDARD',
|
||||||
|
'x-amz-restore': {
|
||||||
|
'ongoing-request': false,
|
||||||
|
},
|
||||||
|
'archive': {
|
||||||
|
archiveInfo: {},
|
||||||
|
},
|
||||||
'x-amz-server-side-encryption': '',
|
'x-amz-server-side-encryption': '',
|
||||||
'x-amz-server-side-encryption-aws-kms-key-id': '',
|
'x-amz-server-side-encryption-aws-kms-key-id': '',
|
||||||
'x-amz-server-side-encryption-customer-algorithm': '',
|
'x-amz-server-side-encryption-customer-algorithm': '',
|
||||||
|
@ -1194,6 +1202,56 @@ class ObjectMD {
|
||||||
getValue() {
|
getValue() {
|
||||||
return this._data;
|
return this._data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get x-amz-restore
|
||||||
|
*
|
||||||
|
* @returns {ObjectMDAmzRestore} x-amz-restore
|
||||||
|
*/
|
||||||
|
getAmzRestore() {
|
||||||
|
return this._data['x-amz-restore'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set x-amz-restore
|
||||||
|
*
|
||||||
|
* @param {ObjectMDAmzRestore} value x-amz-restore object
|
||||||
|
* @returns {ObjectMD} itself
|
||||||
|
* @throws {Error} case of invalid parameter
|
||||||
|
*/
|
||||||
|
setAmzRestore(value) {
|
||||||
|
// Accept object instance of ObjectMDAmzRestore and Object
|
||||||
|
if (!(value instanceof ObjectMDAmzRestore) && !ObjectMDAmzRestore.isValid(value)) {
|
||||||
|
throw new Error('x-amz-restore is must be type of ObjectMDAmzRestore.');
|
||||||
|
}
|
||||||
|
this._data['x-amz-restore'] = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get archive
|
||||||
|
*
|
||||||
|
* @returns {ObjectMDArchive} archive
|
||||||
|
*/
|
||||||
|
getArchive() {
|
||||||
|
return this._data.archive;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set archive
|
||||||
|
*
|
||||||
|
* @param {ObjectMDArchive} value archive object
|
||||||
|
* @returns {ObjectMD} itself
|
||||||
|
* @throws {Error} case of invalid parameter
|
||||||
|
*/
|
||||||
|
setArchive(value) {
|
||||||
|
// Accept object instance of ObjectMDArchive and Object
|
||||||
|
if (!(value instanceof ObjectMDArchive) && !ObjectMDArchive.isValid(value)) {
|
||||||
|
throw new Error('archive is must be type of ObjectMDArchive.');
|
||||||
|
}
|
||||||
|
this._data.archive = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = ObjectMD;
|
module.exports = ObjectMD;
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
// (c) Fujifilm & Scality (TODO)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* class representing the x-amz-restore of object metadata.
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
class ObjectMDAmzRestore {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
* @param {boolean} ongoingRequest ongoing-request
|
||||||
|
* @param {Date} [expiryDate] expiry-date
|
||||||
|
* @throws {Error} case of invalid parameter
|
||||||
|
*/
|
||||||
|
constructor(ongoingRequest, expiryDate = undefined) {
|
||||||
|
this.setOngoingRequest(ongoingRequest);
|
||||||
|
this.setExpiryDate(expiryDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Object} data archiveInfo
|
||||||
|
* @returns {boolean} true if the provided object is valid
|
||||||
|
*/
|
||||||
|
static isValid(data) {
|
||||||
|
try {
|
||||||
|
const restoreMD = new ObjectMDAmzRestore(false);
|
||||||
|
restoreMD.setOngoingRequest(data['ongoing-request']);
|
||||||
|
restoreMD.setExpiryDate(data['expiry-date']);
|
||||||
|
return true;
|
||||||
|
} catch (err) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns {boolean} ongoing-request
|
||||||
|
*/
|
||||||
|
getOngoingRequest() {
|
||||||
|
return this['ongoing-request'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {boolean} value ongoing-request
|
||||||
|
* @returns {void}
|
||||||
|
* @throws {Error} case of invalid parameter
|
||||||
|
*/
|
||||||
|
setOngoingRequest(value) {
|
||||||
|
if (value === undefined) {
|
||||||
|
throw new Error('ongoing-request is required.');
|
||||||
|
} else if (typeof value !== 'boolean') {
|
||||||
|
throw new Error('ongoing-request must be type of boolean.');
|
||||||
|
}
|
||||||
|
this['ongoing-request'] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns {Date} expiry-date
|
||||||
|
*/
|
||||||
|
getExpiryDate() {
|
||||||
|
return this['expiry-date'] || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Date} value expiry-date
|
||||||
|
* @returns {void}
|
||||||
|
* @throws {Error} case of invalid parameter
|
||||||
|
*/
|
||||||
|
setExpiryDate(value) {
|
||||||
|
if (value) {
|
||||||
|
if (!(value instanceof Date)) {
|
||||||
|
throw new Error('expiry-date is must be type of Date.');
|
||||||
|
}
|
||||||
|
this['expiry-date'] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns {ObjectMDAmzRestore} itself
|
||||||
|
*/
|
||||||
|
getValue() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = ObjectMDAmzRestore;
|
|
@ -0,0 +1,169 @@
|
||||||
|
/**
|
||||||
|
* class representing the archive of object metadata.
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
*/
|
||||||
|
class ObjectMDArchive {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
* @param {Object} archiveInfo contains the archive info set by the TLP and returned by the TLP jobs
|
||||||
|
* @param {Date} [restoreRequestedAt] set at the time restore request is made by the client
|
||||||
|
* @param {Number} [restoreRequestedDays] set at the time restore request is made by the client
|
||||||
|
* @param {Date} [restoreCompletedAt] set at the time of successful restore
|
||||||
|
* @param {Date} [restoreWillExpireAt] computed and stored at the time of restore
|
||||||
|
* @throws {Error} case of invalid parameter
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
archiveInfo,
|
||||||
|
restoreRequestedAt = undefined,
|
||||||
|
restoreRequestedDays = undefined,
|
||||||
|
restoreCompletedAt = undefined,
|
||||||
|
restoreWillExpireAt = undefined) {
|
||||||
|
this.setArchiveInfo(archiveInfo);
|
||||||
|
this.setRestoreRequestedAt(restoreRequestedAt);
|
||||||
|
this.setRestoreRequestedDays(restoreRequestedDays);
|
||||||
|
this.setRestoreCompletedAt(restoreCompletedAt);
|
||||||
|
this.setRestoreWillExpireAt(restoreWillExpireAt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Object} data archiveInfo
|
||||||
|
* @returns {boolean} true if the provided object is valid
|
||||||
|
*/
|
||||||
|
static isValid(data) {
|
||||||
|
try {
|
||||||
|
const archiveMD = new ObjectMDArchive({});
|
||||||
|
archiveMD.setArchiveInfo(data.archiveInfo);
|
||||||
|
archiveMD.setRestoreRequestedAt(data.restoreRequestedAt);
|
||||||
|
archiveMD.setRestoreRequestedDays(data.restoreRequestedDays);
|
||||||
|
archiveMD.setRestoreCompletedAt(data.restoreCompletedAt);
|
||||||
|
archiveMD.setRestoreWillExpireAt(data.restoreWillExpireAt);
|
||||||
|
return true;
|
||||||
|
} catch (err) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns {Object} archiveInfo
|
||||||
|
*/
|
||||||
|
getArchiveInfo() {
|
||||||
|
return this.archiveInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Object} value archiveInfo
|
||||||
|
* @returns {void}
|
||||||
|
* @throws {Error} case of invalid parameter
|
||||||
|
*/
|
||||||
|
setArchiveInfo(value) {
|
||||||
|
if (!value) {
|
||||||
|
throw new Error('archiveInfo is required.');
|
||||||
|
} else if (typeof value !== 'object') {
|
||||||
|
throw new Error('archiveInfo must be type of object.');
|
||||||
|
}
|
||||||
|
this.archiveInfo = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns {Date} restoreRequestedAt
|
||||||
|
*/
|
||||||
|
getRestoreRequestedAt() {
|
||||||
|
return this.restoreRequestedAt;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {Object} value restoreRequestedAt
|
||||||
|
* @returns {void}
|
||||||
|
* @throws {Error} case of invalid parameter
|
||||||
|
*/
|
||||||
|
setRestoreRequestedAt(value) {
|
||||||
|
if (value) {
|
||||||
|
if (!(value instanceof Date)) {
|
||||||
|
throw new Error('restoreRequestedAt must be type of Date.');
|
||||||
|
}
|
||||||
|
this.restoreRequestedAt = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns {Number} restoreRequestedDays
|
||||||
|
*/
|
||||||
|
getRestoreRequestedDays() {
|
||||||
|
return this.restoreRequestedDays;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {Number} value restoreRequestedDays
|
||||||
|
* @returns {void}
|
||||||
|
* @throws {Error} case of invalid parameter
|
||||||
|
*/
|
||||||
|
setRestoreRequestedDays(value) {
|
||||||
|
if (value) {
|
||||||
|
if (isNaN(value)) {
|
||||||
|
throw new Error('restoreRequestedDays must be type of Number.');
|
||||||
|
}
|
||||||
|
this.restoreRequestedDays = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns {Date} restoreCompletedAt
|
||||||
|
*/
|
||||||
|
getRestoreCompletedAt() {
|
||||||
|
return this.restoreCompletedAt;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {Date} value restoreCompletedAt
|
||||||
|
* @returns {void}
|
||||||
|
* @throws {Error} case of invalid parameter
|
||||||
|
*/
|
||||||
|
setRestoreCompletedAt(value) {
|
||||||
|
if (value) {
|
||||||
|
if (!this.restoreRequestedAt || !this.restoreRequestedDays) {
|
||||||
|
throw new Error('restoreCompletedAt must be set after restoreRequestedAt and restoreRequestedDays.');
|
||||||
|
}
|
||||||
|
if (!(value instanceof Date)) {
|
||||||
|
throw new Error('restoreCompletedAt must be type of Date.');
|
||||||
|
}
|
||||||
|
this.restoreCompletedAt = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns {Date} restoreWillExpireAt
|
||||||
|
*/
|
||||||
|
getRestoreWillExpireAt() {
|
||||||
|
return this.restoreWillExpireAt;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {Date} value restoreWillExpireAt
|
||||||
|
* @returns {void}
|
||||||
|
* @throws {Error} case of invalid parameter
|
||||||
|
*/
|
||||||
|
setRestoreWillExpireAt(value) {
|
||||||
|
if (value) {
|
||||||
|
if (!this.restoreRequestedAt || !this.restoreRequestedDays) {
|
||||||
|
throw new Error('restoreWillExpireAt must be set after restoreRequestedAt and restoreRequestedDays.');
|
||||||
|
}
|
||||||
|
if (!(value instanceof Date)) {
|
||||||
|
throw new Error('restoreWillExpireAt must be type of Date.');
|
||||||
|
}
|
||||||
|
this.restoreWillExpireAt = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @returns {ObjectMDArchive} itself
|
||||||
|
*/
|
||||||
|
getValue() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = ObjectMDArchive;
|
|
@ -47,6 +47,7 @@ const sharedActionMap = {
|
||||||
objectPutLegalHold: 's3:PutObjectLegalHold',
|
objectPutLegalHold: 's3:PutObjectLegalHold',
|
||||||
objectPutRetention: 's3:PutObjectRetention',
|
objectPutRetention: 's3:PutObjectRetention',
|
||||||
objectPutTagging: 's3:PutObjectTagging',
|
objectPutTagging: 's3:PutObjectTagging',
|
||||||
|
objectRestore: 's3:RestoreObject',
|
||||||
};
|
};
|
||||||
|
|
||||||
// action map used for request context
|
// action map used for request context
|
||||||
|
|
|
@ -47,6 +47,14 @@ function routePOST(request, response, api, log) {
|
||||||
corsHeaders));
|
corsHeaders));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// POST Object restore
|
||||||
|
if (request.query.restore !== undefined) {
|
||||||
|
return api.callApiMethod('objectRestore', request, response,
|
||||||
|
log, (err, statusCode, resHeaders) =>
|
||||||
|
routesUtils.responseNoBody(err, resHeaders, response,
|
||||||
|
statusCode, log));
|
||||||
|
}
|
||||||
|
|
||||||
return routesUtils.responseNoBody(errors.NotImplemented, null, response,
|
return routesUtils.responseNoBody(errors.NotImplemented, null, response,
|
||||||
200, log);
|
200, log);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,18 @@ describe('ObjectMD class setters/getters', () => {
|
||||||
['AmzServerVersionId', 'server-version-id'],
|
['AmzServerVersionId', 'server-version-id'],
|
||||||
['AmzStorageClass', null, 'STANDARD'],
|
['AmzStorageClass', null, 'STANDARD'],
|
||||||
['AmzStorageClass', 'storage-class'],
|
['AmzStorageClass', 'storage-class'],
|
||||||
|
['AmzRestore', null, {
|
||||||
|
'ongoing-request': false,
|
||||||
|
}],
|
||||||
|
['AmzRestore', {
|
||||||
|
'ongoing-request': false,
|
||||||
|
}],
|
||||||
|
['Archive', null, {
|
||||||
|
archiveInfo: {},
|
||||||
|
}],
|
||||||
|
['Archive', {
|
||||||
|
archiveInfo: {},
|
||||||
|
}],
|
||||||
['AmzServerSideEncryption', null, ''],
|
['AmzServerSideEncryption', null, ''],
|
||||||
['AmzServerSideEncryption', 'server-side-encryption'],
|
['AmzServerSideEncryption', 'server-side-encryption'],
|
||||||
['AmzEncryptionKeyId', null, ''],
|
['AmzEncryptionKeyId', null, ''],
|
||||||
|
@ -417,6 +429,8 @@ describe('getAttributes static method', () => {
|
||||||
'x-amz-server-side-encryption-aws-kms-key-id': true,
|
'x-amz-server-side-encryption-aws-kms-key-id': true,
|
||||||
'x-amz-server-side-encryption-customer-algorithm': true,
|
'x-amz-server-side-encryption-customer-algorithm': true,
|
||||||
'x-amz-website-redirect-location': true,
|
'x-amz-website-redirect-location': true,
|
||||||
|
'x-amz-restore': true,
|
||||||
|
'archive': true,
|
||||||
'acl': true,
|
'acl': true,
|
||||||
'key': true,
|
'key': true,
|
||||||
'location': true,
|
'location': true,
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
const assert = require('assert');
|
||||||
|
const ObjectMDAmzRestore = require('../../../lib/models/ObjectMDAmzRestore');
|
||||||
|
|
||||||
|
const amzRestore = new ObjectMDAmzRestore(false, new Date());
|
||||||
|
|
||||||
|
describe('ObjectMDAmzRestore value', () => {
|
||||||
|
it('should return the correct value', () => {
|
||||||
|
const amzRestoreObj = amzRestore.getValue();
|
||||||
|
assert.deepStrictEqual(amzRestoreObj, amzRestore);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('ObjectMDAmzRestore setters/getters', () => {
|
||||||
|
it('should control the ongoing-request attribute', () => {
|
||||||
|
const ongoing = true;
|
||||||
|
amzRestore.setOngoingRequest(ongoing);
|
||||||
|
assert.deepStrictEqual(amzRestore.getOngoingRequest(),
|
||||||
|
ongoing);
|
||||||
|
});
|
||||||
|
it('should control the expiry-date attribute', () => {
|
||||||
|
const expiry = new Date(100);
|
||||||
|
amzRestore.setExpiryDate(expiry);
|
||||||
|
assert.deepStrictEqual(amzRestore.getExpiryDate(),
|
||||||
|
expiry);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,84 @@
|
||||||
|
const assert = require('assert');
|
||||||
|
const ObjectMDArchive = require('../../../lib/models/ObjectMDArchive');
|
||||||
|
|
||||||
|
const testArchive = {
|
||||||
|
archiveInfo: {
|
||||||
|
any: 'value',
|
||||||
|
},
|
||||||
|
restoreRequestedAt: new Date(0),
|
||||||
|
restoreRequestedDays: 5,
|
||||||
|
restoreCompletedAt: new Date(1000),
|
||||||
|
restoreWillExpireAt: new Date(10000),
|
||||||
|
};
|
||||||
|
|
||||||
|
const archive = new ObjectMDArchive(
|
||||||
|
testArchive.archiveInfo,
|
||||||
|
testArchive.restoreRequestedAt,
|
||||||
|
testArchive.restoreRequestedDays,
|
||||||
|
testArchive.restoreCompletedAt,
|
||||||
|
testArchive.restoreWillExpireAt,
|
||||||
|
);
|
||||||
|
|
||||||
|
describe('ObjectMDArchive value', () => {
|
||||||
|
it('should return the correct value', () => {
|
||||||
|
const amzRestoreObj = archive.getValue();
|
||||||
|
assert.deepStrictEqual(amzRestoreObj, archive);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('ObjectMDArchive setters/getters', () => {
|
||||||
|
let archived = null;
|
||||||
|
beforeEach(() => {
|
||||||
|
archived = new ObjectMDArchive(
|
||||||
|
testArchive.archiveInfo,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('should control the archiveInfo attribute', () => {
|
||||||
|
const info = {
|
||||||
|
test: 'data',
|
||||||
|
};
|
||||||
|
archive.setArchiveInfo(info);
|
||||||
|
assert.deepStrictEqual(archive.getArchiveInfo(),
|
||||||
|
info);
|
||||||
|
});
|
||||||
|
it('should control the restoreRequestedAt attribute', () => {
|
||||||
|
const requestedAt = new Date(123456);
|
||||||
|
assert.doesNotThrow(() => {
|
||||||
|
archived.setRestoreRequestedAt(requestedAt);
|
||||||
|
});
|
||||||
|
archive.setRestoreRequestedAt(requestedAt);
|
||||||
|
assert.deepStrictEqual(archive.getRestoreRequestedAt(),
|
||||||
|
requestedAt);
|
||||||
|
});
|
||||||
|
it('should control the restoreRequestedDays attribute', () => {
|
||||||
|
const requestedDays = 8;
|
||||||
|
assert.doesNotThrow(() => {
|
||||||
|
archived.setRestoreRequestedDays(requestedDays);
|
||||||
|
});
|
||||||
|
archive.setRestoreRequestedDays(requestedDays);
|
||||||
|
assert.deepStrictEqual(archive.getRestoreRequestedDays(),
|
||||||
|
requestedDays);
|
||||||
|
});
|
||||||
|
it('should control the restoreCompletedAt attribute', () => {
|
||||||
|
const completedAt = new Date(123456);
|
||||||
|
assert.throws(() => {
|
||||||
|
archived.setRestoreCompletedAt(completedAt);
|
||||||
|
});
|
||||||
|
archive.setRestoreCompletedAt(completedAt);
|
||||||
|
assert.deepStrictEqual(archive.getRestoreCompletedAt(),
|
||||||
|
completedAt);
|
||||||
|
});
|
||||||
|
it('should control the restoreWillExpireAt attribute', () => {
|
||||||
|
const willExpireAt = new Date(123456);
|
||||||
|
assert.throws(() => {
|
||||||
|
archived.setRestoreWillExpireAt(willExpireAt);
|
||||||
|
});
|
||||||
|
archive.setRestoreWillExpireAt(willExpireAt);
|
||||||
|
assert.deepStrictEqual(archive.getRestoreWillExpireAt(),
|
||||||
|
willExpireAt);
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue