Skip to content

Commit 9dd78df

Browse files
authored
fix: raise a ValueError in BucketNotification.create() if a topic name is not set (#617)
* fix: topic name is required to create a notification. add check and tests * revise conf tests * fix topic formatting and remove extra validation * blacken lint * update docstrings
1 parent 72379e8 commit 9dd78df

File tree

4 files changed

+72
-3
lines changed

4 files changed

+72
-3
lines changed

google/cloud/storage/notification.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,8 @@ def create(self, client=None, timeout=_DEFAULT_TIMEOUT, retry=None):
253253
:type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
254254
:param retry:
255255
(Optional) How to retry the RPC. See: :ref:`configuring_retries`
256+
257+
:raises ValueError: if the notification already exists.
256258
"""
257259
if self.notification_id is not None:
258260
raise ValueError(
@@ -267,7 +269,14 @@ def create(self, client=None, timeout=_DEFAULT_TIMEOUT, retry=None):
267269

268270
path = "/b/{}/notificationConfigs".format(self.bucket.name)
269271
properties = self._properties.copy()
270-
properties["topic"] = _TOPIC_REF_FMT.format(self.topic_project, self.topic_name)
272+
273+
if self.topic_name is None:
274+
properties["topic"] = _TOPIC_REF_FMT.format(self.topic_project, "")
275+
else:
276+
properties["topic"] = _TOPIC_REF_FMT.format(
277+
self.topic_project, self.topic_name
278+
)
279+
271280
self._properties = client._post_resource(
272281
path, properties, query_params=query_params, timeout=timeout, retry=retry,
273282
)

tests/conformance/test_conformance.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
_CONF_TEST_SERVICE_ACCOUNT_EMAIL = (
5353
5454
)
55+
_CONF_TEST_PUBSUB_TOPIC_NAME = "my-topic-name"
5556

5657
_STRING_CONTENT = "hello world"
5758
_BYTE_CONTENT = b"12345678"
@@ -190,7 +191,7 @@ def client_get_service_account_email(client, _preconditions, **_):
190191

191192
def notification_create(client, _preconditions, **resources):
192193
bucket = client.bucket(resources.get("bucket").name)
193-
notification = bucket.notification()
194+
notification = bucket.notification(topic_name=_CONF_TEST_PUBSUB_TOPIC_NAME)
194195
notification.create()
195196

196197

@@ -761,7 +762,9 @@ def object(client, bucket):
761762

762763
@pytest.fixture
763764
def notification(client, bucket):
764-
notification = client.bucket(bucket.name).notification()
765+
notification = client.bucket(bucket.name).notification(
766+
topic_name=_CONF_TEST_PUBSUB_TOPIC_NAME
767+
)
765768
notification.create()
766769
notification.reload()
767770
yield notification

tests/system/test_notification.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,34 @@ def test_notification_create_w_user_project(
149149
notification.delete()
150150

151151

152+
def test_notification_create_wo_topic_name(
153+
storage_client,
154+
buckets_to_delete,
155+
topic_name,
156+
notification_topic,
157+
event_types,
158+
payload_format,
159+
):
160+
from google.cloud.exceptions import BadRequest
161+
162+
bucket_name = _helpers.unique_name("notification-wo-name")
163+
bucket = _helpers.retry_429_503(storage_client.create_bucket)(bucket_name)
164+
buckets_to_delete.append(bucket)
165+
166+
assert list(bucket.list_notifications()) == []
167+
168+
notification = bucket.notification(
169+
topic_name=None,
170+
custom_attributes=custom_attributes,
171+
event_types=event_types,
172+
blob_name_prefix=blob_name_prefix,
173+
payload_format=payload_format,
174+
)
175+
176+
with pytest.raises(BadRequest):
177+
notification.create()
178+
179+
152180
def test_bucket_get_notification(
153181
storage_client,
154182
buckets_to_delete,

tests/unit/test_notification.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,35 @@ def test_create_w_existing_notification_id(self):
242242

243243
client._post_resource.assert_not_called()
244244

245+
def test_create_wo_topic_name(self):
246+
from google.cloud.exceptions import BadRequest
247+
from google.cloud.storage.notification import NONE_PAYLOAD_FORMAT
248+
249+
client = mock.Mock(spec=["_post_resource", "project"])
250+
client.project = self.BUCKET_PROJECT
251+
client._post_resource.side_effect = BadRequest(
252+
"Invalid Google Cloud Pub/Sub topic."
253+
)
254+
bucket = self._make_bucket(client)
255+
notification = self._make_one(bucket, None)
256+
257+
with self.assertRaises(BadRequest):
258+
notification.create()
259+
260+
expected_topic = self.TOPIC_REF_FMT.format(self.BUCKET_PROJECT, "")
261+
expected_data = {
262+
"topic": expected_topic,
263+
"payload_format": NONE_PAYLOAD_FORMAT,
264+
}
265+
expected_query_params = {}
266+
client._post_resource.assert_called_once_with(
267+
self.CREATE_PATH,
268+
expected_data,
269+
query_params=expected_query_params,
270+
timeout=self._get_default_timeout(),
271+
retry=None,
272+
)
273+
245274
def test_create_w_defaults(self):
246275
from google.cloud.storage.notification import NONE_PAYLOAD_FORMAT
247276

0 commit comments

Comments
 (0)