Zulip 服务器和 Web 应用程序。开源团队聊天可帮助团队保持高效和专注。
Go to file
Steve Howell 176ab66fc7 event_schema: Extract check_realm_user_update.
This a pretty big commit, but I really wanted it
to be atomic.

All realm_user/update events look the same from
the top:

    _check_realm_user_update = check_events_dict(
        required_keys=[
            ("type", equals("realm_user")),
            ("op", equals("update")),
            ("person", _check_realm_user_person),
        ]
    )

And then we have a bunch of fields for person that
are optional, and we usually only send user_id plus
one other field, with the exception of avatar-related
events:

    _check_realm_user_person = check_dict_only(
        required_keys=[
            # vertical formatting
            ("user_id", check_int),
        ],
        optional_keys=[
            ("avatar_source", check_string),
            ("avatar_url", check_none_or(check_string)),
            ("avatar_url_medium", check_none_or(check_string)),
            ("avatar_version", check_int),
            ("bot_owner_id", check_int),
            ("custom_profile_field", _check_custom_profile_field),
            ("delivery_email", check_string),
            ("full_name", check_string),
            ("role", check_int_in(UserProfile.ROLE_TYPES)),
            ("email", check_string),
            ("user_id", check_int),
            ("timezone", check_string),
        ],
    )

I would start the code review by just skimming the changes
to event_schema.py, to get the big picture of the complexity
here.  Basically the schema is just the combined superset of
all the individual schemas that we remove from test_events.

Then I would read test_events.py.

The simplest diffs are basically of this form:

    -  schema_checker = check_events_dict([
    -      ('type', equals('realm_user')),
    -      ('op', equals('update')),
    -      ('person', check_dict_only([
    -          ('role', check_int_in(UserProfile.ROLE_TYPES)),
    -          ('user_id', check_int),
    -      ])),
    -  ])

    # ...
    -  schema_checker('events[0]', events[0])
    +  check_realm_user_update('events[0]', events[0], {'role'})

Instead of a custom schema checker, we use the "superset"
schema checker, but then we pass in the set of fields that we
expect to be there.  Note that 'user_id' is always there.

So most of the heavy lifting happens in this new function
in event_schema.py:

    def check_realm_user_update(
        var_name: str, event: Dict[str, Any], optional_fields: Set[str],
    ) -> None:
        _check_realm_user_update(var_name, event)

        keys = set(event["person"].keys()) - {"user_id"}
        assert optional_fields == keys

But we still do some more custom checks in test_events.py.

custom profile fields: check keys of custom_profile_field

     def test_custom_profile_field_data_events(self) -> None:
+        self.assertEqual(
+            events[0]['person']['custom_profile_field'].keys(),
+            {"id", "value", "rendered_value"}
+        )

+        check_realm_user_update('events[0]', events[0], {"custom_profile_field"})
+        self.assertEqual(
+            events[0]['person']['custom_profile_field'].keys(),
+            {"id", "value"}
+        )

avatar fields: check more specific types, since the superset
    schema has check_none_or(check_string)

     def test_change_avatar_fields(self) -> None:
+        check_realm_user_update('events[0]', events[0], avatar_fields)
+        assert isinstance(events[0]['person']['avatar_url'], str)
+        assert isinstance(events[0]['person']['avatar_url_medium'], str)

+        check_realm_user_update('events[0]', events[0], avatar_fields)
+        self.assertEqual(events[0]['person']['avatar_url'], None)
+        self.assertEqual(events[0]['person']['avatar_url_medium'], None)

Also note that avatar_fields is a set of four fields that
are set in event_schema.

full name: no extra work!

     def test_change_full_name(self) -> None:
-        schema_checker('events[0]', events[0])
+        check_realm_user_update('events[0]', events[0], {'full_name'})

test_change_user_delivery_email_email_address_visibilty_admins:

    no extra work for delivery_email
    check avatar fields more directly

roles (several examples) -- actually check the specific role

     def test_change_realm_authentication_methods(self) -> None:
-            schema_checker('events[0]', events[0])
+            check_realm_user_update('events[0]', events[0], {'role'})
+            self.assertEqual(events[0]['person']['role'], role)

bot_owner_id: no extra work!

-        change_bot_owner_checker_user('events[1]', events[1])
+        check_realm_user_update('events[1]', events[1], {"bot_owner_id"})

-        change_bot_owner_checker_user('events[1]', events[1])
+        check_realm_user_update('events[1]', events[1], {"bot_owner_id"})

-        change_bot_owner_checker_user('events[1]', events[1])
+        check_realm_user_update('events[1]', events[1], {"bot_owner_id"})

timezone: no extra work!

-                timezone_schema_checker('events[1]', events[1])
+                check_realm_user_update('events[1]', events[1], {"email", "timezone"})
2020-07-24 09:38:34 -07:00
.circleci lint: Reformat YAML files with Prettier. 2020-07-14 16:25:31 -07:00
.github lint: Reformat YAML files with Prettier. 2020-07-14 16:25:31 -07:00
.tx cleanup: Delete trailing newlines. 2019-08-06 23:29:11 -07:00
analytics database: Remove short_name from UserProfile. 2020-07-17 11:15:15 -07:00
confirmation python: Convert more percent formatting to Python 3.6 f-strings. 2020-06-14 23:27:22 -07:00
corporate billing: Don't allow guest users to upgrade. 2020-07-22 16:57:49 -07:00
docs docs: Fix versions in stretch=>buster documentation. 2020-07-22 16:35:05 -07:00
frontend_tests casper_tests: Log in as Desdemona, not Iago. 2020-07-23 10:26:27 -07:00
locale i18n: Update translation data from Transifex. 2020-07-23 12:06:15 -07:00
pgroonga migrations: Escape more pedantically in pgroonga.0003_v2_api_upgrade. 2020-06-13 21:50:37 -07:00
puppet puppet: Use correct scope for zulip_ops::munin_plugin. 2020-07-15 21:49:45 -07:00
requirements requirements: Upgrade zulint. 2020-07-14 00:41:20 -07:00
scripts install-node: Upgrade Node.js to 12.18.2. 2020-07-20 10:56:31 -07:00
static upload: Do not open compose box when editing. 2020-07-23 11:29:32 -07:00
stubs pysa: Introduce sanitizers, models, and inline marking safe. 2020-06-11 12:57:49 -07:00
templates billing: Restrict access to billing page to realm owners and billing admins. 2020-07-22 16:57:49 -07:00
tools casper_tests: Log in as Desdemona, not Iago. 2020-07-23 10:26:27 -07:00
zerver event_schema: Extract check_realm_user_update. 2020-07-24 09:38:34 -07:00
zilencer database: Remove short_name from UserProfile. 2020-07-17 11:15:15 -07:00
zproject loggers: Set propagate False for zulip.slow_queries logger. 2020-07-22 17:12:28 -07:00
zthumbor zthumbor: Rename thumbor.conf to thumbor_settings.py. 2020-07-06 18:44:58 -07:00
.browserslistrc webpack: Transpile JS code with Babel. 2019-07-22 17:55:32 -07:00
.codecov.yml codecov: Change threshold to use percentage syntax. 2019-07-20 14:37:04 -07:00
.editorconfig .editorconfig: Add .scss, .hbs; drop weirder rules. 2020-04-22 15:03:08 -07:00
.eslintignore blueslip: Apply ESLint. 2019-11-01 12:13:59 -07:00
.eslintrc.json js: Use ES6 object literal shorthand syntax. 2020-07-21 12:42:22 -07:00
.gitattributes Revert "gitattributes: Mark yarn.lock as "binary", i.e. suppress diffs." 2019-05-20 19:31:14 -07:00
.gitignore tools: Move CI docker images files into tools/ci. 2020-06-29 16:31:43 -07:00
.gitlint lint: Allow revert commit messages in gitlint. 2018-02-13 09:21:01 -08:00
.isort.cfg requirements: Upgrade isort. 2020-06-26 22:50:01 -07:00
.mailmap mailmap: Add mailmap entry for Alex Vandiver. 2020-07-16 00:08:41 -07:00
.npmignore Add proxy notes to new README.dev.md troubleshooting section. 2016-03-29 21:54:05 -07:00
.prettierignore lint: Use Prettier for JavaScript files. 2020-07-17 14:31:25 -07:00
.pyre_configuration pysa: Add basic .pyre_configuration and taint.config for pysa. 2020-06-11 12:57:49 -07:00
.sonarcloud.properties tools: Configure Zulip to be scannable by SonarCloud. 2020-06-24 12:41:17 -07:00
.stylelintrc lint: Ban color names in CSS. 2019-01-22 15:33:18 -08:00
.yarnrc .yarnrc: Set ignore-scripts true. 2019-08-28 16:15:54 -07:00
babel.config.js js: Remove extra consecutive spaces. 2020-07-17 14:31:25 -07:00
CODE_OF_CONDUCT.md docs: Convert many http URLs to https. 2020-03-26 21:35:32 -07:00
CONTRIBUTING.md docs: Update most remaining references to zulipchat.com. 2020-06-08 18:10:45 -07:00
Dockerfile-postgresql base Zulip PostgreSQL Docker container on PGroonga official one 2019-12-30 10:20:25 -08:00
LICENSE docs: Bump copyright year. 2020-04-23 16:04:54 -07:00
manage.py python: Sort imports with isort. 2020-06-11 16:45:32 -07:00
mypy.ini zthumbor: Fix strict_optional errors. 2020-07-06 11:25:48 -07:00
NOTICE license: Move license application notice from LICENSE to NOTICE. 2018-10-02 12:04:44 -07:00
package.json dependencies: Upgrade JavaScript dependencies. 2020-07-20 10:56:31 -07:00
postcss.config.js js: Remove inner spacing from object literals. 2020-07-17 14:31:25 -07:00
prettier.config.js lint: Use Prettier for JavaScript files. 2020-07-17 14:31:25 -07:00
README.md docs: Document that we use Prettier. 2020-07-22 15:49:48 -07:00
SECURITY.md docs: Create GitHub SECURITY.md file. 2020-06-25 15:23:22 -07:00
setup.cfg lint: Use standard setup.cfg configuration for pycodestyle. 2020-07-14 00:41:20 -07:00
tsconfig.json tsconfig: Enable resolveJsonModule. 2020-05-26 23:33:40 -07:00
Vagrantfile vagrant: Remove uartmode1 woarkound. 2020-06-22 14:56:38 -07:00
version.py version: Bump PROVISION_VERSION for :slight_smile: rename. 2020-07-21 18:25:18 -07:00
yarn.lock dependencies: Upgrade JavaScript dependencies. 2020-07-20 10:56:31 -07:00

Zulip overview

Zulip is a powerful, open source group chat application that combines the immediacy of real-time chat with the productivity benefits of threaded conversations. Zulip is used by open source projects, Fortune 500 companies, large standards bodies, and others who need a real-time chat system that allows users to easily process hundreds or thousands of messages a day. With over 500 contributors merging over 500 commits a month, Zulip is also the largest and fastest growing open source group chat project.

CircleCI branch Coverage Status Mypy coverage code style: prettier GitHub release docs Zulip chat Twitter

Getting started

Click on the appropriate link below. If nothing seems to apply, join us on the Zulip community server and tell us what's up!

You might be interested in:

You may also be interested in reading our blog or following us on twitter. Zulip is distributed under the Apache 2.0 license.