diff --git a/testbench/proto2rest.py b/testbench/proto2rest.py index f346db44..b1065ca4 100644 --- a/testbench/proto2rest.py +++ b/testbench/proto2rest.py @@ -178,3 +178,8 @@ def __postprocess_bucket_rest(data): def bucket_as_rest(bucket: storage_pb2.Bucket): metadata = json_format.MessageToDict(bucket) return __postprocess_bucket_rest(metadata) + + +def bucket_access_control_as_rest(bucket_id: str, acl: storage_pb2.BucketAccessControl): + rest = json_format.MessageToDict(acl) + return __postprocess_rest_bucket_acl(bucket_id, rest) diff --git a/testbench/rest_server.py b/testbench/rest_server.py index 4d41931d..ab514706 100644 --- a/testbench/rest_server.py +++ b/testbench/rest_server.py @@ -273,11 +273,13 @@ def bucket_delete(bucket_name): @retry_test(method="storage.bucket_acl.list") def bucket_acl_list(bucket_name): bucket = db.get_bucket(bucket_name, None) - response = {"kind": "storage#bucketAccessControls", "items": []} - for acl in bucket.metadata.acl: - acl_rest = json_format.MessageToDict(acl) - acl_rest["kind"] = "storage#bucketAccessControl" - response["items"].append(acl_rest) + response = { + "kind": "storage#bucketAccessControls", + "items": [ + testbench.proto2rest.bucket_access_control_as_rest(bucket_name, acl) + for acl in bucket.metadata.acl + ], + } fields = flask.request.args.get("fields", None) return testbench.common.filter_response_rest(response, None, fields) @@ -287,8 +289,7 @@ def bucket_acl_list(bucket_name): def bucket_acl_insert(bucket_name): bucket = db.get_bucket(bucket_name, None) acl = bucket.insert_acl(flask.request, None) - response = json_format.MessageToDict(acl) - response["kind"] = "storage#bucketAccessControl" + response = testbench.proto2rest.bucket_access_control_as_rest(bucket_name, acl) fields = flask.request.args.get("fields", None) return testbench.common.filter_response_rest(response, None, fields) @@ -298,8 +299,7 @@ def bucket_acl_insert(bucket_name): def bucket_acl_get(bucket_name, entity): bucket = db.get_bucket(bucket_name, None) acl = bucket.get_acl(entity, None) - response = json_format.MessageToDict(acl) - response["kind"] = "storage#bucketAccessControl" + response = testbench.proto2rest.bucket_access_control_as_rest(bucket_name, acl) fields = flask.request.args.get("fields", None) return testbench.common.filter_response_rest(response, None, fields) @@ -309,8 +309,7 @@ def bucket_acl_get(bucket_name, entity): def bucket_acl_update(bucket_name, entity): bucket = db.get_bucket(bucket_name, None) acl = bucket.update_acl(flask.request, entity, None) - response = json_format.MessageToDict(acl) - response["kind"] = "storage#bucketAccessControl" + response = testbench.proto2rest.bucket_access_control_as_rest(bucket_name, acl) fields = flask.request.args.get("fields", None) return testbench.common.filter_response_rest(response, None, fields) @@ -321,8 +320,7 @@ def bucket_acl_patch(bucket_name, entity): testbench.common.enforce_patch_override(flask.request) bucket = db.get_bucket(bucket_name, None) acl = bucket.patch_acl(flask.request, entity, None) - response = json_format.MessageToDict(acl) - response["kind"] = "storage#bucketAccessControl" + response = testbench.proto2rest.bucket_access_control_as_rest(bucket_name, acl) fields = flask.request.args.get("fields", None) return testbench.common.filter_response_rest(response, None, fields) @@ -332,7 +330,7 @@ def bucket_acl_patch(bucket_name, entity): def bucket_acl_delete(bucket_name, entity): bucket = db.get_bucket(bucket_name, None) bucket.delete_acl(entity, None) - return "" + return flask.make_response("") @gcs.route("/b//defaultObjectAcl") diff --git a/tests/test_proto2rest.py b/tests/test_proto2rest.py new file mode 100644 index 00000000..33f69648 --- /dev/null +++ b/tests/test_proto2rest.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 +# +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Unit test for proto2rest.""" + +import unittest + +from google.storage.v2 import storage_pb2 + +import testbench + + +class TestProto2Rest(unittest.TestCase): + def test_bucket_access_control_as_rest(self): + acl = storage_pb2.BucketAccessControl( + id="test-id", + entity="test-entity", + entity_id="test-entity-id", + role="test-role", + email="test-email", + domain="test-domain", + project_team=storage_pb2.ProjectTeam( + project_number="12345", team="test-team" + ), + ) + actual = testbench.proto2rest.bucket_access_control_as_rest( + "test-bucket-id", acl + ) + expected = { + "kind": "storage#bucketAccessControl", + "id": "test-id", + "bucket": "test-bucket-id", + "entity": "test-entity", + "role": "test-role", + "email": "test-email", + "domain": "test-domain", + "projectTeam": {"projectNumber": "12345", "team": "test-team"}, + } + self.assertEqual(actual, {**actual, **expected}) + self.assertIn("etag", actual) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_testbench_bucket.py b/tests/test_testbench_bucket.py index d072f809..cd6bc0f8 100644 --- a/tests/test_testbench_bucket.py +++ b/tests/test_testbench_bucket.py @@ -128,6 +128,9 @@ def test_bucket_acl_crud(self): ) insert_rest = json.loads(response.data) self.assertEqual(insert_rest, {**insert_rest, **insert_data}) + self.assertIn("etag", insert_rest) + self.assertIn("bucket", insert_rest) + self.assertIn("kind", insert_rest) response = self.client.get( "/storage/v1/b/bucket-name/acl/allAuthenticatedUsers" @@ -138,6 +141,9 @@ def test_bucket_acl_crud(self): ) get_rest = json.loads(response.data) self.assertEqual(get_rest, insert_rest) + self.assertIn("etag", get_rest) + self.assertIn("bucket", get_rest) + self.assertIn("kind", get_rest) response = self.client.patch( "/storage/v1/b/bucket-name/acl/allAuthenticatedUsers", @@ -149,6 +155,9 @@ def test_bucket_acl_crud(self): ) patch_rest = json.loads(response.data) self.assertEqual(patch_rest.get("role", None), "OWNER") + self.assertIn("etag", patch_rest) + self.assertIn("bucket", patch_rest) + self.assertIn("kind", patch_rest) update_data = patch_rest.copy() update_data["role"] = "READER" @@ -162,6 +171,9 @@ def test_bucket_acl_crud(self): ) update_rest = json.loads(response.data) self.assertEqual(update_rest.get("role", None), "READER") + self.assertIn("etag", update_rest) + self.assertIn("bucket", update_rest) + self.assertIn("kind", update_rest) response = self.client.get("/storage/v1/b/bucket-name/acl") self.assertEqual(response.status_code, 200) @@ -172,6 +184,11 @@ def test_bucket_acl_crud(self): self.assertIn( "allAuthenticatedUsers", [a.get("entity") for a in list_rest.get("items")] ) + self.assertNotEqual(len(list_rest.get("items")), 0) + front = list_rest.get("items")[0] + self.assertIn("etag", front) + self.assertIn("bucket", front) + self.assertIn("kind", front) response = self.client.delete( "/storage/v1/b/bucket-name/acl/allAuthenticatedUsers"