mirror of
				https://github.com/zulip/zulip.git
				synced 2025-10-31 03:53:50 +00:00 
			
		
		
		
	drafts: Add support for toggling drafts synchronization.
With changes mostly to the API documentation by tabbott.
This commit is contained in:
		
				
					committed by
					
						 Tim Abbott
						Tim Abbott
					
				
			
			
				
	
			
			
			
						parent
						
							4d3b10d84d
						
					
				
				
					commit
					c00089ac28
				
			| @@ -11,6 +11,15 @@ below features are supported. | ||||
|  | ||||
| ## Changes in Zulip 5.0 | ||||
|  | ||||
| **Feature level 87** | ||||
|  | ||||
| * [`PATCH /settings`](/api/update-settings): Added a new | ||||
|   `enable_drafts_synchronization` setting, which controls whether the | ||||
|   syncing drafts between different clients is enabled. | ||||
| * [`GET /events`](/api/get-events), [`POST /register`](/api/register-queue): | ||||
|   Added new `enable_drafts_synchronization` setting under | ||||
|   `update_display_settings`. | ||||
|  | ||||
| **Feature level 86** | ||||
|  | ||||
| * [`GET /events`](/api/get-events): Added `emoji_name`, | ||||
|   | ||||
| @@ -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 = 86 | ||||
| API_FEATURE_LEVEL = 87 | ||||
|  | ||||
| # 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 | ||||
|   | ||||
| @@ -197,6 +197,7 @@ from zerver.models import ( | ||||
|     CustomProfileFieldValue, | ||||
|     DefaultStream, | ||||
|     DefaultStreamGroup, | ||||
|     Draft, | ||||
|     EmailChangeStatus, | ||||
|     Message, | ||||
|     MultiuseInvite, | ||||
| @@ -5101,6 +5102,13 @@ def do_set_user_display_setting( | ||||
|             active_user_ids(user_profile.realm_id), | ||||
|         ) | ||||
|  | ||||
|     if setting_name == "enable_drafts_synchronization" and setting_value is False: | ||||
|         # Delete all of the drafts from the backend but don't send delete events | ||||
|         # for them since all that's happened is that we stopped syncing changes, | ||||
|         # not deleted every previously synced draft - to do that use the DELETE | ||||
|         # endpoint. | ||||
|         Draft.objects.filter(user_profile=user_profile).delete() | ||||
|  | ||||
|  | ||||
| def lookup_default_stream_groups( | ||||
|     default_stream_group_names: List[str], realm: Realm | ||||
|   | ||||
| @@ -1354,6 +1354,7 @@ class UserBaseSettings(models.Model): | ||||
|         demote_inactive_streams=int, | ||||
|         dense_mode=bool, | ||||
|         emojiset=str, | ||||
|         enable_drafts_synchronization=bool, | ||||
|         enter_sends=bool, | ||||
|         fluid_layout_width=bool, | ||||
|         high_contrast_mode=bool, | ||||
|   | ||||
| @@ -8830,6 +8830,17 @@ paths: | ||||
|  | ||||
|                           See [PATCH /settings](/api/update-settings) for details on | ||||
|                           the meaning of this setting. | ||||
|                       enable_drafts_synchronization: | ||||
|                         type: boolean | ||||
|                         description: | | ||||
|                           Present if `update_display_settings` is present in `fetch_event_types`. | ||||
|  | ||||
|                           Whether drafts synchronization is enabled for the user. | ||||
|  | ||||
|                           See [PATCH /settings](/api/update-settings) for details on | ||||
|                           the meaning of this setting. | ||||
|  | ||||
|                           **Changes**: New in Zulip 5.0 (feature level 87). | ||||
|                       fluid_layout_width: | ||||
|                         type: boolean | ||||
|                         description: | | ||||
| @@ -10294,6 +10305,20 @@ paths: | ||||
|                   - 2 | ||||
|                   - 3 | ||||
|               example: 1 | ||||
|         - name: enable_drafts_synchronization | ||||
|           in: query | ||||
|           description: | | ||||
|             A boolean parameter to control whether synchronizing drafts is enabled for | ||||
|             the user. When synchronization is disabled, all drafts stored in the server | ||||
|             will be automatically deleted from the server. | ||||
|  | ||||
|             This does not do anything (like sending events) to delete local copies of | ||||
|             drafts stored in clients. | ||||
|  | ||||
|             **Changes**: New in Zulip 5.0 (feature level 87). | ||||
|           schema: | ||||
|             type: boolean | ||||
|           example: true | ||||
|         - name: translate_emoticons | ||||
|           in: query | ||||
|           description: | | ||||
|   | ||||
| @@ -2299,3 +2299,21 @@ class SubscribeActionTest(BaseAction): | ||||
|             events[0]["streams"][0]["message_retention_days"], | ||||
|             10, | ||||
|         ) | ||||
|  | ||||
|  | ||||
| class DraftActionTest(BaseAction): | ||||
|     def do_enable_drafts_synchronization(self, user_profile: UserProfile) -> None: | ||||
|         do_set_user_display_setting(user_profile, "enable_drafts_synchronization", True) | ||||
|  | ||||
|     def do_disable_drafts_synchronization(self, user_profile: UserProfile) -> None: | ||||
|         do_set_user_display_setting(user_profile, "enable_drafts_synchronization", False) | ||||
|  | ||||
|     def test_enable_syncing_drafts(self) -> None: | ||||
|         self.do_disable_drafts_synchronization(self.user_profile) | ||||
|         action = lambda: self.do_enable_drafts_synchronization(self.user_profile) | ||||
|         self.verify_action(action) | ||||
|  | ||||
|     def test_disable_syncing_drafts(self) -> None: | ||||
|         self.do_enable_drafts_synchronization(self.user_profile) | ||||
|         action = lambda: self.do_disable_drafts_synchronization(self.user_profile) | ||||
|         self.verify_action(action) | ||||
|   | ||||
| @@ -70,6 +70,7 @@ class HomeTest(ZulipTestCase): | ||||
|         "emojiset_choices", | ||||
|         "enable_desktop_notifications", | ||||
|         "enable_digest_emails", | ||||
|         "enable_drafts_synchronization", | ||||
|         "enable_login_emails", | ||||
|         "enable_marketing_emails", | ||||
|         "enable_offline_email_notifications", | ||||
|   | ||||
| @@ -11,7 +11,7 @@ from zerver.lib.rate_limiter import add_ratelimit_rule, remove_ratelimit_rule | ||||
| from zerver.lib.test_classes import ZulipTestCase | ||||
| from zerver.lib.test_helpers import get_test_image_file | ||||
| from zerver.lib.users import get_all_api_keys | ||||
| from zerver.models import UserProfile, get_user_profile_by_api_key | ||||
| from zerver.models import Draft, UserProfile, get_user_profile_by_api_key | ||||
|  | ||||
|  | ||||
| class ChangeSettingsTest(ZulipTestCase): | ||||
| @@ -473,3 +473,52 @@ class UserChangesTest(ZulipTestCase): | ||||
|  | ||||
|         for api_key in current_api_keys: | ||||
|             self.assertEqual(get_user_profile_by_api_key(api_key).email, email) | ||||
|  | ||||
|  | ||||
| class UserDraftSettingsTests(ZulipTestCase): | ||||
|     def test_enable_drafts_syncing(self) -> None: | ||||
|         hamlet = self.example_user("hamlet") | ||||
|         hamlet.enable_drafts_synchronization = False | ||||
|         hamlet.save() | ||||
|         payload = {"enable_drafts_synchronization": orjson.dumps(True).decode()} | ||||
|         resp = self.api_patch(hamlet, "/api/v1/settings", payload) | ||||
|         self.assert_json_success(resp) | ||||
|         hamlet = self.example_user("hamlet") | ||||
|         self.assertTrue(hamlet.enable_drafts_synchronization) | ||||
|  | ||||
|     def test_disable_drafts_syncing(self) -> None: | ||||
|         aaron = self.example_user("aaron") | ||||
|         self.assertTrue(aaron.enable_drafts_synchronization) | ||||
|  | ||||
|         initial_count = Draft.objects.count() | ||||
|  | ||||
|         # Create some drafts. These should be deleted once aaron disables | ||||
|         # syncing drafts. | ||||
|         visible_stream_id = self.get_stream_id(self.get_streams(aaron)[0]) | ||||
|         draft_dicts = [ | ||||
|             { | ||||
|                 "type": "stream", | ||||
|                 "to": [visible_stream_id], | ||||
|                 "topic": "thinking out loud", | ||||
|                 "content": "What if pigs really could fly?", | ||||
|                 "timestamp": 15954790199, | ||||
|             }, | ||||
|             { | ||||
|                 "type": "private", | ||||
|                 "to": [], | ||||
|                 "topic": "", | ||||
|                 "content": "What if made it possible to sync drafts in Zulip?", | ||||
|                 "timestamp": 1595479020, | ||||
|             }, | ||||
|         ] | ||||
|         payload = {"drafts": orjson.dumps(draft_dicts).decode()} | ||||
|         resp = self.api_post(aaron, "/api/v1/drafts", payload) | ||||
|         self.assert_json_success(resp) | ||||
|         self.assertEqual(Draft.objects.count() - initial_count, 2) | ||||
|  | ||||
|         payload = {"enable_drafts_synchronization": orjson.dumps(False).decode()} | ||||
|         resp = self.api_patch(aaron, "/api/v1/settings", payload) | ||||
|         self.assert_json_success(resp) | ||||
|         aaron = self.example_user("aaron") | ||||
|         self.assertFalse(aaron.enable_drafts_synchronization) | ||||
|         self.assertEqual(Draft.objects.count() - initial_count, 0) | ||||
|   | ||||
| @@ -123,6 +123,7 @@ def json_change_settings( | ||||
|     email_notifications_batching_period_seconds: Optional[int] = REQ( | ||||
|         json_validator=check_int, default=None | ||||
|     ), | ||||
|     enable_drafts_synchronization: Optional[bool] = REQ(json_validator=check_bool, default=None), | ||||
|     enable_stream_desktop_notifications: Optional[bool] = REQ( | ||||
|         json_validator=check_bool, default=None | ||||
|     ), | ||||
|   | ||||
		Reference in New Issue
	
	Block a user