@@ -7,7 +7,7 @@ const services = require('../../../lib/services');
77const { bucketPut } = require ( '../../../lib/api/bucketPut' ) ;
88const bucketPutACL = require ( '../../../lib/api/bucketPutACL' ) ;
99const constants = require ( '../../../constants' ) ;
10- const { cleanup, DummyRequestLogger, makeAuthInfo } = require ( '../helpers' ) ;
10+ const { cleanup, DummyRequestLogger, makeAuthInfo, versioningTestUtils } = require ( '../helpers' ) ;
1111const objectPut = require ( '../../../lib/api/objectPut' ) ;
1212const { objectDelete, objectDeleteInternal } = require ( '../../../lib/api/objectDelete' ) ;
1313const objectGet = require ( '../../../lib/api/objectGet' ) ;
@@ -16,6 +16,7 @@ const mpuUtils = require('../utils/mpuUtils');
1616const metadataswitch = require ( '../metadataswitch' ) ;
1717const { fakeMetadataArchive } = require ( '../../functional/aws-node-sdk/test/utils/init' ) ;
1818const bucketPutNotification = require ( '../../../lib/api/bucketPutNotification' ) ;
19+ const bucketPutVersioning = require ( '../../../lib/api/bucketPutVersioning' ) ;
1920
2021const any = sinon . match . any ;
2122const originalDeleteObject = services . deleteObject ;
@@ -32,6 +33,8 @@ const lateDate = new Date();
3233earlyDate . setMinutes ( earlyDate . getMinutes ( ) - 30 ) ;
3334lateDate . setMinutes ( lateDate . getMinutes ( ) + 30 ) ;
3435
36+ const enableVersioningRequest = versioningTestUtils . createBucketPutVersioningReq ( bucketName , 'Enabled' ) ;
37+
3538function testAuth ( bucketOwner , authUser , bucketPutReq , objPutReq , objDelReq ,
3639 log , cb ) {
3740 bucketPut ( bucketOwner , bucketPutReq , log , ( ) => {
@@ -371,3 +374,65 @@ describe('objectDelete API', () => {
371374 } ) ;
372375 } ) ;
373376} ) ;
377+
378+ describe ( 'objectDelete API with versioning' , ( ) => {
379+ let testPutObjectRequest ;
380+
381+ beforeEach ( ( ) => {
382+ cleanup ( ) ;
383+ testPutObjectRequest = new DummyRequest ( {
384+ bucketName,
385+ namespace,
386+ objectKey,
387+ headers : { } ,
388+ url : `/${ bucketName } /${ objectKey } ` ,
389+ } , postBody ) ;
390+
391+ sinon . stub ( services , 'deleteObject' ) . callsFake ( originalDeleteObject ) ;
392+ sinon . spy ( metadataswitch , 'putObjectMD' ) ;
393+ sinon . spy ( metadataswitch , 'deleteObjectMD' ) ;
394+ } ) ;
395+
396+ afterEach ( ( ) => {
397+ sinon . restore ( ) ;
398+ } ) ;
399+
400+ const testBucketPutRequest = new DummyRequest ( {
401+ bucketName,
402+ namespace,
403+ headers : { } ,
404+ url : `/${ bucketName } ` ,
405+ } ) ;
406+ const testDeleteRequest = new DummyRequest ( {
407+ bucketName,
408+ namespace,
409+ objectKey,
410+ headers : { } ,
411+ url : `/${ bucketName } /${ objectKey } ` ,
412+ } ) ;
413+
414+ it ( 'should upgrade master-only document to a version document when storing a delete marker version' , done => {
415+ async . series ( [
416+ next => bucketPut ( authInfo , testBucketPutRequest , log , next ) ,
417+ next => objectPut ( authInfo , testPutObjectRequest , undefined , log , next ) ,
418+ next => bucketPutVersioning ( authInfo , enableVersioningRequest , log , next ) ,
419+ next => objectDelete ( authInfo , testDeleteRequest , log , next ) ,
420+ async ( ) => {
421+ const calls = metadataswitch . putObjectMD . getCalls ( ) ;
422+ sinon . assert . calledWith ( calls [ calls . length - 2 ] ,
423+ bucketName , objectKey , sinon . match ( {
424+ versionId : sinon . match . truthy ,
425+ isNull : true ,
426+ originOp : 's3:StoreNullVersion' ,
427+ } ) , any , any , any ) ;
428+ } ,
429+ async ( ) => {
430+ // New version document (delete marker) was created with the right originOp.
431+ sinon . assert . calledWith ( metadataswitch . putObjectMD . lastCall ,
432+ bucketName , objectKey , sinon . match ( {
433+ _data : { originOp : 's3:ObjectRemoved:DeleteMarkerCreated' } ,
434+ } ) , any , any , any ) ;
435+ } ,
436+ ] , done ) ;
437+ } ) ;
438+ } ) ;
0 commit comments