@@ -837,7 +837,7 @@ def test_list_objects_next_marker(self, s3_bucket, snapshot, aws_client):
837
837
snapshot .match ("list-objects-marker-empty" , resp )
838
838
839
839
@markers .aws .validated
840
- @pytest .mark .xfail (condition = is_v2_provider , reason = "not implemented in moto" )
840
+ @pytest .mark .xfail (condition = is_v2_provider () , reason = "not implemented in moto" )
841
841
def test_list_multiparts_next_marker (self , s3_bucket , snapshot , aws_client ):
842
842
snapshot .add_transformer (snapshot .transform .s3_api ())
843
843
snapshot .add_transformers_list (
@@ -943,7 +943,7 @@ def test_list_multiparts_next_marker(self, s3_bucket, snapshot, aws_client):
943
943
snapshot .match ("list-multiparts-next-key-empty" , response )
944
944
945
945
@markers .aws .validated
946
- @pytest .mark .xfail (condition = is_v2_provider , reason = "not implemented in moto" )
946
+ @pytest .mark .xfail (condition = is_v2_provider () , reason = "not implemented in moto" )
947
947
def test_list_multiparts_with_prefix_and_delimiter (
948
948
self , s3_bucket , snapshot , aws_client , aws_http_client_factory
949
949
):
@@ -989,7 +989,7 @@ def test_list_multiparts_with_prefix_and_delimiter(
989
989
resp_dict ["ListMultipartUploadsResult" ].pop ("@xmlns" , None )
990
990
snapshot .match ("list-multiparts-no-encoding" , resp_dict )
991
991
992
- @pytest .mark .xfail (condition = is_v2_provider , reason = "not implemented in moto" )
992
+ @pytest .mark .xfail (condition = is_v2_provider () , reason = "not implemented in moto" )
993
993
@markers .aws .validated
994
994
def test_list_parts_pagination (self , s3_bucket , snapshot , aws_client ):
995
995
snapshot .add_transformer (
@@ -1045,6 +1045,44 @@ def test_list_parts_pagination(self, s3_bucket, snapshot, aws_client):
1045
1045
)
1046
1046
snapshot .match ("list-parts-wrong-part" , response )
1047
1047
1048
+ @pytest .mark .xfail (
1049
+ condition = is_v2_provider (), reason = "moto does not handle empty query string parameters"
1050
+ )
1051
+ @markers .aws .validated
1052
+ def test_list_parts_empty_part_number_marker (self , s3_bucket , snapshot , aws_client_factory ):
1053
+ # we need to disable validation for this test
1054
+ s3_client = aws_client_factory (config = Config (parameter_validation = False )).s3
1055
+ snapshot .add_transformer (
1056
+ [
1057
+ snapshot .transform .key_value ("Bucket" , reference_replacement = False ),
1058
+ snapshot .transform .key_value ("Location" ),
1059
+ snapshot .transform .key_value ("UploadId" ),
1060
+ snapshot .transform .key_value ("DisplayName" , reference_replacement = False ),
1061
+ snapshot .transform .key_value ("ID" , reference_replacement = False ),
1062
+ ]
1063
+ )
1064
+ object_key = "test-list-part-empty-marker"
1065
+ response = s3_client .create_multipart_upload (Bucket = s3_bucket , Key = object_key )
1066
+ upload_id = response ["UploadId" ]
1067
+
1068
+ s3_client .upload_part (
1069
+ Bucket = s3_bucket ,
1070
+ Key = object_key ,
1071
+ Body = BytesIO (b"data" ),
1072
+ PartNumber = 1 ,
1073
+ UploadId = upload_id ,
1074
+ )
1075
+ # it seems S3 does not care about empty string for integer query string parameters
1076
+ response = s3_client .list_parts (
1077
+ Bucket = s3_bucket , UploadId = upload_id , Key = object_key , PartNumberMarker = ""
1078
+ )
1079
+ snapshot .match ("list-parts-empty-marker" , response )
1080
+
1081
+ response = s3_client .list_parts (
1082
+ Bucket = s3_bucket , UploadId = upload_id , Key = object_key , MaxParts = ""
1083
+ )
1084
+ snapshot .match ("list-parts-empty-max-parts" , response )
1085
+
1048
1086
@markers .aws .validated
1049
1087
def test_get_object_no_such_bucket (self , snapshot , aws_client ):
1050
1088
snapshot .add_transformer (snapshot .transform .key_value ("BucketName" ))
0 commit comments