def test_change_subscription_property(self) -> None: user = self.example_user('hamlet') # Fetch the Denmark stream for testing stream = get_stream("Denmark", user.realm) sub = Subscription.objects.get(user_profile=user, recipient__type=Recipient.STREAM, recipient__type_id=stream.id) properties = {"color": True, "is_muted": True, "desktop_notifications": False, "audible_notifications": False, "push_notifications": True, "email_notifications": True, "pin_to_top": True, "wildcard_mentions_notify": False} for property, value in properties.items(): now = timezone_now() old_value = getattr(sub, property) self.assertNotEqual(old_value, value) do_change_subscription_property(user, sub, stream, property, value, acting_user=user) expected_extra_data = {RealmAuditLog.OLD_VALUE: {'property': property, 'value': old_value}, RealmAuditLog.NEW_VALUE: {'property': property, 'value': value}} self.assertEqual(RealmAuditLog.objects.filter( realm=user.realm, event_type=RealmAuditLog.SUBSCRIPTION_PROPERTY_CHANGED, event_time__gte=now, acting_user=user, modified_user=user, extra_data=ujson.dumps(expected_extra_data)).count(), 1) self.assertEqual(getattr(sub, property), value)
def update_subscription_properties_backend( request: HttpRequest, user_profile: UserProfile, subscription_data: List[Dict[str, Any]] = REQ(validator=check_list( check_dict([("stream_id", check_int), ("property", check_string), ("value", check_union([check_string, check_bool]))]), ), ), ) -> HttpResponse: """ This is the entry point to changing subscription properties. This is a bulk endpoint: requestors always provide a subscription_data list containing dictionaries for each stream of interest. Requests are of the form: [{"stream_id": "1", "property": "is_muted", "value": False}, {"stream_id": "1", "property": "color", "value": "#c2c2c2"}] """ property_converters = { "color": check_color, "in_home_view": check_bool, "is_muted": check_bool, "desktop_notifications": check_bool, "audible_notifications": check_bool, "push_notifications": check_bool, "email_notifications": check_bool, "pin_to_top": check_bool, "wildcard_mentions_notify": check_bool } response_data = [] for change in subscription_data: stream_id = change["stream_id"] property = change["property"] value = change["value"] if property not in property_converters: return json_error( _("Unknown subscription property: {}").format(property)) (stream, recipient, sub) = access_stream_by_id(user_profile, stream_id) if sub is None: return json_error( _("Not subscribed to stream id {}").format(stream_id)) try: value = property_converters[property](property, value) except ValidationError as error: return json_error(error.message) do_change_subscription_property(user_profile, sub, stream, property, value) response_data.append({ 'stream_id': stream_id, 'property': property, 'value': value }) return json_success({"subscription_data": response_data})
def json_subscription_property( request, user_profile, subscription_data=REQ(validator=check_list( check_dict([("stream", check_string), ("property", check_string), ("value", check_variable_type([check_string, check_bool]))])))): # type: (HttpRequest, UserProfile, List[Dict[str, Any]]) -> HttpResponse """ This is the entry point to changing subscription properties. This is a bulk endpoint: requestors always provide a subscription_data list containing dictionaries for each stream of interest. Requests are of the form: [{"stream": "devel", "property": "in_home_view", "value": False}, {"stream": "devel", "property": "color", "value": "#c2c2c2"}] """ if request.method != "POST": return json_error(_("Invalid verb")) property_converters = { "color": check_string, "in_home_view": check_bool, "desktop_notifications": check_bool, "audible_notifications": check_bool, "pin_to_top": check_bool } response_data = [] for change in subscription_data: stream_name = change["stream"] property = change["property"] value = change["value"] if property not in property_converters: return json_error( _("Unknown subscription property: %s") % (property, )) (stream, recipient, sub) = access_stream_by_name(user_profile, stream_name) if sub is None: return json_error( _("Not subscribed to stream %s") % (stream_name, )) property_conversion = property_converters[property](property, value) if property_conversion: return json_error(property_conversion) do_change_subscription_property(user_profile, sub, stream, property, value) response_data.append({ 'stream': stream_name, 'property': property, 'value': value }) return json_success({"subscription_data": response_data})
def change_subscription_properties( user_profile: UserProfile, stream: Stream, sub: Subscription, properties: Dict[str, bool], ) -> None: for property_name, value in properties.items(): do_change_subscription_property(user_profile, sub, stream, property_name, value)
def json_subscription_property( request, user_profile, subscription_data=REQ( validator=check_list( check_dict( [ ("stream", check_string), ("property", check_string), ("value", check_variable_type([check_string, check_bool])), ] ) ) ), ): # type: (HttpRequest, UserProfile, List[Dict[str, Any]]) -> HttpResponse """ This is the entry point to changing subscription properties. This is a bulk endpoint: requestors always provide a subscription_data list containing dictionaries for each stream of interest. Requests are of the form: [{"stream": "devel", "property": "in_home_view", "value": False}, {"stream": "devel", "property": "color", "value": "#c2c2c2"}] """ if request.method != "POST": return json_error(_("Invalid verb")) property_converters = { "color": check_string, "in_home_view": check_bool, "desktop_notifications": check_bool, "audible_notifications": check_bool, "pin_to_top": check_bool, } response_data = [] for change in subscription_data: stream_name = change["stream"] property = change["property"] value = change["value"] if property not in property_converters: return json_error(_("Unknown subscription property: %s") % (property,)) sub = get_subscription_or_die(stream_name, user_profile)[0] property_conversion = property_converters[property](property, value) if property_conversion: return json_error(property_conversion) do_change_subscription_property(user_profile, sub, stream_name, property, value) response_data.append({"stream": stream_name, "property": property, "value": value}) return json_success({"subscription_data": response_data})
def json_subscription_property( request, user_profile, subscription_data=REQ(validator=check_list( check_dict([["stream", check_string], ["property", check_string], ["value", check_variable_type([check_string, check_bool])]])))): """ This is the entry point to changing subscription properties. This is a bulk endpoint: requestors always provide a subscription_data list containing dictionaries for each stream of interest. Requests are of the form: [{"stream": "devel", "property": "in_home_view", "value": False}, {"stream": "devel", "property": "color", "value": "#c2c2c2"}] """ if request.method != "POST": return json_error("Invalid verb") property_converters = { "color": check_string, "in_home_view": check_bool, "desktop_notifications": check_bool, "audible_notifications": check_bool } response_data = [] for change in subscription_data: stream_name = change["stream"] property = change["property"] value = change["value"] if property not in property_converters: return json_error("Unknown subscription property: %s" % (property, )) sub = get_subscription_or_die(stream_name, user_profile)[0] property_conversion = property_converters[property](property, value) if property_conversion: return json_error(property_conversion) do_change_subscription_property(user_profile, sub, stream_name, property, value) response_data.append({ 'stream': stream_name, 'property': property, 'value': value }) return json_success({"subscription_data": response_data})
def update_subscription_properties_backend( request: HttpRequest, user_profile: UserProfile, subscription_data: List[Dict[str, Any]]=REQ( validator=check_list( check_dict([("stream_id", check_int), ("property", check_string), ("value", check_variable_type([check_string, check_bool]))]) ) ), ) -> HttpResponse: """ This is the entry point to changing subscription properties. This is a bulk endpoint: requestors always provide a subscription_data list containing dictionaries for each stream of interest. Requests are of the form: [{"stream_id": "1", "property": "in_home_view", "value": False}, {"stream_id": "1", "property": "color", "value": "#c2c2c2"}] """ property_converters = {"color": check_color, "in_home_view": check_bool, "desktop_notifications": check_bool, "audible_notifications": check_bool, "push_notifications": check_bool, "email_notifications": check_bool, "pin_to_top": check_bool} response_data = [] for change in subscription_data: stream_id = change["stream_id"] property = change["property"] value = change["value"] if property not in property_converters: return json_error(_("Unknown subscription property: %s") % (property,)) (stream, recipient, sub) = access_stream_by_id(user_profile, stream_id) if sub is None: return json_error(_("Not subscribed to stream id %d") % (stream_id,)) property_conversion = property_converters[property](property, value) if property_conversion: return json_error(property_conversion) do_change_subscription_property(user_profile, sub, stream, property, value) response_data.append({'stream_id': stream_id, 'property': property, 'value': value}) return json_success({"subscription_data": response_data})
def update_subscription_properties_backend( request: HttpRequest, user_profile: UserProfile, subscription_data: List[Dict[str, Any]] = REQ(json_validator=check_list( check_dict([ ("stream_id", check_int), ("property", check_string), ("value", check_union([check_string, check_bool])), ]), ), ), ) -> HttpResponse: """ This is the entry point to changing subscription properties. This is a bulk endpoint: requestors always provide a subscription_data list containing dictionaries for each stream of interest. Requests are of the form: [{"stream_id": "1", "property": "is_muted", "value": False}, {"stream_id": "1", "property": "color", "value": "#c2c2c2"}] """ property_converters = { "color": check_color, "in_home_view": check_bool, "is_muted": check_bool, "desktop_notifications": check_bool, "audible_notifications": check_bool, "push_notifications": check_bool, "email_notifications": check_bool, "pin_to_top": check_bool, "wildcard_mentions_notify": check_bool, } for change in subscription_data: stream_id = change["stream_id"] property = change["property"] value = change["value"] if property not in property_converters: raise JsonableError( _("Unknown subscription property: {}").format(property)) (stream, sub) = access_stream_by_id(user_profile, stream_id) if sub is None: raise JsonableError( _("Not subscribed to stream id {}").format(stream_id)) try: value = property_converters[property](property, value) except ValidationError as error: raise JsonableError(error.message) do_change_subscription_property(user_profile, sub, stream, property, value, acting_user=user_profile) # TODO: Do this more generally, see update_realm_user_settings_defaults.realm.py from zerver.lib.request import RequestNotes request_notes = RequestNotes.get_notes(request) for req_var in request.POST: if req_var not in request_notes.processed_parameters: request_notes.ignored_parameters.add(req_var) result: Dict[str, Any] = {} if len(request_notes.ignored_parameters) > 0: result["ignored_parameters_unsupported"] = list( request_notes.ignored_parameters) return json_success(request, data=result)