Skip to content

Commit 113b842

Browse files
committed
tests: add test coverage for type error path
1 parent fa0a959 commit 113b842

2 files changed

Lines changed: 171 additions & 1 deletion

File tree

tests/test_manifest.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,33 @@
1313
# limitations under the License.
1414
"""Manifest unit tests."""
1515

16+
from collections.abc import Mapping as _Mapping
17+
from zoneinfo import ZoneInfo
18+
19+
from pytest import raises
20+
1621
import firebase_functions.params as _params
1722
import firebase_functions.private.manifest as _manifest
1823

24+
25+
class _CustomMapping(_Mapping):
26+
def __init__(self, data):
27+
self._data = data
28+
29+
def __getitem__(self, key):
30+
return self._data[key]
31+
32+
def __iter__(self):
33+
return iter(self._data)
34+
35+
def __len__(self):
36+
return len(self._data)
37+
38+
39+
class _UnsupportedManifestValue:
40+
pass
41+
42+
1943
full_endpoint = _manifest.ManifestEndpoint(
2044
platform="gcfv2",
2145
region=["us-west1"],
@@ -160,3 +184,23 @@ def test_endpoint_nones(self):
160184
assert expressions_actual_dict == expressions_expected_dict, (
161185
"Generated endpoint spec dict does not match expected dict."
162186
)
187+
188+
def test_object_to_spec_converts_tuple_to_list(self):
189+
"""Check tuple values are converted to manifest lists."""
190+
actual = _manifest._object_to_spec(("hello", 1, True))
191+
assert actual == ["hello", 1, True]
192+
193+
def test_object_to_spec_converts_custom_mapping_to_dict(self):
194+
"""Check Mapping implementations are converted via dict serialization."""
195+
actual = _manifest._object_to_spec(_CustomMapping({"hello": "world"}))
196+
assert actual == {"hello": "world"}
197+
198+
def test_object_to_spec_converts_zoneinfo_to_key(self):
199+
"""Check ZoneInfo values serialize to their key."""
200+
actual = _manifest._object_to_spec(ZoneInfo("America/Los_Angeles"))
201+
assert actual == "America/Los_Angeles"
202+
203+
def test_object_to_spec_raises_for_unsupported_value(self):
204+
"""Check unsupported values fail fast."""
205+
with raises(TypeError, match="Unsupported manifest spec value"):
206+
_manifest._object_to_spec(_UnsupportedManifestValue())

tests/test_options.py

Lines changed: 127 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@
1515
Options unit tests.
1616
"""
1717

18-
from pytest import raises
18+
from pytest import mark, raises
1919

2020
from firebase_functions import alerts_fn, https_fn, options, params
21+
import firebase_functions.private.manifest as _manifest
2122
from firebase_functions.alerts import (
2223
app_distribution_fn,
2324
billing_fn,
@@ -31,6 +32,30 @@
3132
ALERT_SECRET = params.SecretParam("GITLAB_PERSONAL_ACCESS_TOKEN")
3233

3334

35+
class _UnsupportedManifestValue:
36+
pass
37+
38+
39+
class _FakePattern:
40+
def __init__(self, value, has_wildcards=False):
41+
self.value = value
42+
self.has_wildcards = has_wildcards
43+
44+
45+
def _assert_endpoint_manifest_type_error(endpoint):
46+
with raises(TypeError, match="Unsupported manifest spec value"):
47+
_manifest.manifest_to_spec_dict(_manifest.ManifestStack(endpoints={"test": endpoint}))
48+
49+
50+
def _assert_option_builder_type_error(builder):
51+
try:
52+
endpoint = builder()
53+
except TypeError as exc:
54+
assert "Unsupported manifest spec value" in str(exc)
55+
else:
56+
_assert_endpoint_manifest_type_error(endpoint)
57+
58+
3459
@https_fn.on_call()
3560
def asamplefunction(_):
3661
return "hello world"
@@ -305,3 +330,104 @@ def sample(_event):
305330
"crashlytics.newFatalIssue",
306331
expect_app_id="app-123",
307332
)
333+
334+
335+
@mark.parametrize(
336+
("builder"),
337+
[
338+
lambda: options.RuntimeOptions(region=_UnsupportedManifestValue())._endpoint(
339+
func_name="test"
340+
),
341+
lambda: options.EventHandlerOptions(retry=_UnsupportedManifestValue())._endpoint(
342+
func_name="test",
343+
event_filters={},
344+
event_type="google.cloud.pubsub.topic.v1.messagePublished",
345+
),
346+
lambda: options.TaskQueueOptions(
347+
retry_config=options.RetryConfig(max_attempts=_UnsupportedManifestValue())
348+
)._endpoint(func_name="test"),
349+
lambda: options.PubSubOptions(topic=_UnsupportedManifestValue())._endpoint(
350+
func_name="test"
351+
),
352+
lambda: options.FirebaseAlertOptions(alert_type=_UnsupportedManifestValue())._endpoint(
353+
func_name="test"
354+
),
355+
lambda: options.AppDistributionOptions(app_id=_UnsupportedManifestValue())._endpoint(
356+
func_name="test",
357+
alert_type=options.AlertType.APP_DISTRIBUTION_NEW_TESTER_IOS_DEVICE,
358+
),
359+
lambda: options.PerformanceOptions(app_id=_UnsupportedManifestValue())._endpoint(
360+
func_name="test",
361+
alert_type=options.AlertType.PERFORMANCE_THRESHOLD,
362+
),
363+
lambda: options.CrashlyticsOptions(app_id=_UnsupportedManifestValue())._endpoint(
364+
func_name="test",
365+
alert_type=options.AlertType.CRASHLYTICS_NEW_FATAL_ISSUE,
366+
),
367+
lambda: options.BillingOptions()._endpoint(
368+
func_name="test",
369+
alert_type=_UnsupportedManifestValue(),
370+
),
371+
lambda: options.EventarcTriggerOptions(
372+
event_type="firebase.extensions.storage-resize-images.v1.complete",
373+
filters={"subject": _UnsupportedManifestValue()},
374+
)._endpoint(func_name="test"),
375+
lambda: options.ScheduleOptions(schedule=_UnsupportedManifestValue())._endpoint(
376+
func_name="test"
377+
),
378+
lambda: options.StorageOptions(bucket=_UnsupportedManifestValue())._endpoint(
379+
func_name="test",
380+
event_type="google.cloud.storage.object.v1.finalized",
381+
),
382+
lambda: options.DatabaseOptions(reference="/foo/{bar}")._endpoint(
383+
func_name="test",
384+
event_type="google.firebase.database.ref.v1.written",
385+
instance_pattern=_FakePattern(_UnsupportedManifestValue()),
386+
),
387+
lambda: options.BlockingOptions(id_token=_UnsupportedManifestValue())._endpoint(
388+
func_name="test",
389+
event_type="providers/cloud.auth/eventTypes/user.beforeSignIn",
390+
),
391+
lambda: options.FirestoreOptions(document="foo/{bar}")._endpoint(
392+
func_name="test",
393+
event_type="google.cloud.firestore.document.v1.written",
394+
document_pattern=_FakePattern(_UnsupportedManifestValue(), has_wildcards=True),
395+
),
396+
lambda: options.HttpsOptions(invoker=[_UnsupportedManifestValue()])._endpoint(
397+
func_name="test"
398+
),
399+
lambda: options.HttpsOptions(labels={"broken": _UnsupportedManifestValue()})._endpoint(
400+
func_name="test",
401+
callable=True,
402+
),
403+
lambda: options.DataConnectOptions(service="service")._endpoint(
404+
func_name="test",
405+
event_type="google.firebase.dataconnect.connector.v1.mutationExecuted",
406+
service_pattern=_FakePattern(_UnsupportedManifestValue()),
407+
connector_pattern=_FakePattern("connector"),
408+
operation_pattern=_FakePattern("operation"),
409+
),
410+
],
411+
ids=[
412+
"runtime",
413+
"event_handler",
414+
"task_queue",
415+
"pubsub",
416+
"firebase_alert",
417+
"app_distribution",
418+
"performance",
419+
"crashlytics",
420+
"billing",
421+
"eventarc",
422+
"schedule",
423+
"storage",
424+
"database",
425+
"blocking",
426+
"firestore",
427+
"https",
428+
"callable_https",
429+
"dataconnect",
430+
],
431+
)
432+
def test_manifest_to_spec_rejects_unsupported_values_across_option_types(builder):
433+
_assert_option_builder_type_error(builder)

0 commit comments

Comments
 (0)