comparison tests/unit/test_plugin_xep_0420.py @ 3911:8289ac1b34f4

plugin XEP-0384: Fully reworked to adjust to the reworked python-omemo: - support for both (modern) OMEMO under the `urn:xmpp:omemo:2` namespace and (legacy) OMEMO under the `eu.siacs.conversations.axolotl` namespace - maintains one identity across both versions of OMEMO - migrates data from the old plugin - includes more features for protocol stability - uses SCE for modern OMEMO - fully type-checked, linted and format-checked - added type hints to various pieces of backend code used by the plugin - added stubs for some Twisted APIs used by the plugin under stubs/ (use `export MYPYPATH=stubs/` before running mypy) - core (xmpp): enabled `send` trigger and made it an asyncPoint fix 375
author Syndace <me@syndace.dev>
date Tue, 23 Aug 2022 21:06:24 +0200
parents 00212260f659
children cecf45416403
comparison
equal deleted inserted replaced
3910:199598223f82 3911:8289ac1b34f4
14 # GNU Affero General Public License for more details. 14 # GNU Affero General Public License for more details.
15 15
16 # You should have received a copy of the GNU Affero General Public License 16 # You should have received a copy of the GNU Affero General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. 17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 18
19 # Type-check with `mypy --strict --disable-error-code no-untyped-call`
20 # Lint with `pylint`
21
22 from datetime import datetime, timezone 19 from datetime import datetime, timezone
23 from typing import Callable, Iterator, Optional, cast 20 from typing import Callable, cast
24 21
25 import pytest 22 import pytest
26 23
27 from sat.plugins.plugin_xep_0334 import NS_HINTS 24 from sat.plugins.plugin_xep_0334 import NS_HINTS
28 from sat.plugins.plugin_xep_0420 import ( 25 from sat.plugins.plugin_xep_0420 import (
75 <xs:attribute name="sender" type="xs:string"/> 72 <xs:attribute name="sender" type="xs:string"/>
76 </xs:complexType> 73 </xs:complexType>
77 </xs:element>""" 74 </xs:element>"""
78 75
79 def create(self, stanza: domish.Element) -> domish.Element: 76 def create(self, stanza: domish.Element) -> domish.Element:
80 recipient = cast(Optional[str], stanza.getAttribute("to", None)) 77 recipient = stanza.getAttribute("to", None)
81 sender = cast(Optional[str], stanza.getAttribute("from", None)) 78 sender = stanza.getAttribute("from", None)
82 79
83 if recipient is None or sender is None: 80 if recipient is None or sender is None:
84 raise ValueError( 81 raise ValueError(
85 "Stanza doesn't have ``to`` and ``from`` attributes required by the" 82 "Stanza doesn't have ``to`` and ``from`` attributes required by the"
86 " full-jids custom affix." 83 " full-jids custom affix."
485 ) 482 )
486 ) 483 )
487 484
488 envelope_serialized = XEP_0420.pack_stanza(profile, stanza) 485 envelope_serialized = XEP_0420.pack_stanza(profile, stanza)
489 envelope = string_to_domish(envelope_serialized.decode("utf-8")) 486 envelope = string_to_domish(envelope_serialized.decode("utf-8"))
490 content = next(cast(Iterator[domish.Element], envelope.elements(NS_SCE, "content"))) 487 content = next(envelope.elements(NS_SCE, "content"))
491 488
492 # The body should have been assigned ``jabber:client`` as its namespace 489 # The body should have been assigned ``jabber:client`` as its namespace
493 assert next( 490 assert next(content.elements("jabber:client", "body"), None) is not None
494 cast(Iterator[domish.Element], content.elements("jabber:client", "body")),
495 None
496 ) is not None
497 491
498 XEP_0420.unpack_stanza(profile, stanza, envelope_serialized) 492 XEP_0420.unpack_stanza(profile, stanza, envelope_serialized)
499 493
500 # The body should still have ``jabber:client`` after unpacking 494 # The body should still have ``jabber:client`` after unpacking
501 assert next( 495 assert next(stanza.elements("jabber:client", "body"), None) is not None
502 cast(Iterator[domish.Element], stanza.elements("jabber:client", "body")),
503 None
504 ) is not None
505 496
506 497
507 def test_non_encryptable_elements() -> None: # pylint: disable=missing-function-docstring 498 def test_non_encryptable_elements() -> None: # pylint: disable=missing-function-docstring
508 profile = SCEProfile( 499 profile = SCEProfile(
509 SCEAffixPolicy.NOT_NEEDED, 500 SCEAffixPolicy.NOT_NEEDED,
518 <store xmlns="urn:xmpp:hints"/> 509 <store xmlns="urn:xmpp:hints"/>
519 </message>""") 510 </message>""")
520 511
521 envelope_serialized = XEP_0420.pack_stanza(profile, stanza) 512 envelope_serialized = XEP_0420.pack_stanza(profile, stanza)
522 envelope = string_to_domish(envelope_serialized.decode("utf-8")) 513 envelope = string_to_domish(envelope_serialized.decode("utf-8"))
523 content = next(cast(Iterator[domish.Element], envelope.elements(NS_SCE, "content"))) 514 content = next(envelope.elements(NS_SCE, "content"))
524 515
525 # The store hint must not have been moved to the content element 516 # The store hint must not have been moved to the content element
526 assert next( 517 assert next(stanza.elements(NS_HINTS, "store"), None) is not None
527 cast(Iterator[domish.Element], stanza.elements(NS_HINTS, "store")), 518 assert next(content.elements(NS_HINTS, "store"), None) is None
528 None
529 ) is not None
530
531 assert next(
532 cast(Iterator[domish.Element], content.elements(NS_HINTS, "store")),
533 None
534 ) is None
535 519
536 stanza = string_to_domish( 520 stanza = string_to_domish(
537 """<message from="foo@example.com" to="bar@example.com"></message>""" 521 """<message from="foo@example.com" to="bar@example.com"></message>"""
538 ) 522 )
539 523
546 </content> 530 </content>
547 </envelope>""".encode("utf-8") 531 </envelope>""".encode("utf-8")
548 532
549 XEP_0420.unpack_stanza(profile, stanza, envelope_serialized) 533 XEP_0420.unpack_stanza(profile, stanza, envelope_serialized)
550 534
551 assert next( 535 assert next(stanza.elements(NS_HINTS, "store"), None) is None
552 cast(Iterator[domish.Element], stanza.elements(NS_HINTS, "store")),
553 None
554 ) is None
555 536
556 537
557 def test_schema_validation() -> None: # pylint: disable=missing-function-docstring 538 def test_schema_validation() -> None: # pylint: disable=missing-function-docstring
558 profile = SCEProfile( 539 profile = SCEProfile(
559 SCEAffixPolicy.NOT_NEEDED, 540 SCEAffixPolicy.NOT_NEEDED,