Example #1
0
    def test_user_settings_based_on_client_capabilities(self) -> None:
        hamlet = self.example_user("hamlet")
        result = fetch_initial_state_data(
            user_profile=hamlet,
            user_settings_object=True,
        )
        self.assertIn("user_settings", result)
        for prop in UserProfile.property_types:
            self.assertNotIn(prop, result)
            self.assertIn(prop, result["user_settings"])
        for prop in UserProfile.notification_setting_types:
            self.assertNotIn(prop, result)
            self.assertIn(prop, result["user_settings"])

        result = fetch_initial_state_data(
            user_profile=hamlet,
            user_settings_object=False,
        )
        self.assertIn("user_settings", result)
        for prop in UserProfile.property_types:
            self.assertIn(prop, result)
            self.assertIn(prop, result["user_settings"])
        for prop in UserProfile.notification_setting_types:
            self.assertIn(prop, result)
            self.assertIn(prop, result["user_settings"])
Example #2
0
    def test_delivery_email_presence_for_non_admins(self) -> None:
        user_profile = self.example_user("aaron")
        self.assertFalse(user_profile.is_realm_admin)

        do_set_realm_property(
            user_profile.realm,
            "email_address_visibility",
            Realm.EMAIL_ADDRESS_VISIBILITY_EVERYONE,
            acting_user=None,
        )
        result = fetch_initial_state_data(user_profile)

        for key, value in result["raw_users"].items():
            self.assertNotIn("delivery_email", value)

        do_set_realm_property(
            user_profile.realm,
            "email_address_visibility",
            Realm.EMAIL_ADDRESS_VISIBILITY_ADMINS,
            acting_user=None,
        )
        result = fetch_initial_state_data(user_profile)

        for key, value in result["raw_users"].items():
            self.assertNotIn("delivery_email", value)
    def test_queries(self) -> None:
        user = self.example_user("hamlet")

        self.login_user(user)

        flush_per_request_caches()
        with queries_captured() as queries:
            with mock.patch("zerver.lib.events.always_want") as want_mock:
                fetch_initial_state_data(user)

        self.assert_length(queries, 31)

        expected_counts = dict(
            alert_words=1,
            custom_profile_fields=1,
            default_streams=1,
            default_stream_groups=1,
            hotspots=0,
            message=1,
            muted_topics=1,
            muted_users=1,
            presence=1,
            realm=0,
            realm_bot=1,
            realm_domains=1,
            realm_embedded_bots=0,
            realm_incoming_webhook_bots=0,
            realm_emoji=1,
            realm_filters=1,
            realm_playgrounds=1,
            realm_user=3,
            realm_user_groups=2,
            recent_private_conversations=1,
            starred_messages=1,
            stream=2,
            stop_words=0,
            subscription=4,
            update_display_settings=0,
            update_global_notifications=0,
            update_message_flags=5,
            user_status=1,
            video_calls=0,
            giphy=0,
        )

        wanted_event_types = {item[0][0] for item in want_mock.call_args_list}

        self.assertEqual(wanted_event_types, set(expected_counts))

        for event_type in sorted(wanted_event_types):
            count = expected_counts[event_type]
            flush_per_request_caches()
            with queries_captured() as queries:
                if event_type == "update_message_flags":
                    event_types = ["update_message_flags", "message"]
                else:
                    event_types = [event_type]

                fetch_initial_state_data(user, event_types=event_types)
            self.assert_length(queries, count)
Example #4
0
    def test_delivery_email_presence_for_admins(self) -> None:
        user_profile = self.example_user('iago')
        self.assertTrue(user_profile.is_realm_admin)

        do_set_realm_property(user_profile.realm, "email_address_visibility",
                              Realm.EMAIL_ADDRESS_VISIBILITY_EVERYONE)
        result = fetch_initial_state_data(user_profile,
                                          None,
                                          "",
                                          client_gravatar=False,
                                          user_avatar_url_field_optional=False,
                                          realm=user_profile.realm)
        for key, value in result['raw_users'].items():
            self.assertNotIn('delivery_email', value)

        do_set_realm_property(user_profile.realm, "email_address_visibility",
                              Realm.EMAIL_ADDRESS_VISIBILITY_ADMINS)
        result = fetch_initial_state_data(user_profile,
                                          None,
                                          "",
                                          client_gravatar=False,
                                          user_avatar_url_field_optional=False,
                                          realm=user_profile.realm)
        for key, value in result['raw_users'].items():
            self.assertIn('delivery_email', value)
Example #5
0
    def test_user_avatar_url_field_optional(self) -> None:
        hamlet = self.example_user('hamlet')
        users = [
            self.example_user('iago'),
            self.example_user('cordelia'),
            self.example_user('ZOE'),
            self.example_user('othello'),
        ]

        for user in users:
            user.long_term_idle = True
            user.save()

        long_term_idle_users_ids = [user.id for user in users]

        result = fetch_initial_state_data(user_profile=hamlet,
                                          event_types=None,
                                          queue_id='',
                                          client_gravatar=False,
                                          user_avatar_url_field_optional=True,
                                          realm=hamlet.realm)

        raw_users = result['raw_users']

        for user_dict in raw_users.values():
            if user_dict['user_id'] in long_term_idle_users_ids:
                self.assertFalse('avatar_url' in user_dict)
            else:
                self.assertIsNotNone(user_dict['avatar_url'])

        gravatar_users_id = [
            user_dict['user_id'] for user_dict in raw_users.values()
            if 'avatar_url' in user_dict
            and 'gravatar.com' in user_dict['avatar_url']
        ]

        # Test again with client_gravatar = True
        result = fetch_initial_state_data(user_profile=hamlet,
                                          event_types=None,
                                          queue_id='',
                                          client_gravatar=True,
                                          user_avatar_url_field_optional=True,
                                          realm=hamlet.realm)

        raw_users = result['raw_users']

        for user_dict in raw_users.values():
            if user_dict['user_id'] in gravatar_users_id:
                self.assertIsNone(user_dict['avatar_url'])
            else:
                self.assertFalse('avatar_url' in user_dict)
Example #6
0
    def test_user_avatar_url_field_optional(self) -> None:
        hamlet = self.example_user("hamlet")
        users = [
            self.example_user("iago"),
            self.example_user("cordelia"),
            self.example_user("ZOE"),
            self.example_user("othello"),
        ]

        for user in users:
            user.long_term_idle = True
            user.save()

        long_term_idle_users_ids = [user.id for user in users]

        result = fetch_initial_state_data(
            user_profile=hamlet,
            user_avatar_url_field_optional=True,
        )

        raw_users = result["raw_users"]

        for user_dict in raw_users.values():
            if user_dict["user_id"] in long_term_idle_users_ids:
                self.assertFalse("avatar_url" in user_dict)
            else:
                self.assertIsNotNone(user_dict["avatar_url"])

        gravatar_users_id = [
            user_dict["user_id"] for user_dict in raw_users.values()
            if "avatar_url" in user_dict
            and "gravatar.com" in user_dict["avatar_url"]
        ]

        # Test again with client_gravatar = True
        result = fetch_initial_state_data(
            user_profile=hamlet,
            client_gravatar=True,
            user_avatar_url_field_optional=True,
        )

        raw_users = result["raw_users"]

        for user_dict in raw_users.values():
            if user_dict["user_id"] in gravatar_users_id:
                self.assertIsNone(user_dict["avatar_url"])
            else:
                self.assertFalse("avatar_url" in user_dict)
Example #7
0
 def test_realm_bots_admin(self) -> None:
     user_profile = self.example_user("hamlet")
     do_change_user_role(user_profile,
                         UserProfile.ROLE_REALM_ADMINISTRATOR,
                         acting_user=None)
     self.assertTrue(user_profile.is_realm_admin)
     result = fetch_initial_state_data(user_profile)
     self.assertGreater(len(result["realm_bots"]), 2)
Example #8
0
    def test_realm_bots_non_admin(self) -> None:
        user_profile = self.example_user("cordelia")
        self.assertFalse(user_profile.is_realm_admin)
        result = fetch_initial_state_data(user_profile)
        self.assert_length(result["realm_bots"], 0)

        # additionally the API key for a random bot is not present in the data
        api_key = get_api_key(self.notification_bot(user_profile.realm))
        self.assertNotIn(api_key, str(result))
Example #9
0
 def test_max_message_id_with_no_history(self) -> None:
     user_profile = self.example_user('aaron')
     # Delete all historical messages for this user
     UserMessage.objects.filter(user_profile=user_profile).delete()
     result = fetch_initial_state_data(user_profile,
                                       None,
                                       "",
                                       client_gravatar=False,
                                       user_avatar_url_field_optional=False)
     self.assertEqual(result['max_message_id'], -1)
Example #10
0
 def test_realm_bots_admin(self) -> None:
     user_profile = self.example_user('hamlet')
     do_change_user_role(user_profile, UserProfile.ROLE_REALM_ADMINISTRATOR)
     self.assertTrue(user_profile.is_realm_admin)
     result = fetch_initial_state_data(user_profile,
                                       None,
                                       "",
                                       client_gravatar=False,
                                       user_avatar_url_field_optional=False)
     self.assertTrue(len(result['realm_bots']) > 2)
Example #11
0
    def test_realm_bots_non_admin(self) -> None:
        user_profile = self.example_user('cordelia')
        self.assertFalse(user_profile.is_realm_admin)
        result = fetch_initial_state_data(user_profile,
                                          None,
                                          "",
                                          client_gravatar=False,
                                          user_avatar_url_field_optional=False)
        self.assert_length(result['realm_bots'], 0)

        # additionally the API key for a random bot is not present in the data
        api_key = get_api_key(self.notification_bot())
        self.assertNotIn(api_key, str(result))
Example #12
0
    def test_user_settings_based_on_client_capabilities(self) -> None:
        hamlet = self.example_user("hamlet")
        result = fetch_initial_state_data(
            user_profile=hamlet,
            user_settings_object=True,
        )
        self.assertIn("user_settings", result)
        for prop in UserProfile.property_types:
            self.assertNotIn(prop, result)
            self.assertIn(prop, result["user_settings"])

        result = fetch_initial_state_data(
            user_profile=hamlet,
            user_settings_object=False,
        )
        self.assertIn("user_settings", result)
        for prop in UserProfile.property_types:
            if prop in {
                    **UserProfile.display_settings_legacy,
                    **UserProfile.notification_settings_legacy,
            }:
                # Only legacy settings are included in the top level.
                self.assertIn(prop, result)
            self.assertIn(prop, result["user_settings"])
Example #13
0
 def test_max_message_id_with_no_history(self) -> None:
     user_profile = self.example_user("aaron")
     # Delete all historical messages for this user
     UserMessage.objects.filter(user_profile=user_profile).delete()
     result = fetch_initial_state_data(user_profile)
     self.assertEqual(result["max_message_id"], -1)
Example #14
0
def build_page_params_for_home_page_load(
    request: HttpRequest,
    user_profile: Optional[UserProfile],
    realm: Realm,
    insecure_desktop_app: bool,
    narrow: List[List[str]],
    narrow_stream: Optional[Stream],
    narrow_topic: Optional[str],
    first_in_realm: bool,
    prompt_for_invites: bool,
    needs_tutorial: bool,
) -> Tuple[int, Dict[str, Any]]:
    """
    This function computes page_params for when we load the home page.

    The page_params data structure gets sent to the client.
    """
    client_capabilities = {
        "notification_settings_null": True,
        "bulk_message_deletion": True,
        "user_avatar_url_field_optional": True,
        "stream_typing_notifications": False,  # Set this to True when frontend support is implemented.
        "user_settings_object": True,
    }

    if user_profile is not None:
        client = RequestNotes.get_notes(request).client
        assert client is not None
        register_ret = do_events_register(
            user_profile,
            client,
            apply_markdown=True,
            client_gravatar=True,
            slim_presence=True,
            client_capabilities=client_capabilities,
            narrow=narrow,
            include_streams=False,
        )
    else:
        # Since events for spectator is not implemented, we only fetch the data
        # at the time of request and don't register for any events.
        # TODO: Implement events for spectator.
        from zerver.lib.events import fetch_initial_state_data, post_process_state

        register_ret = fetch_initial_state_data(
            user_profile,
            realm=realm,
            event_types=None,
            queue_id=None,
            client_gravatar=False,
            user_avatar_url_field_optional=client_capabilities["user_avatar_url_field_optional"],
            user_settings_object=client_capabilities["user_settings_object"],
            slim_presence=False,
            include_subscribers=False,
            include_streams=False,
        )

        post_process_state(user_profile, register_ret, False)

    furthest_read_time = get_furthest_read_time(user_profile)

    request_language = get_and_set_request_language(
        request,
        register_ret["user_settings"]["default_language"],
        translation.get_language_from_path(request.path_info),
    )

    two_fa_enabled = settings.TWO_FACTOR_AUTHENTICATION_ENABLED and user_profile is not None
    billing_info = get_billing_info(user_profile)
    user_permission_info = get_user_permission_info(user_profile)

    # Pass parameters to the client-side JavaScript code.
    # These end up in a JavaScript Object named 'page_params'.
    page_params = dict(
        ## Server settings.
        test_suite=settings.TEST_SUITE,
        insecure_desktop_app=insecure_desktop_app,
        login_page=settings.HOME_NOT_LOGGED_IN,
        warn_no_email=settings.WARN_NO_EMAIL,
        search_pills_enabled=settings.SEARCH_PILLS_ENABLED,
        # Only show marketing email settings if on Zulip Cloud
        corporate_enabled=settings.CORPORATE_ENABLED,
        ## Misc. extra data.
        language_list=get_language_list(),
        needs_tutorial=needs_tutorial,
        first_in_realm=first_in_realm,
        prompt_for_invites=prompt_for_invites,
        furthest_read_time=furthest_read_time,
        bot_types=get_bot_types(user_profile),
        two_fa_enabled=two_fa_enabled,
        apps_page_url=get_apps_page_url(),
        show_billing=billing_info.show_billing,
        promote_sponsoring_zulip=promote_sponsoring_zulip_in_realm(realm),
        show_plans=billing_info.show_plans,
        show_webathena=user_permission_info.show_webathena,
        # Adding two_fa_enabled as condition saves us 3 queries when
        # 2FA is not enabled.
        two_fa_enabled_user=two_fa_enabled and bool(default_device(user_profile)),
        is_spectator=user_profile is None,
        # There is no event queue for spectators since
        # events support for spectators is not implemented yet.
        no_event_queue=user_profile is None,
    )

    for field_name in register_ret.keys():
        page_params[field_name] = register_ret[field_name]

    if narrow_stream is not None:
        # In narrow_stream context, initial pointer is just latest message
        recipient = narrow_stream.recipient
        try:
            max_message_id = (
                Message.objects.filter(recipient=recipient).order_by("id").reverse()[0].id
            )
        except IndexError:
            max_message_id = -1
        page_params["narrow_stream"] = narrow_stream.name
        if narrow_topic is not None:
            page_params["narrow_topic"] = narrow_topic
        page_params["narrow"] = [dict(operator=term[0], operand=term[1]) for term in narrow]
        page_params["max_message_id"] = max_message_id
        assert isinstance(page_params["user_settings"], dict)
        page_params["user_settings"]["enable_desktop_notifications"] = False

    page_params["translation_data"] = get_language_translation_data(request_language)

    return register_ret["queue_id"], page_params
Example #15
0
 def test_realm_bots_admin(self) -> None:
     user_profile = self.example_user('hamlet')
     do_change_user_role(user_profile, UserProfile.ROLE_REALM_ADMINISTRATOR)
     self.assertTrue(user_profile.is_realm_admin)
     result = fetch_initial_state_data(user_profile)
     self.assertTrue(len(result['realm_bots']) > 2)
Example #16
0
def build_page_params_for_home_page_load(
    request: HttpRequest,
    user_profile: Optional[UserProfile],
    realm: Realm,
    insecure_desktop_app: bool,
    has_mobile_devices: bool,
    narrow: List[List[str]],
    narrow_stream: Optional[Stream],
    narrow_topic: Optional[str],
    first_in_realm: bool,
    prompt_for_invites: bool,
    needs_tutorial: bool,
) -> Tuple[int, Dict[str, Any]]:
    """
    This function computes page_params for when we load the home page.

    The page_params data structure gets sent to the client.
    """
    client_capabilities = {
        "notification_settings_null": True,
        "bulk_message_deletion": True,
        "user_avatar_url_field_optional": True,
    }

    if user_profile is not None:
        register_ret = do_events_register(
            user_profile,
            request.client,
            apply_markdown=True,
            client_gravatar=True,
            slim_presence=True,
            client_capabilities=client_capabilities,
            narrow=narrow,
            include_streams=False,
        )
    else:
        # Since events for web_public_visitor is not implemented, we only fetch the data
        # at the time of request and don't register for any events.
        # TODO: Implement events for web_public_visitor.
        from zerver.lib.events import fetch_initial_state_data, post_process_state
        register_ret = fetch_initial_state_data(
            user_profile,
            event_types=None,
            queue_id=None,
            client_gravatar=False,
            user_avatar_url_field_optional=client_capabilities[
                'user_avatar_url_field_optional'],
            realm=realm,
            slim_presence=False,
            include_subscribers=False,
            include_streams=False)

        post_process_state(user_profile, register_ret, False)

    furthest_read_time = get_furthest_read_time(user_profile)

    request_language = get_and_set_request_language(
        request, register_ret['default_language'],
        translation.get_language_from_path(request.path_info))

    two_fa_enabled = (settings.TWO_FACTOR_AUTHENTICATION_ENABLED
                      and user_profile is not None)

    # Pass parameters to the client-side JavaScript code.
    # These end up in a global JavaScript Object named 'page_params'.
    page_params = dict(
        # Server settings.
        debug_mode=settings.DEBUG,
        test_suite=settings.TEST_SUITE,
        poll_timeout=settings.POLL_TIMEOUT,
        insecure_desktop_app=insecure_desktop_app,
        login_page=settings.HOME_NOT_LOGGED_IN,
        root_domain_uri=settings.ROOT_DOMAIN_URI,
        save_stacktraces=settings.SAVE_FRONTEND_STACKTRACES,
        warn_no_email=settings.WARN_NO_EMAIL,
        search_pills_enabled=settings.SEARCH_PILLS_ENABLED,
        # Misc. extra data.
        initial_servertime=time.time(
        ),  # Used for calculating relative presence age
        default_language_name=get_language_name(
            register_ret["default_language"]),
        language_list_dbl_col=get_language_list_for_templates(
            register_ret["default_language"]),
        language_list=get_language_list(),
        needs_tutorial=needs_tutorial,
        first_in_realm=first_in_realm,
        prompt_for_invites=prompt_for_invites,
        furthest_read_time=furthest_read_time,
        has_mobile_devices=has_mobile_devices,
        bot_types=get_bot_types(user_profile),
        two_fa_enabled=two_fa_enabled,
        # Adding two_fa_enabled as condition saves us 3 queries when
        # 2FA is not enabled.
        two_fa_enabled_user=two_fa_enabled
        and bool(default_device(user_profile)),
        is_web_public_visitor=user_profile is None,
        # There is no event queue for web_public_visitors since
        # events support for web_public_visitors is not implemented yet.
        no_event_queue=user_profile is None,
    )

    for field_name in register_ret.keys():
        page_params[field_name] = register_ret[field_name]

    if narrow_stream is not None:
        # In narrow_stream context, initial pointer is just latest message
        recipient = narrow_stream.recipient
        try:
            max_message_id = (Message.objects.filter(
                recipient=recipient).order_by("id").reverse()[0].id)
        except IndexError:
            max_message_id = -1
        page_params["narrow_stream"] = narrow_stream.name
        if narrow_topic is not None:
            page_params["narrow_topic"] = narrow_topic
        page_params["narrow"] = [
            dict(operator=term[0], operand=term[1]) for term in narrow
        ]
        page_params["max_message_id"] = max_message_id
        page_params["enable_desktop_notifications"] = False

    page_params["translation_data"] = get_language_translation_data(
        request_language)

    # Fetch data from the connected/logged in devices
    page_params["logged_in_devices"] = get_logged_in_devices()

    return register_ret["queue_id"], page_params