diff --git a/templates/zerver/api/changelog.md b/templates/zerver/api/changelog.md index 5303b11cae..19f11ce1a9 100644 --- a/templates/zerver/api/changelog.md +++ b/templates/zerver/api/changelog.md @@ -20,6 +20,12 @@ format used by the Zulip server that they are interacting with. ## Changes in Zulip 5.0 +**Feature level 111** + +* [`POST /subscriptions/properties`](/api/update-subscription-settings): + Removed `subscription_data` from response object, replacing it with + `ignored_parameters_unsupported`. + **Feature level 110** * [`POST /register`](/api/register-queue): Added diff --git a/version.py b/version.py index b8fa705048..f5d9527d4f 100644 --- a/version.py +++ b/version.py @@ -33,7 +33,7 @@ DESKTOP_WARNING_VERSION = "5.4.3" # Changes should be accompanied by documentation explaining what the # new level means in templates/zerver/api/changelog.md, as well as # "**Changes**" entries in the endpoint's documentation in `zulip.yaml`. -API_FEATURE_LEVEL = 110 +API_FEATURE_LEVEL = 111 # Bump the minor PROVISION_VERSION to indicate that folks should provision # only when going from an old version of the code to a newer version. Bump diff --git a/zerver/openapi/zulip.yaml b/zerver/openapi/zulip.yaml index 2926d3c83a..a2d8446d65 100644 --- a/zerver/openapi/zulip.yaml +++ b/zerver/openapi/zulip.yaml @@ -7857,6 +7857,11 @@ paths: per-stream notification settings. `POST {{ api_url }}/v1/users/me/subscriptions/properties` + + **Changes**: Prior to Zulip 5.0 (feature level 111), response + object included the `subscription_data` in the the + request. The endpoint now returns the more ergonimic + `ignored_parameters_unsupported` field instead. parameters: - name: subscription_data in: query @@ -7910,71 +7915,11 @@ paths: properties: result: {} msg: {} - subscription_data: - type: array - items: - type: object - additionalProperties: false - properties: - stream_id: - description: | - The unique ID of the stream. - type: integer - property: - type: string - description: | - The changed property. It is one of: - - - `color`: The hex value of the user's personal display color for the stream. - - `is_muted`: Whether the stream is [muted](/help/mute-a-stream).
- **Changes**: Prior to Zulip 2.1, this feature was - represented by the more confusingly named `in_home_view` (with the - opposite value, `in_home_view=!is_muted`); for - backwards-compatibility, modern Zulip still accepts/returns that property. - - `pin_to_top`: Whether to pin the stream at the top of the stream list. - - `desktop_notifications`: Whether to show desktop notifications for all - messages sent to the stream. - - `audible_notifications`: Whether to play a sound notification for all - messages sent to the stream. - - `push_notifications`: Whether to trigger a mobile push notification for - all messages sent to the stream. - - `email_notifications`: Whether to trigger an email notification for all - messages sent to the stream. - - `wildcard_mentions_notify`: whether wildcard mentions trigger notifications - as though they were personal mentions in this stream. - enum: - - color - - is_muted - - pin_to_top - - desktop_notifications - - audible_notifications - - push_notifications - - email_notifications - - wildcard_mentions_notify - - in_home_view - value: - description: | - The desired value of the property. - oneOf: - - type: boolean - - type: string - description: | - The same `subscription_data` array sent by the client for the request. + ignored_parameters_unsupported: + $ref: "#/components/schemas/IgnoredParametersUnsupported" example: { - "subscription_data": - [ - { - "stream_id": 1, - "property": "pin_to_top", - "value": true, - }, - { - "stream_id": 3, - "property": "color", - "value": "#f00f00", - }, - ], + "ignored_parameters_unsupported": ["invalid_parameter"], "result": "success", "msg": "", } @@ -11976,13 +11921,12 @@ paths: backwards-compatibility, and will be removed once clients have migrated to use this endpoint. - **Changes**: New in Zulip 5.0 (feature level 78). Previously, + **Changes**: Prior to Zulip 5.0 (feature level 78), the `/settings` endpoint indicated which parameters it had processed by including in the response object `"key": value` - entries for values successfully changed by the request. Now the - `/settings` endpoint indicates which parameters sent with the - request were not supported by this endpoint (see - `ignored_parameters_unsupported` below). + entries for values successfully changed by the request. That + was replaced by the more ergonomic + `ignored_parameters_unsupported` response parameter. The `/settings/notifications` and `/settings/display` endpoints also had this behavior before they became aliases of `/settings` @@ -13548,7 +13492,12 @@ components: implementation or an attempt to configure a new feature while connected to an older Zulip server that does not support said feature. - **Changes**: New in Zulip 5.0 (feature level 78) + **Changes**: Added to `POST /users/me/subscriptions/properties` in + Zulip 5.0 (feature level 111). + + Added to `PATCH /realm/user_settings_defaults` in Zulip 5.0 (feature level 96). + + Introduced in `PATCH /settings` in Zulip 5.0 (feature level 78). EventIdSchema: type: integer description: | diff --git a/zerver/tests/test_subs.py b/zerver/tests/test_subs.py index c4b65adae5..e4749abf09 100644 --- a/zerver/tests/test_subs.py +++ b/zerver/tests/test_subs.py @@ -2729,6 +2729,40 @@ class SubscriptionPropertiesTest(ZulipTestCase): ) self.assert_json_error(result, "Unknown subscription property: bad") + def test_ignored_parameters_in_subscriptions_properties_endpoint(self) -> None: + """ + Sending an invalid parameter with a valid parameter returns + an `ignored_parameters_unsupported` array. + """ + test_user = self.example_user("hamlet") + self.login_user(test_user) + + subs = gather_subscriptions(test_user)[0] + sub = subs[0] + json_result = self.api_post( + test_user, + "/api/v1/users/me/subscriptions/properties", + { + "subscription_data": orjson.dumps( + [ + { + "property": "wildcard_mentions_notify", + "stream_id": sub["stream_id"], + "value": True, + } + ] + ).decode(), + "invalid_parameter": orjson.dumps( + [{"property": "pin_to_top", "stream_id": sub["stream_id"], "value": False}] + ).decode(), + }, + ) + + self.assert_json_success(json_result) + result = orjson.loads(json_result.content) + self.assertIn("ignored_parameters_unsupported", result) + self.assertEqual(result["ignored_parameters_unsupported"], ["invalid_parameter"]) + class SubscriptionRestApiTest(ZulipTestCase): def test_basic_add_delete(self) -> None: diff --git a/zerver/views/streams.py b/zerver/views/streams.py index 70218bd583..8d000dd36e 100644 --- a/zerver/views/streams.py +++ b/zerver/views/streams.py @@ -877,7 +877,6 @@ def update_subscription_properties_backend( "pin_to_top": check_bool, "wildcard_mentions_notify": check_bool, } - response_data = [] for change in subscription_data: stream_id = change["stream_id"] @@ -900,6 +899,16 @@ def update_subscription_properties_backend( user_profile, sub, stream, property, value, acting_user=user_profile ) - response_data.append({"stream_id": stream_id, "property": property, "value": value}) + # TODO: Do this more generally, see update_realm_user_settings_defaults.realm.py + from zerver.lib.request import RequestNotes - return json_success({"subscription_data": response_data}) + 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(result)