Commit Graph

53063 Commits

Author SHA1 Message Date
Lalit Kumar Singh 5c2ba6c8fa ts: Migrate `avatar.js` module to TypeScript. 2023-09-08 13:09:12 -07:00
Lalit Kumar Singh 8d7a9162e2 jquery: Make `expectOne` helper function generic. 2023-09-08 13:09:12 -07:00
Karl Stolley df18d2768c images: Prevent default browser behavior on paste.
This introduces an early return when no files are found on the
clipboard, which is a necessary condition to safely invoke
`event.preventDefault()` without short-circuiting run-of-the-mill
pastes.

CZO discussion:
https://chat.zulip.org/#narrow/stream/191-kandra-support/topic/embedded.20links.20broken.3F/near/1635730
2023-09-08 13:04:04 -07:00
Anders Kaseorg 5fe0cb3054 pyproject: Delete trailing whitespace.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-09-08 10:13:47 -07:00
Aman Agrawal 34927a6d96 narrow: Don't call deactivate directly.
As stated in the deactivate function comments, it should be called
via `browser_history.go_to_location` so that all the correct
functions are called like recent view being hidden.

This fixes a bug where searching for nothing results in activating
all messages narrow without hiding recent view. Now, all messages
should be activated as expected.
2023-09-08 09:30:28 -07:00
Lauryn Menard 9959c48697 i18n: Fix formatting in recent_topic_row template.
Corrects formatting for translated string in handlebars template.

Fixes #26640.
2023-09-08 09:09:46 -07:00
Lauryn Menard 64929d7bd1 i18n: Simplify formatting in subscribe_to_more_streams template.
There's no need to use the multi-line `tr` block format here.
2023-09-08 09:09:46 -07:00
Tim Abbott bcff5580d1 makemessages: Fix handling of handlebars whitespace control.
Our logic for extracting strings from templates did not properly
handle the syntax for code containing whitespace control characters,
resulting in a couple strings from subscribe_to_more_streams.hbs not
being processed.
2023-09-08 09:09:46 -07:00
Zixuan James Li 7d683018bd webhooks: Migrate travis to use @typed_endpoint.
To perform the same check, we define a Pydantic model. This includes
some keys "build_url" and "type" that we did not check for previously.
2023-09-08 08:20:17 -07:00
Zixuan James Li 4037196fb2 webhooks: Migrate librato to use @typed_endpoint.
The Librato webhook requires a mapping (which should be considered
immutable) with a default value. Ruff reports a false-positive due to
the Json wrapper.
2023-09-08 08:20:17 -07:00
Zixuan James Li a33607d8ad webhooks: Convert gitlab to use @typed_endpoint.
The GitLab webhook has a mix of different types of parameters each
requring a unique set of configurations.
2023-09-08 08:20:17 -07:00
Zixuan James Li b163f2fe4e webhooks: Convert non-body payload webhooks to use @typed_endpoint.
These webhooks do not use argument_type_is_body, so they are parsing the
payload from a query parameter directly into WildValue.
2023-09-08 08:20:17 -07:00
Zixuan James Li 318a9316a7 webhooks: Migrate webhooks with special payload types to use @typed_endpoint.
Instead of a WildValue, the JSON/Sentry webhook expect the request body to be a
dict.

For the JSON webhook, json.dumps accepts other types of input as well and the
constraint is not necessary, but this serve as a good example of an alternative
use of WebhookPayload to describe a payload that is intended to be parsed from
the entire request body from JSON, into a type other than WildValue.
2023-09-08 08:20:17 -07:00
Zixuan James Li ece6b98699 webhooks: Migrate helloworld to use WildValue to use @typed_endpoint.
We owe more documentation on the use of WildValue. A follow-up on
updating it with examples of WildValue and endpoint will be desirable.
2023-09-08 08:20:17 -07:00
Zixuan James Li 9fef12950a webhooks: Migrate transifex to use endpoint to use @typed_endpoint.
Transifex has parameters that need to be parsed from JSON and converted
to int. Note that we use Optional[Json[int]] instead of
Json[Optional[int]] to replicate the behavior of json_validator. This
caveat is explained in a new test called test_json_optional.
2023-09-08 08:20:17 -07:00
Zixuan James Li 1329284848 webhooks: Migrate webhooks with str parameters to use @typed_endpoint.
These webhooks have some URL query params that do not need additional
validation or parsing from JSON. So WebhookPaylaod is not applicable to
these webhooks.
2023-09-08 08:20:17 -07:00
Zixuan James Li 9377080f1f webhooks: Migrate most webhooks to use @typed_endpoint.
This converts most webhook integration views to use @typed_endpoint instead
of @has_request_variables, rewriting REQ parameters. For these
webhooks, it simply requires switching the decorator, rewriting the
type annotation of payload/message to WebhookPayload[WildValue], and
removing the REQ default that defines the to_wild_value converter.
2023-09-08 08:20:17 -07:00
Zixuan James Li 574740dda4 webhooks: Migrate check_send_webhook_message to use @typed_endpoint.
This function is used by almost all webhooks.

To support it, we use the "api_ignore_parameter" flag so that positional
arguments like topic and body that are not intended to be parsed from
the request can be ignored.
2023-09-08 08:20:17 -07:00
Zixuan James Li 910f69465c drafts: Migrate drafts to use @typed_endpoint.
This demonstrates the use of BaseModel to replace a check_dict_only
validator.

We also add support to referring to $defs in the OpenAPI tests. In the
future, we can descend down each object instead of mapping them to dict
for more accurate checks.
2023-09-08 08:20:17 -07:00
Zixuan James Li 4701f290f7 presence: Migrate presence to use @typed_endpoint.
This demonstrates a use of StringConstraints.
2023-09-08 08:20:17 -07:00
Zixuan James Li 6201914fd3 message_edit: Migrate message_edit to use @typed_endpoint.
This demonstrates how an alias is created and its suitable use case, the
use of PathOnly, NonNegativeInt, and Literal.
2023-09-08 08:20:17 -07:00
Zixuan James Li 9c53995830 alert_words: Migrate alert_words to use @typed_endpoint.
This demonstrates some basic use cases of the Json[...] wrapper with
@typed_endpoint.

Along with this change we extend test_openapi so that schema checking
based on function signatures will still work with this new decorator.
Pydantic's TypeAdapter supports dumping the JSON schema of any given type,
which is leveraged here to validate against our own OpenAPI definitions.
Parts of the implementation will be covered in later commits as we
migrate more functions to use @typed_endpoint.

See also:
https://docs.pydantic.dev/latest/api/type_adapter/#pydantic.type_adapter.TypeAdapter.json_schema

For the OpenAPI schema, we preprocess it mostly the same way. For the
parameter types though, we no longer need to use
get_standardized_argument_type to normalize type annotation, because
Pydantic dumps a JSON schema that is compliant with OpenAPI schema
already, which makes it a lot convenient for us to compare the types
with our OpenAPI definitions.

Do note that there are some exceptions where our definitions do not match
the generated one. For example, we use JSON to parse int and bool parameters,
but we don't mark them to use "application/json" in our definitions.
2023-09-08 08:20:17 -07:00
Zixuan James Li c336bf0398 api: Avoid programming errors due to nested Annotated types.
We want to reject ambiguous type annotations that set ApiParamConfig
inside a Union. If a parameter is Optional and has a default of None, we
prefer Annotated[Optional[T], ...] over Optional[Annotated[T, ...]].

This implements a check that detects Optional[Annotated[T, ...]] and
raise an assertion error if ApiParamConfig is in the annotation. It also
checks if the type annotation contains any ApiParamConfig objects that
are ignored, which can happen if the Annotated type is nested inside
another type like List, Union, etc.

Note that because
param: Annotated[Optional[T], ...] = None
and
param: Optional[Annotated[Optional[T], ...]] = None
are equivalent in runtime prior to Python 3.11, there is no way for us
to distinguish the two. So we cannot detect that in runtime.
See also: https://github.com/python/cpython/issues/90353
2023-09-08 08:20:17 -07:00
Zixuan James Li 5a7b1065e5 api: Rewrite argument type test for clarity.
We refactor HostRequestMock so that it now proper populates the request
body given the post data, assuming that the request is JSON encoded.
2023-09-08 08:20:17 -07:00
Zixuan James Li f4caf9dd79 api: Add new typed_endpoint decorators.
The goal of typed_endpoint is to replicate most features supported by
has_request_variables, and to improve on top of it. There are some
unresolved issues that we don't plan to work on currently. For example,
typed_endpoint does not support ignored_parameters_supported for 400
responses, and it does not run validators on path-only arguments.

Unlike has_request_variables, typed_endpoint supports error handling by
processing validation errors from Pydantic.

Most features supported by has_request_variables are supported by
typed_endpoint in various ways.

To define a function, use a syntax like this with Annotated if there is
any metadata you want to associate with a parameter, do note that
parameters that are not keyword-only are ignored from the request:
```
@typed_endpoint
def view(
    request: HttpRequest,
    user_profile: UserProfile,
    *,
    foo: Annotated[int, ApiParamConfig(path_only=True)],
    bar: Json[int],
    other: Annotated[
        Json[int],
        ApiParamConfig(
            whence="lorem",
            documentation_status=NTENTIONALLY_UNDOCUMENTED
        )
    ] = 10,
) -> HttpResponse:
    ....
```

There are also some shorthands for the commonly used annotated types,
which are encouraged when applicable for better readability and less
typing:
```
WebhookPayload = Annotated[Json[T], ApiParamConfig(argument_type_is_body=True)]
PathOnly = Annotated[T, ApiParamConfig(path_only=True)]
```

Then the view function above can be rewritten as:
```
@typed_endpoint
def view(
    request: HttpRequest,
    user_profile: UserProfile,
    *,
    foo: PathOnly[int],
    bar: Json[int],
    other: Annotated[
        Json[int],
        ApiParamConfig(
            whence="lorem",
            documentation_status=INTENTIONALLY_UNDOCUMENTED
        )
    ] = 10,
) -> HttpResponse:
    ....
```

There are some intentional restrictions:
- A single parameter cannot have more than one ApiParamConfig
- Path-only parameters cannot have default values
- argument_type_is_body is incompatible with whence
- Arguments of name "request", "user_profile", "args", and "kwargs" and
  etc. are ignored by typed_endpoint.
- positional-only arguments are not supported by typed_endpoint. Only
  keyword-only parameters are expected to be parsed from the request.
- Pydantic's strict mode is always enabled, because we don't want to
  coerce input parsed from JSON into other types unnecessarily.
- Using strict mode all the time also means that we should always use
  Json[int] instead of int, because it is only possible for the request
  to have data of type str, and a type annotation of int will always
  reject such data.

typed_endpoint's handling of ignored_parameters_unsupported is mostly
identical to that of has_request_variables.
2023-09-08 08:20:17 -07:00
Zixuan James Li 7da4e73d57 requirements: Add pydantic and configure mypy plugin.
Along with pydantic we add annotated_types for Annotated utils that can
be used for more specific validation constraints.

Signed-off-by: Zixuan James Li <p359101898@gmail.com>
2023-09-08 08:20:17 -07:00
David Rosa 2174e0a7b7 help: Document "Add subscribers" mobile feature.
- Documents adding users via all streams, and stream settings/info.
2023-09-08 08:08:06 -07:00
David Rosa 5e2e53a350 help: Update "Add or remove users from a stream".
- Updates Desktop/web instructions to follow current help center
  documentation patterns.
- Adds instructions to subscribe users via stream settings.
2023-09-08 08:08:06 -07:00
evykassirer 49667cdbdb recent: Rename recent_topics test file. 2023-09-08 07:36:33 -07:00
evykassirer fc2ff74ea2 recent: Rename recent_topics in some test files. 2023-09-08 07:36:33 -07:00
evykassirer d3e561dbb1 recent: Rename some variables referencing recent_topics. 2023-09-08 07:36:33 -07:00
evykassirer 54acc3fccf recent: Rename recent_topics.css. 2023-09-08 07:36:33 -07:00
evykassirer a8ba40c04e recent: Rename narrow_to_recent_topics. 2023-09-08 07:36:33 -07:00
evykassirer 3179e6bb86 recent: Rename .top_left_recent_topics. 2023-09-08 07:36:33 -07:00
evykassirer 92163ad207 hotkey: Rename open_recent_topics. 2023-09-08 07:36:33 -07:00
evykassirer 37d6f319e3 recent: Rename coming_from_recent_topics. 2023-09-08 07:36:33 -07:00
evykassirer 08112356c8 recent: Rename maybe_hide_recent_topics. 2023-09-08 07:36:33 -07:00
evykassirer 0804704a76 recent: Rename update_buttons_for_recent_topics. 2023-09-08 07:36:33 -07:00
evykassirer ee2208ff9a recent: Rename .recent_topics_participant_avatar. 2023-09-08 07:36:33 -07:00
evykassirer d40030d4ae recent: Rename .recent_topics_participants. 2023-09-08 07:36:33 -07:00
evykassirer 8896cb28cb recent: Rename .recent_topics_participant_item. 2023-09-08 07:36:33 -07:00
evykassirer 29b796db7a recent: Rename .recent_topics_focusable. 2023-09-08 07:36:33 -07:00
evykassirer 6d67723fbe recent: Rename .recent_topics_participant_overflow. 2023-09-08 07:36:33 -07:00
evykassirer 77fcedfb50 recent: Rename #recent_topics_search. 2023-09-08 07:36:33 -07:00
evykassirer e5cd59c224 recent: Rename #recent_topics_filter_buttons. 2023-09-08 07:36:33 -07:00
evykassirer f7b96b2bee recent: Rename #recent_topics_loading_messages_indicator. 2023-09-08 07:36:33 -07:00
evykassirer 11591f7169 recent: Rename #recent_topics_bottom_whitespace. 2023-09-08 07:36:33 -07:00
evykassirer f4954d3183 recent: Rename .recent_topics_container. 2023-09-08 07:36:33 -07:00
evykassirer 0e6cbf14ea recent: Rename #recent_topics_view. 2023-09-08 07:36:33 -07:00
evykassirer 131127aa30 recent: Rename #recent_topics_table. 2023-09-08 07:36:33 -07:00