mirror of
https://github.com/element-hq/synapse.git
synced 2026-05-14 21:15:12 +00:00
95e146a0a0
Prepare for porting the event class into Rust, where the constructor strictly validates that all format-required fields (depth, hashes, origin_server_ts, auth_events, prev_events, ...) are present. Most tests build minimal dicts that omit these fields because they only care about the fields the test exercises. Introduce make_test_event and make_test_pdu_event, which layer format-version-aware defaults on top of caller-supplied fields so individual tests don't need to spell out every required key.
141 lines
5.1 KiB
Python
141 lines
5.1 KiB
Python
#
|
|
# This file is licensed under the Affero General Public License (AGPL) version 3.
|
|
#
|
|
# Copyright (C) 2026 Element Creations Ltd.
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU Affero General Public License as
|
|
# published by the Free Software Foundation, either version 3 of the
|
|
# License, or (at your option) any later version.
|
|
#
|
|
# See the GNU Affero General Public License for more details:
|
|
# <https://www.gnu.org/licenses/agpl-3.0.html>.
|
|
#
|
|
"""Test-only helpers for building events.
|
|
|
|
The Rust `Event` constructor strictly validates that all format-required
|
|
fields are present on the event dict. Most production code paths always
|
|
supply these, but tests routinely build minimal dicts that omit fields
|
|
like `depth`, `hashes`, `origin_server_ts`, `auth_events`, or
|
|
`prev_events`. This module provides `make_test_event`, which fills in
|
|
sensible defaults for the required fields based on the event format
|
|
version, so individual tests only need to specify the fields they
|
|
actually care about.
|
|
"""
|
|
|
|
from typing import Any
|
|
|
|
from synapse.api.room_versions import (
|
|
EventFormatVersions,
|
|
RoomVersion,
|
|
RoomVersions,
|
|
)
|
|
from synapse.events import EventBase, make_event_from_dict
|
|
from synapse.federation.federation_base import event_from_pdu_json
|
|
from synapse.types import JsonDict
|
|
|
|
|
|
def default_event_fields(room_version: RoomVersion) -> JsonDict:
|
|
"""Return the default values for every field required by `room_version`.
|
|
|
|
Tests can call this directly when they need to merge defaults into a
|
|
builder (e.g. inside another helper) rather than constructing the
|
|
event up-front.
|
|
"""
|
|
defaults: JsonDict = {
|
|
"type": "m.test",
|
|
"sender": "@test:test",
|
|
"content": {},
|
|
"depth": 1,
|
|
"origin_server_ts": 1,
|
|
"hashes": {"sha256": ""},
|
|
}
|
|
|
|
if room_version.event_format == EventFormatVersions.ROOM_V1_V2:
|
|
# V1 events store auth/prev as `[(event_id, hashes)]` pairs and
|
|
# carry an explicit `event_id` and `room_id`.
|
|
defaults["auth_events"] = []
|
|
defaults["prev_events"] = []
|
|
defaults["room_id"] = "!test:test"
|
|
defaults["event_id"] = "$test:test"
|
|
elif room_version.event_format in (
|
|
EventFormatVersions.ROOM_V3,
|
|
EventFormatVersions.ROOM_V4_PLUS,
|
|
):
|
|
# V2/V3 and V4 share the flat auth/prev list shape. V2/V3 always
|
|
# carry a `room_id`; V4 makes it optional on create events but
|
|
# required otherwise, so callers building non-create events
|
|
# supply it explicitly.
|
|
defaults["auth_events"] = []
|
|
defaults["prev_events"] = []
|
|
defaults["room_id"] = "!test:test"
|
|
else:
|
|
# V11 Hydra+ and VMSC4242 derive the room_id from the create
|
|
# event's ID, so we never default it here — providing one would
|
|
# break auth-event derivation for create events on these
|
|
# versions. Callers supply room_id explicitly on non-create
|
|
# events.
|
|
defaults["auth_events"] = []
|
|
defaults["prev_events"] = []
|
|
|
|
if room_version.msc4242_state_dags:
|
|
defaults["prev_state_events"] = []
|
|
|
|
return defaults
|
|
|
|
|
|
def make_test_event(
|
|
event_dict: JsonDict | None = None,
|
|
room_version: RoomVersion = RoomVersions.V1,
|
|
internal_metadata_dict: JsonDict | None = None,
|
|
rejected_reason: str | None = None,
|
|
**fields: Any,
|
|
) -> EventBase:
|
|
"""Build an `EventBase` with defaults for the strict-required fields.
|
|
|
|
Pass an `event_dict` and/or `**fields` keyword arguments — both are
|
|
merged on top of the format-version defaults from
|
|
`default_event_fields`. Explicit values win over defaults, and
|
|
`**fields` wins over `event_dict` so call sites can override a
|
|
shared base dict with one-off tweaks.
|
|
|
|
Args:
|
|
event_dict: Explicit event fields. Wins over defaults; loses to
|
|
`**fields`.
|
|
room_version: Determines which format-specific defaults apply.
|
|
internal_metadata_dict: Forwarded to `make_event_from_dict`.
|
|
rejected_reason: Forwarded to `make_event_from_dict`.
|
|
**fields: Additional event fields. Wins over `event_dict`.
|
|
|
|
Returns:
|
|
The constructed `EventBase`.
|
|
"""
|
|
merged: JsonDict = {
|
|
**default_event_fields(room_version),
|
|
**(event_dict or {}),
|
|
**fields,
|
|
}
|
|
return make_event_from_dict(
|
|
merged,
|
|
room_version=room_version,
|
|
internal_metadata_dict=internal_metadata_dict,
|
|
rejected_reason=rejected_reason,
|
|
)
|
|
|
|
|
|
def make_test_pdu_event(
|
|
pdu: JsonDict,
|
|
room_version: RoomVersion,
|
|
received_time: int | None = None,
|
|
) -> EventBase:
|
|
"""Wrapper around `event_from_pdu_json` for test PDU dicts.
|
|
|
|
Federation-side test fixtures often omit fields the strict Rust ctor
|
|
requires (e.g. `hashes`, `auth_events`, `prev_events`, `depth`)
|
|
because those tests focus on transport/auth flow rather than event
|
|
well-formedness. This helper layers in the same format-version
|
|
defaults as `make_test_event` before delegating.
|
|
"""
|
|
pdu = {**default_event_fields(room_version), **pdu}
|
|
return event_from_pdu_json(pdu, room_version, received_time=received_time)
|