Notify IWA team of features in IWA category. (#3548)
* Notify IWA team of features in IWA category. * Fix mock import
This commit is contained in:
Родитель
6452815cc9
Коммит
94aa996208
|
@ -140,6 +140,10 @@ def convert_reasons_to_task(
|
|||
WEBVIEW_RULE_REASON = (
|
||||
'This feature has an android milestone, but not a webview milestone')
|
||||
WEBVIEW_RULE_ADDRS = ['webview-leads-external@google.com']
|
||||
IWA_RULE_REASON = (
|
||||
'You are subscribed to all IWA features')
|
||||
IWA_RULE_ADDRS = ['iwa-dev@chromium.org']
|
||||
|
||||
|
||||
|
||||
def apply_subscription_rules(
|
||||
|
@ -150,6 +154,10 @@ def apply_subscription_rules(
|
|||
changed_field_names = {c['prop_name'] for c in changes}
|
||||
results: dict[str, list[str]] = {}
|
||||
|
||||
# Rule 1: Check for IWA features
|
||||
if fe.category == core_enums.IWA:
|
||||
results[IWA_RULE_REASON] = IWA_RULE_ADDRS
|
||||
|
||||
# Find an existing shipping stage with milestone info.
|
||||
fe_stages = stage_helpers.get_feature_stages(fe.key.integer_id())
|
||||
stage_type = core_enums.STAGE_TYPES_SHIPPING[fe.feature_type] or 0
|
||||
|
@ -157,7 +165,7 @@ def apply_subscription_rules(
|
|||
ship_milestones: MilestoneSet | None = (
|
||||
ship_stages[0].milestones if len(ship_stages) > 0 else None)
|
||||
|
||||
# Check if feature has some other milestone set, but not webview.
|
||||
# Rule 2: Check if feature has some other milestone set, but not webview.
|
||||
if (ship_milestones is not None and
|
||||
ship_milestones.android_first and
|
||||
not ship_milestones.webview_first):
|
||||
|
|
|
@ -39,8 +39,9 @@ def _get_changes_as_amendments(
|
|||
old_value=str(old_val), new_value=str(new_val)))
|
||||
return amendments
|
||||
|
||||
def notify_feature_subscribers_of_changes(fe: 'FeatureEntry',
|
||||
amendments: list[Amendment]) -> None:
|
||||
def notify_feature_subscribers_of_changes(
|
||||
fe: 'FeatureEntry', amendments: list[Amendment],
|
||||
is_update: bool=True) -> None:
|
||||
"""Async notifies subscribers of new features and property changes to
|
||||
features by posting to a task queue.
|
||||
"""
|
||||
|
@ -54,16 +55,16 @@ def notify_feature_subscribers_of_changes(fe: 'FeatureEntry',
|
|||
|
||||
params = {
|
||||
'changes': changed_props,
|
||||
# Subscribers are only notified on feature update.
|
||||
'is_update': True,
|
||||
'is_update': is_update,
|
||||
'feature': converters.feature_entry_to_json_verbose(fe)
|
||||
}
|
||||
|
||||
# Create task to email subscribers.
|
||||
cloud_tasks_helpers.enqueue_task('/tasks/email-subscribers', params)
|
||||
|
||||
def notify_subscribers_and_save_amendments(fe: 'FeatureEntry',
|
||||
changed_fields: CHANGED_FIELDS_LIST_TYPE, notify: bool=True) -> None:
|
||||
def notify_subscribers_and_save_amendments(
|
||||
fe: 'FeatureEntry', changed_fields: CHANGED_FIELDS_LIST_TYPE,
|
||||
notify: bool=True, is_update: bool=True) -> None:
|
||||
"""Notify subscribers of changes to FeatureEntry and save amendments."""
|
||||
amendments = _get_changes_as_amendments(changed_fields)
|
||||
|
||||
|
@ -76,7 +77,7 @@ def notify_subscribers_and_save_amendments(fe: 'FeatureEntry',
|
|||
activity.put()
|
||||
|
||||
if notify:
|
||||
notify_feature_subscribers_of_changes(fe, amendments)
|
||||
notify_feature_subscribers_of_changes(fe, amendments, is_update=is_update)
|
||||
|
||||
|
||||
def notify_approvers_of_reviews(
|
||||
|
|
|
@ -231,6 +231,18 @@ class EmailFormattingTest(testing_config.CustomTestCase):
|
|||
self.assertEqual('subject', actual['subject'])
|
||||
self.assertEqual('triggerer@example.com', actual['reply_to'])
|
||||
|
||||
def test_apply_subscription_rules__iwa_match(self):
|
||||
"""When a feature has category IWA rule, a reason is returned."""
|
||||
self.fe_1.category = core_enums.IWA
|
||||
changes = [{'prop_name': 'shipped_android_milestone'}] # Anything
|
||||
|
||||
actual = notifier.apply_subscription_rules(
|
||||
self.fe_1, changes)
|
||||
|
||||
self.assertEqual(
|
||||
{notifier.IWA_RULE_REASON: notifier.IWA_RULE_ADDRS},
|
||||
actual)
|
||||
|
||||
def test_apply_subscription_rules__relevant_match(self):
|
||||
"""When a feature and change match a rule, a reason is returned."""
|
||||
self.ship_stage.milestones.android_first = 88
|
||||
|
|
|
@ -83,6 +83,9 @@ class FeatureCreateHandler(basehandlers.FlaskHandler):
|
|||
# Write each Stage and Gate entity for the given feature.
|
||||
self.write_gates_and_stages_for_feature(key.integer_id(), feature_type)
|
||||
|
||||
notifier_helpers.notify_subscribers_and_save_amendments(
|
||||
feature_entry, [], is_update=False)
|
||||
|
||||
# Remove all feature-related cache.
|
||||
rediscache.delete_keys_with_prefix(FeatureEntry.feature_cache_prefix())
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
import testing_config # Must be imported before the module under test.
|
||||
|
||||
import flask
|
||||
from unittest import mock
|
||||
import werkzeug
|
||||
from google.cloud import ndb # type: ignore
|
||||
|
||||
|
@ -68,7 +69,8 @@ class FeatureCreateTest(testing_config.CustomTestCase):
|
|||
with self.assertRaises(werkzeug.exceptions.Forbidden):
|
||||
self.handler.post()
|
||||
|
||||
def test_post__normal_valid(self):
|
||||
@mock.patch('internals.notifier_helpers.notify_subscribers_and_save_amendments')
|
||||
def test_post__normal_valid(self, mock_notify):
|
||||
"""Allowed user can create a feature."""
|
||||
testing_config.sign_in('user1@google.com', 1234567890)
|
||||
with test_app.test_request_context(
|
||||
|
@ -100,6 +102,9 @@ class FeatureCreateTest(testing_config.CustomTestCase):
|
|||
self.assertEqual(len(stages), 6)
|
||||
self.assertEqual(len(gates), 11)
|
||||
|
||||
# Ensure notifications are sent.
|
||||
mock_notify.assert_called_once()
|
||||
|
||||
|
||||
class FeatureEditHandlerTest(testing_config.CustomTestCase):
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче