slidge 0.3.0b3__tar.gz → 0.3.0b4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {slidge-0.3.0b3 → slidge-0.3.0b4}/.woodpecker/container-ci.yaml +1 -1
- {slidge-0.3.0b3 → slidge-0.3.0b4}/PKG-INFO +1 -1
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/gateway.py +7 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/mixins/base.py +2 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/mixins/message_text.py +29 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/mixins/presence.py +3 -2
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/group/archive.py +4 -1
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/group/bookmarks.py +1 -1
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/group/participant.py +15 -2
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/group/room.py +8 -4
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/migration.py +0 -11
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/util/util.py +7 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge.egg-info/PKG-INFO +1 -1
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge.egg-info/SOURCES.txt +2 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/tests/test_avatar.py +2 -1
- slidge-0.3.0b4/tests/test_empty_subject.py +139 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/tests/test_session_2.py +87 -1
- slidge-0.3.0b4/tests/test_type_conversion.py +119 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/.gitignore +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/.pre-commit-config.yaml +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/.woodpecker/docs.yaml +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/.woodpecker/package.yaml +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/.woodpecker/test.yaml +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/Dockerfile +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/LICENSE +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/README.md +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/commitlint.config.js +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/dev/assets/5x5.png +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/dev/assets/slidge-color-small.png +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/dev/assets/slidge-color.png +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/dev/assets/slidge-mono-black.png +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/dev/assets/slidge-mono-white.png +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/dev/assets/slidge.svg +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/dev/confs/movim.env +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/dev/confs/nginx.conf +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/dev/confs/slidge-dev.ini +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/dev/confs/slidge-example.ini +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/dev/hot-reload.sh +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/dev/prettify_tests.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/doap.xml +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docker-compose.yml +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/Makefile +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/admin/attachments.rst +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/admin/component.rst +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/admin/config/index.rst +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/admin/daemon.rst +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/admin/examples/ejabberd.yaml +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/admin/examples/index.rst +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/admin/examples/prosody.cfg.lua +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/admin/index.rst +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/admin/install.rst +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/admin/note.rst +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/admin/privilege.rst +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/codeberg.svg +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/conf.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/dev/contributing.rst +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/dev/design.rst +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/dev/howto.rst +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/dev/index.rst +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/dev/tutorial.rst +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/glossary.rst +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/index.rst +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/user/commands.rst +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/user/contacts.rst +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/user/foxyproxy.png +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/user/gajim.png +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/user/index.rst +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/user/low_profile.rst +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/user/movim1.png +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/user/movim2.png +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/user/note.rst +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/docs/source/user/register.rst +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/pyproject.toml +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/setup.cfg +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/__init__.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/__main__.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/command/__init__.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/command/adhoc.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/command/admin.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/command/base.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/command/categories.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/command/chat_command.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/command/register.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/command/user.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/contact/__init__.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/contact/contact.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/contact/roster.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/__init__.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/config.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/dispatcher/__init__.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/dispatcher/caps.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/dispatcher/disco.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/dispatcher/message/__init__.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/dispatcher/message/chat_state.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/dispatcher/message/marker.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/dispatcher/message/message.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/dispatcher/muc/__init__.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/dispatcher/muc/admin.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/dispatcher/muc/mam.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/dispatcher/muc/misc.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/dispatcher/muc/owner.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/dispatcher/muc/ping.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/dispatcher/presence.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/dispatcher/registration.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/dispatcher/search.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/dispatcher/session_dispatcher.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/dispatcher/util.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/dispatcher/vcard.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/mixins/__init__.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/mixins/attachment.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/mixins/avatar.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/mixins/db.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/mixins/disco.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/mixins/message.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/mixins/message_maker.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/mixins/recipient.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/pubsub.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/core/session.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/db/__init__.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/db/alembic/__init__.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/db/alembic/env.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/db/alembic/script.py.mako +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/db/alembic/versions/cef02a8b1451_initial_schema.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/db/avatar.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/db/meta.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/db/models.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/db/store.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/group/__init__.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/main.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/py.typed +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/slixfix/__init__.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/slixfix/delivery_receipt.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/slixfix/link_preview/__init__.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/slixfix/link_preview/link_preview.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/slixfix/link_preview/stanza.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/slixfix/roster.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/slixfix/xep_0077/__init__.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/slixfix/xep_0077/register.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/slixfix/xep_0077/stanza.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/slixfix/xep_0100/__init__.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/slixfix/xep_0100/gateway.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/slixfix/xep_0100/stanza.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/slixfix/xep_0153/__init__.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/slixfix/xep_0153/vcard_avatar.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/slixfix/xep_0292/__init__.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/slixfix/xep_0292/vcard4.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/util/__init__.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/util/archive_msg.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/util/conf.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/util/jid_escaping.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/util/lock.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/util/test.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge/util/types.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge.egg-info/dependency_links.txt +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge.egg-info/entry_points.txt +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge.egg-info/requires.txt +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/slidge.egg-info/top_level.txt +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/superduper/__init__.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/superduper/__main__.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/superduper/contact.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/superduper/gateway.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/superduper/group.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/superduper/legacy_client.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/superduper/session.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/superduper/util.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/tests/conftest.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/tests/test_adhoc/test_access.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/tests/test_adhoc/test_confirmation.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/tests/test_adhoc/test_form.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/tests/test_adhoc/test_reported.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/tests/test_attachment.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/tests/test_backfill.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/tests/test_chat_commands.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/tests/test_config.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/tests/test_db/test_store.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/tests/test_db/test_user.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/tests/test_feature_restriction.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/tests/test_mam_archivable.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/tests/test_mds.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/tests/test_muc.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/tests/test_resourceprep.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/tests/test_session.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/tests/test_set_name_before_fill.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/tests/test_shakespeare.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/tests/test_stanza_link_preview.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/tests/test_util.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/tests/test_vcard.py +0 -0
- {slidge-0.3.0b3 → slidge-0.3.0b4}/uv.lock +0 -0
@@ -172,6 +172,13 @@ class BaseGateway(
|
|
172
172
|
required=True,
|
173
173
|
type="boolean",
|
174
174
|
),
|
175
|
+
FormField(
|
176
|
+
var="reaction_fallback",
|
177
|
+
label="Receive fallback messages for reactions (for legacy XMPP clients)",
|
178
|
+
value="false",
|
179
|
+
required=True,
|
180
|
+
type="boolean",
|
181
|
+
),
|
175
182
|
]
|
176
183
|
|
177
184
|
ROSTER_GROUP: str = "slidge"
|
@@ -2,6 +2,9 @@ import logging
|
|
2
2
|
from datetime import datetime
|
3
3
|
from typing import Iterable, Optional
|
4
4
|
|
5
|
+
from slixmpp import Message
|
6
|
+
|
7
|
+
from ...util.archive_msg import HistoryMessage
|
5
8
|
from ...util.types import (
|
6
9
|
LegacyMessageType,
|
7
10
|
LegacyThreadType,
|
@@ -9,6 +12,7 @@ from ...util.types import (
|
|
9
12
|
MessageReference,
|
10
13
|
ProcessingHint,
|
11
14
|
)
|
15
|
+
from ...util.util import add_quote_prefix
|
12
16
|
from .message_maker import MessageMaker
|
13
17
|
|
14
18
|
|
@@ -188,8 +192,33 @@ class TextMessageMixin(MessageMaker):
|
|
188
192
|
if not xmpp_id:
|
189
193
|
xmpp_id = self._legacy_to_xmpp(legacy_msg_id)
|
190
194
|
self.xmpp["xep_0444"].set_reactions(msg, to_id=xmpp_id, reactions=emojis)
|
195
|
+
self.__add_reaction_fallback(msg, legacy_msg_id, emojis)
|
191
196
|
self._send(msg, **kwargs)
|
192
197
|
|
198
|
+
def __add_reaction_fallback(
|
199
|
+
self,
|
200
|
+
msg: Message,
|
201
|
+
legacy_msg_id: LegacyMessageType,
|
202
|
+
emojis: Iterable[str] = (),
|
203
|
+
) -> None:
|
204
|
+
if not self.session.user.preferences.get("reaction_fallback", False):
|
205
|
+
return
|
206
|
+
msg["fallback"]["for"] = self.xmpp.plugin["xep_0444"].namespace
|
207
|
+
msg["fallback"].enable("body")
|
208
|
+
msg["body"] = " ".join(emojis)
|
209
|
+
if not self.is_participant:
|
210
|
+
return
|
211
|
+
with self.xmpp.store.session() as orm:
|
212
|
+
archived = self.xmpp.store.mam.get_by_legacy_id(
|
213
|
+
orm, self.muc.stored.id, str(legacy_msg_id)
|
214
|
+
)
|
215
|
+
if archived is None:
|
216
|
+
return
|
217
|
+
history_msg = HistoryMessage(archived.stanza)
|
218
|
+
msg["body"] = (
|
219
|
+
add_quote_prefix(history_msg.stanza["body"]) + "\n" + msg["body"]
|
220
|
+
)
|
221
|
+
|
193
222
|
def retract(
|
194
223
|
self,
|
195
224
|
legacy_msg_id: LegacyMessageType,
|
@@ -62,8 +62,9 @@ class PresenceMixin(BaseSender, DBMixin):
|
|
62
62
|
try:
|
63
63
|
return self.stored.contact
|
64
64
|
except DetachedInstanceError:
|
65
|
-
self.
|
66
|
-
|
65
|
+
with self.xmpp.store.session() as orm:
|
66
|
+
orm.add(self.stored)
|
67
|
+
return self.stored.contact
|
67
68
|
|
68
69
|
@property
|
69
70
|
def __contact_pk(self) -> int | None:
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import logging
|
2
2
|
import uuid
|
3
|
+
import warnings
|
3
4
|
from copy import copy
|
4
5
|
from datetime import datetime, timezone
|
5
6
|
from typing import TYPE_CHECKING, Collection, Optional
|
@@ -48,7 +49,9 @@ class MessageArchive:
|
|
48
49
|
elif participant.is_system:
|
49
50
|
new_msg["muc"]["jid"] = participant.muc.jid
|
50
51
|
else:
|
51
|
-
|
52
|
+
warnings.warn(
|
53
|
+
f"No real JID for participant '{participant.nickname}' in '{self.room.name}'"
|
54
|
+
)
|
52
55
|
new_msg["muc"]["jid"] = (
|
53
56
|
f"{uuid.uuid4()}@{participant.xmpp.boundjid.bare}"
|
54
57
|
)
|
@@ -6,8 +6,8 @@ from copy import copy
|
|
6
6
|
from datetime import datetime
|
7
7
|
from functools import cached_property
|
8
8
|
from typing import TYPE_CHECKING, Any, Optional, Union
|
9
|
+
from xml.etree import ElementTree as ET
|
9
10
|
|
10
|
-
import sqlalchemy as sa
|
11
11
|
from slixmpp import JID, InvalidJID, Message, Presence
|
12
12
|
from slixmpp.plugins.xep_0045.stanza import MUCAdminItem
|
13
13
|
from slixmpp.types import MessageTypes, OptJid
|
@@ -51,6 +51,8 @@ class LegacyParticipant(
|
|
51
51
|
A legacy participant of a legacy group chat.
|
52
52
|
"""
|
53
53
|
|
54
|
+
is_participant = True
|
55
|
+
|
54
56
|
mtype: MessageTypes = "groupchat"
|
55
57
|
_can_send_carbon = False
|
56
58
|
USE_STANZA_ID = True
|
@@ -93,6 +95,13 @@ class LegacyParticipant(
|
|
93
95
|
self.merge()
|
94
96
|
return self.stored.is_user
|
95
97
|
|
98
|
+
@is_user.setter
|
99
|
+
def is_user(self, is_user: bool) -> None:
|
100
|
+
with self.xmpp.store.session(expire_on_commit=True) as orm:
|
101
|
+
orm.add(self.stored)
|
102
|
+
self.stored.is_user = is_user
|
103
|
+
orm.commit()
|
104
|
+
|
96
105
|
@property
|
97
106
|
def jid(self) -> JID:
|
98
107
|
jid = JID(self.muc.jid)
|
@@ -510,7 +519,11 @@ class LegacyParticipant(
|
|
510
519
|
if when is not None:
|
511
520
|
msg["delay"].set_stamp(when)
|
512
521
|
msg["delay"]["from"] = self.muc.jid
|
513
|
-
|
522
|
+
if subject:
|
523
|
+
msg["subject"] = subject
|
524
|
+
else:
|
525
|
+
# may be simplified if slixmpp lets it do it more easily some day
|
526
|
+
msg.xml.append(ET.Element(f"{{{msg.namespace}}}subject"))
|
514
527
|
self._send(msg, full_jid)
|
515
528
|
|
516
529
|
|
@@ -431,8 +431,8 @@ class LegacyMUC(
|
|
431
431
|
yield
|
432
432
|
|
433
433
|
@property
|
434
|
-
def subject(self):
|
435
|
-
return self.stored.subject
|
434
|
+
def subject(self) -> str:
|
435
|
+
return self.stored.subject or ""
|
436
436
|
|
437
437
|
@subject.setter
|
438
438
|
def subject(self, s: str) -> None:
|
@@ -652,7 +652,7 @@ class LegacyMUC(
|
|
652
652
|
orm.refresh(self.stored, ["participants"])
|
653
653
|
if not user_participant.is_user:
|
654
654
|
self.log.warning("is_user flag not set participant on user_participant")
|
655
|
-
user_participant.is_user = True
|
655
|
+
user_participant.is_user = True
|
656
656
|
user_participant.send_initial_presence(
|
657
657
|
user_full_jid,
|
658
658
|
presence_id=join_presence["id"],
|
@@ -680,8 +680,12 @@ class LegacyMUC(
|
|
680
680
|
maxstanzas=maxstanzas,
|
681
681
|
since=since,
|
682
682
|
)
|
683
|
+
if self.HAS_SUBJECT:
|
684
|
+
subject = self.subject or ""
|
685
|
+
else:
|
686
|
+
subject = self.description or self.name or ""
|
683
687
|
self.__get_subject_setter_participant().set_room_subject(
|
684
|
-
|
688
|
+
subject,
|
685
689
|
user_full_jid,
|
686
690
|
self.subject_date,
|
687
691
|
)
|
@@ -1,5 +1,4 @@
|
|
1
1
|
import logging
|
2
|
-
import shutil
|
3
2
|
import sys
|
4
3
|
import traceback
|
5
4
|
from pathlib import Path
|
@@ -7,15 +6,6 @@ from pathlib import Path
|
|
7
6
|
from alembic import command
|
8
7
|
from alembic.config import Config
|
9
8
|
|
10
|
-
from .core import config
|
11
|
-
|
12
|
-
|
13
|
-
def remove_avatar_cache_v1() -> None:
|
14
|
-
old_dir = config.HOME_DIR / "slidge_avatars"
|
15
|
-
if old_dir.exists():
|
16
|
-
log.info("Avatar cache dir v1 found, clearing it.")
|
17
|
-
shutil.rmtree(old_dir)
|
18
|
-
|
19
9
|
|
20
10
|
def get_alembic_cfg() -> Config:
|
21
11
|
alembic_cfg = Config()
|
@@ -28,7 +18,6 @@ def get_alembic_cfg() -> Config:
|
|
28
18
|
|
29
19
|
|
30
20
|
def migrate() -> None:
|
31
|
-
remove_avatar_cache_v1()
|
32
21
|
try:
|
33
22
|
command.upgrade(get_alembic_cfg(), "head")
|
34
23
|
except Exception as e:
|
@@ -324,3 +324,10 @@ def strip_leading_emoji(text: str) -> str:
|
|
324
324
|
|
325
325
|
async def noop_coro() -> None:
|
326
326
|
pass
|
327
|
+
|
328
|
+
|
329
|
+
def add_quote_prefix(text: str):
|
330
|
+
"""
|
331
|
+
Return multi-line text with leading quote marks (i.e. the ">" character).
|
332
|
+
"""
|
333
|
+
return "\n".join(("> " + x).strip() for x in text.split("\n")).strip()
|
@@ -164,6 +164,7 @@ tests/test_avatar.py
|
|
164
164
|
tests/test_backfill.py
|
165
165
|
tests/test_chat_commands.py
|
166
166
|
tests/test_config.py
|
167
|
+
tests/test_empty_subject.py
|
167
168
|
tests/test_feature_restriction.py
|
168
169
|
tests/test_mam_archivable.py
|
169
170
|
tests/test_mds.py
|
@@ -174,6 +175,7 @@ tests/test_session_2.py
|
|
174
175
|
tests/test_set_name_before_fill.py
|
175
176
|
tests/test_shakespeare.py
|
176
177
|
tests/test_stanza_link_preview.py
|
178
|
+
tests/test_type_conversion.py
|
177
179
|
tests/test_util.py
|
178
180
|
tests/test_vcard.py
|
179
181
|
tests/test_adhoc/test_access.py
|
@@ -255,7 +255,8 @@ class BaseMUC(BaseNoMUC):
|
|
255
255
|
</presence>
|
256
256
|
"""
|
257
257
|
)
|
258
|
-
|
258
|
+
subject_msg = self.next_sent()
|
259
|
+
assert subject_msg.xml.find(f"{{{subject_msg.namespace}}}subject") is not None
|
259
260
|
# assert self.next_sent()["from"] == "room@aim.shakespeare.lit"
|
260
261
|
|
261
262
|
def get_muc(self, joined=True) -> MUC:
|
@@ -0,0 +1,139 @@
|
|
1
|
+
import unittest
|
2
|
+
|
3
|
+
import pytest
|
4
|
+
from slixmpp.exceptions import XMPPError
|
5
|
+
|
6
|
+
from conftest import AvatarFixtureMixin
|
7
|
+
from slixmpp import JID, Iq
|
8
|
+
|
9
|
+
from slidge import BaseGateway, BaseSession, GatewayUser, LegacyRoster, LegacyBookmarks, LegacyMUC, LegacyContact
|
10
|
+
from slidge.core.session import _sessions
|
11
|
+
from slidge.util.test import SlidgeTest
|
12
|
+
from slidge.util.types import LegacyUserIdType, LegacyMUCType, MucType
|
13
|
+
|
14
|
+
|
15
|
+
class Gateway(BaseGateway):
|
16
|
+
COMPONENT_NAME = "A test"
|
17
|
+
GROUPS = True
|
18
|
+
|
19
|
+
|
20
|
+
class Contact(LegacyContact):
|
21
|
+
async def update_info(self):
|
22
|
+
if self.legacy_id.startswith("group"):
|
23
|
+
raise XMPPError()
|
24
|
+
|
25
|
+
|
26
|
+
class Session(BaseSession):
|
27
|
+
async def login(self):
|
28
|
+
return "YUP"
|
29
|
+
|
30
|
+
|
31
|
+
class Bookmarks(LegacyBookmarks):
|
32
|
+
async def fill(self) -> None:
|
33
|
+
pass
|
34
|
+
|
35
|
+
|
36
|
+
class MUC(LegacyMUC):
|
37
|
+
async def update_info(self):
|
38
|
+
if not self.legacy_id.startswith("group"):
|
39
|
+
raise XMPPError()
|
40
|
+
self.type = MucType.GROUP
|
41
|
+
|
42
|
+
@pytest.mark.usefixtures("avatar")
|
43
|
+
class TestEmptySubject(AvatarFixtureMixin, SlidgeTest):
|
44
|
+
plugin = globals()
|
45
|
+
xmpp: Gateway
|
46
|
+
|
47
|
+
def setUp(self):
|
48
|
+
super().setUp()
|
49
|
+
with self.xmpp.store.session() as orm:
|
50
|
+
user = GatewayUser(
|
51
|
+
jid=JID("romeo@montague.lit/gajim").bare,
|
52
|
+
legacy_module_data={"username": "romeo", "city": ""},
|
53
|
+
preferences={"sync_avatar": True, "sync_presence": True},
|
54
|
+
)
|
55
|
+
orm.add(user)
|
56
|
+
orm.commit()
|
57
|
+
self.run_coro(
|
58
|
+
self.xmpp._BaseGateway__dispatcher._on_user_register(
|
59
|
+
Iq(sfrom="romeo@montague.lit/gajim")
|
60
|
+
)
|
61
|
+
)
|
62
|
+
welcome = self.next_sent()
|
63
|
+
assert welcome["body"]
|
64
|
+
stanza = self.next_sent()
|
65
|
+
assert "logging in" in stanza["status"].lower(), stanza
|
66
|
+
stanza = self.next_sent()
|
67
|
+
assert "syncing contacts" in stanza["status"].lower(), stanza
|
68
|
+
stanza = self.next_sent()
|
69
|
+
assert "syncing groups" in stanza["status"].lower(), stanza
|
70
|
+
probe = self.next_sent()
|
71
|
+
assert probe.get_type() == "probe"
|
72
|
+
stanza = self.next_sent()
|
73
|
+
assert "yup" in stanza["status"].lower(), stanza
|
74
|
+
|
75
|
+
self.send( # language=XML
|
76
|
+
"""
|
77
|
+
<iq type="get"
|
78
|
+
to="romeo@montague.lit"
|
79
|
+
id="1"
|
80
|
+
from="aim.shakespeare.lit">
|
81
|
+
<pubsub xmlns="http://jabber.org/protocol/pubsub">
|
82
|
+
<items node="urn:xmpp:avatar:metadata" />
|
83
|
+
</pubsub>
|
84
|
+
</iq>
|
85
|
+
"""
|
86
|
+
)
|
87
|
+
|
88
|
+
def tearDown(self):
|
89
|
+
super().tearDown()
|
90
|
+
_sessions.clear()
|
91
|
+
|
92
|
+
@property
|
93
|
+
def romeo_session(self) -> Session:
|
94
|
+
return BaseSession.get_self_or_unique_subclass().from_jid(
|
95
|
+
JID("romeo@montague.lit")
|
96
|
+
)
|
97
|
+
|
98
|
+
def test_empty_subject(self):
|
99
|
+
muc = self.run_coro(self.romeo_session.bookmarks.by_legacy_id("group"))
|
100
|
+
with unittest.mock.patch("slidge.core.mixins.message_maker.uuid4", return_value="uuid"), unittest.mock.patch("uuid.uuid4", return_value="uuid"):
|
101
|
+
self.recv( # language=XML
|
102
|
+
f"""
|
103
|
+
<presence from="romeo@montague.lit/movim"
|
104
|
+
to="{muc.jid}/nick">
|
105
|
+
<x xmlns='http://jabber.org/protocol/muc' />
|
106
|
+
</presence>
|
107
|
+
""" )
|
108
|
+
self.send( # language=XML
|
109
|
+
"""
|
110
|
+
<presence from="group@aim.shakespeare.lit/romeo"
|
111
|
+
to="romeo@montague.lit/movim">
|
112
|
+
<x xmlns="http://jabber.org/protocol/muc#user">
|
113
|
+
<item affiliation="member"
|
114
|
+
role="participant"
|
115
|
+
jid="romeo@montague.lit/movim" />
|
116
|
+
<status code="210" />
|
117
|
+
<status code="110" />
|
118
|
+
<status code="100" />
|
119
|
+
</x>
|
120
|
+
<occupant-id xmlns="urn:xmpp:occupant-id:0"
|
121
|
+
id="slidge-user" />
|
122
|
+
</presence>
|
123
|
+
""",
|
124
|
+
use_values=False)
|
125
|
+
self.send( # language=XML
|
126
|
+
"""
|
127
|
+
<message type="groupchat"
|
128
|
+
from="group@aim.shakespeare.lit"
|
129
|
+
to="romeo@montague.lit/movim">
|
130
|
+
<stanza-id xmlns="urn:xmpp:sid:0"
|
131
|
+
id="uuid"
|
132
|
+
by="group@aim.shakespeare.lit" />
|
133
|
+
<occupant-id xmlns="urn:xmpp:occupant-id:0"
|
134
|
+
id="room" />
|
135
|
+
<subject />
|
136
|
+
</message>
|
137
|
+
""",
|
138
|
+
use_values=False,
|
139
|
+
)
|
@@ -43,7 +43,7 @@ class Contact(LegacyContact):
|
|
43
43
|
|
44
44
|
class MUC(LegacyMUC):
|
45
45
|
async def update_info(self):
|
46
|
-
if self.legacy_id in ("room-noinfo", "room-duplicate-participant", "room-avatar-slow", "room-contact-conflict"):
|
46
|
+
if self.legacy_id in ("room-noinfo", "room-duplicate-participant", "room-avatar-slow", "room-contact-conflict", "room-reaction-fallback"):
|
47
47
|
return
|
48
48
|
if self.legacy_id == "room-avatar-in-slow-task":
|
49
49
|
self.session.create_task(self._slow_set_avatar(), "slow-avatar")
|
@@ -580,3 +580,89 @@ class TestSession2(AvatarFixtureMixin, SlidgeTest):
|
|
580
580
|
</iq>
|
581
581
|
""",
|
582
582
|
)
|
583
|
+
|
584
|
+
def test_reaction_fallback(self):
|
585
|
+
self.romeo_session.user.preferences["reaction_fallback"] = True
|
586
|
+
contact = self.run_coro(self.romeo_session.contacts.by_legacy_id("reacter"))
|
587
|
+
contact.react("msg-id", "♥")
|
588
|
+
self.send( # language=XML
|
589
|
+
"""
|
590
|
+
<message xmlns="jabber:component:accept"
|
591
|
+
type="chat"
|
592
|
+
from="reacter@aim.shakespeare.lit/slidge"
|
593
|
+
to="romeo@montague.lit">
|
594
|
+
<store xmlns="urn:xmpp:hints" />
|
595
|
+
<reactions xmlns="urn:xmpp:reactions:0"
|
596
|
+
id="msg-id">
|
597
|
+
<reaction>♥</reaction>
|
598
|
+
</reactions>
|
599
|
+
<fallback xmlns="urn:xmpp:fallback:0"
|
600
|
+
for="urn:xmpp:reactions:0">
|
601
|
+
<body />
|
602
|
+
</fallback>
|
603
|
+
<body>♥</body>
|
604
|
+
</message>
|
605
|
+
""",
|
606
|
+
use_values=False
|
607
|
+
)
|
608
|
+
|
609
|
+
def test_reaction_fallback_muc(self):
|
610
|
+
self.romeo_session.user.preferences["reaction_fallback"] = True
|
611
|
+
muc: LegacyMUC = self.run_coro(
|
612
|
+
self.romeo_session.bookmarks.by_legacy_id("room-reaction-fallback")
|
613
|
+
)
|
614
|
+
# yuuuuuuck, if we only call it once, then it does not have an archive PK
|
615
|
+
muc: LegacyMUC = self.run_coro(
|
616
|
+
self.romeo_session.bookmarks.by_legacy_id("room-reaction-fallback")
|
617
|
+
)
|
618
|
+
part = self.run_coro(muc.get_participant_by_legacy_id("participant-x"))
|
619
|
+
muc.add_user_resource("gajim")
|
620
|
+
part.send_text("some text\non lines", legacy_msg_id="msg-id")
|
621
|
+
presence = self.next_sent()
|
622
|
+
assert presence["from"] == "room-reaction-fallback@aim.shakespeare.lit/participant-x"
|
623
|
+
self.send( # language=XML
|
624
|
+
"""
|
625
|
+
<message xmlns="jabber:component:accept"
|
626
|
+
type="groupchat"
|
627
|
+
id="msg-id"
|
628
|
+
from="room-reaction-fallback@aim.shakespeare.lit/participant-x"
|
629
|
+
to="romeo@montague.lit/gajim">
|
630
|
+
<body>some text\non lines</body>
|
631
|
+
<active xmlns="http://jabber.org/protocol/chatstates" />
|
632
|
+
<markable xmlns="urn:xmpp:chat-markers:0" />
|
633
|
+
<stanza-id xmlns="urn:xmpp:sid:0"
|
634
|
+
id="msg-id"
|
635
|
+
by="room-reaction-fallback@aim.shakespeare.lit" />
|
636
|
+
<occupant-id xmlns="urn:xmpp:occupant-id:0"
|
637
|
+
id="participant-x@aim.shakespeare.lit/slidge" />
|
638
|
+
</message>
|
639
|
+
""",
|
640
|
+
use_values=False,
|
641
|
+
)
|
642
|
+
with unittest.mock.patch("slidge.core.mixins.message_maker.uuid4", return_value="uuid"):
|
643
|
+
part.react("msg-id", "♥")
|
644
|
+
self.send( # language=XML
|
645
|
+
"""
|
646
|
+
<message xmlns="jabber:component:accept"
|
647
|
+
type="groupchat"
|
648
|
+
from="room-reaction-fallback@aim.shakespeare.lit/participant-x"
|
649
|
+
to="romeo@montague.lit/gajim">
|
650
|
+
<store xmlns="urn:xmpp:hints" />
|
651
|
+
<stanza-id xmlns="urn:xmpp:sid:0"
|
652
|
+
id="uuid"
|
653
|
+
by="room-reaction-fallback@aim.shakespeare.lit" />
|
654
|
+
<reactions xmlns="urn:xmpp:reactions:0"
|
655
|
+
id="msg-id">
|
656
|
+
<reaction>♥</reaction>
|
657
|
+
</reactions>
|
658
|
+
<fallback xmlns="urn:xmpp:fallback:0"
|
659
|
+
for="urn:xmpp:reactions:0">
|
660
|
+
<body />
|
661
|
+
</fallback>
|
662
|
+
<body>> some text\n> on lines\n♥</body>
|
663
|
+
<occupant-id xmlns="urn:xmpp:occupant-id:0"
|
664
|
+
id="participant-x@aim.shakespeare.lit/slidge" />
|
665
|
+
</message>
|
666
|
+
""",
|
667
|
+
use_values=False,
|
668
|
+
)
|
@@ -0,0 +1,119 @@
|
|
1
|
+
import pytest
|
2
|
+
|
3
|
+
from conftest import AvatarFixtureMixin
|
4
|
+
from slixmpp import JID, Iq
|
5
|
+
|
6
|
+
from slidge import BaseGateway, BaseSession, GatewayUser, LegacyRoster, LegacyBookmarks
|
7
|
+
from slidge.core.session import _sessions
|
8
|
+
from slidge.util.test import SlidgeTest
|
9
|
+
from slidge.util.types import LegacyUserIdType
|
10
|
+
|
11
|
+
|
12
|
+
class SomeType:
|
13
|
+
def __init__(self, a: int, b: int):
|
14
|
+
self.a = a
|
15
|
+
self.b = b
|
16
|
+
|
17
|
+
@classmethod
|
18
|
+
def from_str(cls, s: str):
|
19
|
+
a, b = (int(x) for x in s.split("-"))
|
20
|
+
return SomeType(a, b)
|
21
|
+
|
22
|
+
def __str__(self):
|
23
|
+
return f"{self.a}-{self.b}"
|
24
|
+
|
25
|
+
class Gateway(BaseGateway):
|
26
|
+
COMPONENT_NAME = "A test"
|
27
|
+
LEGACY_CONTACT_ID_TYPE = SomeType.from_str
|
28
|
+
LEGACY_ROOM_ID_TYPE = SomeType.from_str
|
29
|
+
GROUPS = True
|
30
|
+
|
31
|
+
|
32
|
+
class Session(BaseSession):
|
33
|
+
async def login(self):
|
34
|
+
return "YUP"
|
35
|
+
|
36
|
+
|
37
|
+
class Roster(LegacyRoster):
|
38
|
+
async def legacy_id_to_jid_username(self, legacy_id: LegacyUserIdType) -> str:
|
39
|
+
return f"{legacy_id.a}-{legacy_id.b}"
|
40
|
+
|
41
|
+
async def jid_username_to_legacy_id(self, jid_username: str) -> LegacyUserIdType:
|
42
|
+
return SomeType.from_str(jid_username)
|
43
|
+
|
44
|
+
|
45
|
+
class Bookmarks(LegacyBookmarks):
|
46
|
+
async def legacy_id_to_jid_username(self, legacy_id: LegacyUserIdType) -> str:
|
47
|
+
return f"{legacy_id.a}-{legacy_id.b}"
|
48
|
+
|
49
|
+
async def jid_username_to_legacy_id(self, jid_username: str) -> LegacyUserIdType:
|
50
|
+
return SomeType.from_str(jid_username)
|
51
|
+
|
52
|
+
async def fill(self):
|
53
|
+
pass
|
54
|
+
|
55
|
+
@pytest.mark.usefixtures("avatar")
|
56
|
+
class TestLegacyTypeConversion(AvatarFixtureMixin, SlidgeTest):
|
57
|
+
plugin = globals()
|
58
|
+
xmpp: Gateway
|
59
|
+
|
60
|
+
def setUp(self):
|
61
|
+
super().setUp()
|
62
|
+
with self.xmpp.store.session() as orm:
|
63
|
+
user = GatewayUser(
|
64
|
+
jid=JID("romeo@montague.lit/gajim").bare,
|
65
|
+
legacy_module_data={"username": "romeo", "city": ""},
|
66
|
+
preferences={"sync_avatar": True, "sync_presence": True},
|
67
|
+
)
|
68
|
+
orm.add(user)
|
69
|
+
orm.commit()
|
70
|
+
self.run_coro(
|
71
|
+
self.xmpp._BaseGateway__dispatcher._on_user_register(
|
72
|
+
Iq(sfrom="romeo@montague.lit/gajim")
|
73
|
+
)
|
74
|
+
)
|
75
|
+
welcome = self.next_sent()
|
76
|
+
assert welcome["body"]
|
77
|
+
stanza = self.next_sent()
|
78
|
+
assert "logging in" in stanza["status"].lower(), stanza
|
79
|
+
stanza = self.next_sent()
|
80
|
+
assert "syncing contacts" in stanza["status"].lower(), stanza
|
81
|
+
stanza = self.next_sent()
|
82
|
+
assert "syncing groups" in stanza["status"].lower(), stanza
|
83
|
+
probe = self.next_sent()
|
84
|
+
assert probe.get_type() == "probe"
|
85
|
+
stanza = self.next_sent()
|
86
|
+
assert "yup" in stanza["status"].lower(), stanza
|
87
|
+
|
88
|
+
self.send( # language=XML
|
89
|
+
"""
|
90
|
+
<iq type="get"
|
91
|
+
to="romeo@montague.lit"
|
92
|
+
id="1"
|
93
|
+
from="aim.shakespeare.lit">
|
94
|
+
<pubsub xmlns="http://jabber.org/protocol/pubsub">
|
95
|
+
<items node="urn:xmpp:avatar:metadata" />
|
96
|
+
</pubsub>
|
97
|
+
</iq>
|
98
|
+
"""
|
99
|
+
)
|
100
|
+
|
101
|
+
def tearDown(self):
|
102
|
+
super().tearDown()
|
103
|
+
_sessions.clear()
|
104
|
+
|
105
|
+
@property
|
106
|
+
def romeo_session(self) -> Session:
|
107
|
+
return BaseSession.get_self_or_unique_subclass().from_jid(
|
108
|
+
JID("romeo@montague.lit")
|
109
|
+
)
|
110
|
+
|
111
|
+
def test_contact(self):
|
112
|
+
contact = self.run_coro(self.romeo_session.contacts.by_legacy_id(SomeType(1, 2)))
|
113
|
+
assert contact.legacy_id.a == 1
|
114
|
+
assert contact.legacy_id.b == 2
|
115
|
+
|
116
|
+
def test_muc(self):
|
117
|
+
muc = self.run_coro(self.romeo_session.bookmarks.by_legacy_id(SomeType(1, 2)))
|
118
|
+
assert muc.legacy_id.a == 1
|
119
|
+
assert muc.legacy_id.b == 2
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|