deltachat-rpc-client 1.157.2__tar.gz → 1.158.0__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.
- {deltachat_rpc_client-1.157.2/src/deltachat_rpc_client.egg-info → deltachat_rpc_client-1.158.0}/PKG-INFO +3 -2
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/pyproject.toml +9 -1
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client/account.py +28 -37
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client/pytestplugin.py +59 -20
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0/src/deltachat_rpc_client.egg-info}/PKG-INFO +3 -2
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/tests/test_account_events.py +3 -2
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/tests/test_chatlist_events.py +3 -6
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/tests/test_iroh_webxdc.py +6 -15
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/tests/test_key_transfer.py +3 -0
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/tests/test_securejoin.py +17 -29
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/tests/test_something.py +149 -87
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/tests/test_webxdc.py +3 -9
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/LICENSE +0 -0
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/README.md +0 -0
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/setup.cfg +0 -0
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client/__init__.py +0 -0
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client/_utils.py +0 -0
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client/chat.py +0 -0
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client/client.py +0 -0
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client/const.py +0 -0
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client/contact.py +0 -0
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client/deltachat.py +0 -0
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client/events.py +0 -0
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client/message.py +0 -0
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client/py.typed +0 -0
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client/rpc.py +0 -0
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client.egg-info/SOURCES.txt +0 -0
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client.egg-info/dependency_links.txt +0 -0
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client.egg-info/entry_points.txt +0 -0
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client.egg-info/top_level.txt +0 -0
- {deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/tests/test_vcard.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: deltachat-rpc-client
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.158.0
|
|
4
4
|
Summary: Python client for Delta Chat core JSON-RPC interface
|
|
5
5
|
Classifier: Development Status :: 5 - Production/Stable
|
|
6
6
|
Classifier: Intended Audience :: Developers
|
|
@@ -19,6 +19,7 @@ Classifier: Topic :: Communications :: Email
|
|
|
19
19
|
Requires-Python: >=3.8
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
21
|
License-File: LICENSE
|
|
22
|
+
Dynamic: license-file
|
|
22
23
|
|
|
23
24
|
# Delta Chat RPC python client
|
|
24
25
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "deltachat-rpc-client"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.158.0"
|
|
8
8
|
description = "Python client for Delta Chat core JSON-RPC interface"
|
|
9
9
|
classifiers = [
|
|
10
10
|
"Development Status :: 5 - Production/Stable",
|
|
@@ -70,3 +70,11 @@ line-length = 120
|
|
|
70
70
|
|
|
71
71
|
[tool.isort]
|
|
72
72
|
profile = "black"
|
|
73
|
+
|
|
74
|
+
[dependency-groups]
|
|
75
|
+
dev = [
|
|
76
|
+
"imap-tools",
|
|
77
|
+
"pytest",
|
|
78
|
+
"pytest-timeout",
|
|
79
|
+
"pytest-xdist",
|
|
80
|
+
]
|
{deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client/account.py
RENAMED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from dataclasses import dataclass
|
|
4
|
-
from pathlib import Path
|
|
5
|
-
from tempfile import TemporaryDirectory
|
|
6
4
|
from typing import TYPE_CHECKING, Optional, Union
|
|
7
5
|
from warnings import warn
|
|
8
6
|
|
|
@@ -28,9 +26,12 @@ class Account:
|
|
|
28
26
|
def _rpc(self) -> "Rpc":
|
|
29
27
|
return self.manager.rpc
|
|
30
28
|
|
|
31
|
-
def wait_for_event(self) -> AttrDict:
|
|
29
|
+
def wait_for_event(self, event_type=None) -> AttrDict:
|
|
32
30
|
"""Wait until the next event and return it."""
|
|
33
|
-
|
|
31
|
+
while True:
|
|
32
|
+
next_event = AttrDict(self._rpc.wait_for_event(self.id))
|
|
33
|
+
if event_type is None or next_event.kind == event_type:
|
|
34
|
+
return next_event
|
|
34
35
|
|
|
35
36
|
def clear_all_events(self):
|
|
36
37
|
"""Removes all queued-up events for a given account. Useful for tests."""
|
|
@@ -41,14 +42,14 @@ class Account:
|
|
|
41
42
|
self._rpc.remove_account(self.id)
|
|
42
43
|
|
|
43
44
|
def clone(self) -> "Account":
|
|
44
|
-
"""Clone given account.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
45
|
+
"""Clone given account.
|
|
46
|
+
This uses backup-transfer via iroh, i.e. the 'Add second device' feature."""
|
|
47
|
+
future = self._rpc.provide_backup.future(self.id)
|
|
48
|
+
qr = self._rpc.get_backup_qr(self.id)
|
|
49
|
+
new_account = self.manager.add_account()
|
|
50
|
+
new_account._rpc.get_backup(new_account.id, qr)
|
|
51
|
+
future()
|
|
52
|
+
return new_account
|
|
52
53
|
|
|
53
54
|
def start_io(self) -> None:
|
|
54
55
|
"""Start the account I/O."""
|
|
@@ -112,12 +113,9 @@ class Account:
|
|
|
112
113
|
def bring_online(self):
|
|
113
114
|
"""Start I/O and wait until IMAP becomes IDLE."""
|
|
114
115
|
self.start_io()
|
|
115
|
-
|
|
116
|
-
event = self.wait_for_event()
|
|
117
|
-
if event.kind == EventType.IMAP_INBOX_IDLE:
|
|
118
|
-
break
|
|
116
|
+
self.wait_for_event(EventType.IMAP_INBOX_IDLE)
|
|
119
117
|
|
|
120
|
-
def create_contact(self, obj: Union[int, str, Contact], name: Optional[str] = None) -> Contact:
|
|
118
|
+
def create_contact(self, obj: Union[int, str, Contact, "Account"], name: Optional[str] = None) -> Contact:
|
|
121
119
|
"""Create a new Contact or return an existing one.
|
|
122
120
|
|
|
123
121
|
Calling this method will always result in the same
|
|
@@ -125,9 +123,15 @@ class Account:
|
|
|
125
123
|
with that e-mail address, it is unblocked and its display
|
|
126
124
|
name is updated if specified.
|
|
127
125
|
|
|
128
|
-
:param obj: email-address
|
|
126
|
+
:param obj: email-address, contact id or account.
|
|
129
127
|
:param name: (optional) display name for this contact.
|
|
130
128
|
"""
|
|
129
|
+
if isinstance(obj, Account):
|
|
130
|
+
vcard = obj.self_contact.make_vcard()
|
|
131
|
+
[contact] = self.import_vcard(vcard)
|
|
132
|
+
if name:
|
|
133
|
+
contact.set_name(name)
|
|
134
|
+
return contact
|
|
131
135
|
if isinstance(obj, int):
|
|
132
136
|
obj = Contact(self, obj)
|
|
133
137
|
if isinstance(obj, Contact):
|
|
@@ -148,9 +152,8 @@ class Account:
|
|
|
148
152
|
return [Contact(self, contact_id) for contact_id in contact_ids]
|
|
149
153
|
|
|
150
154
|
def create_chat(self, account: "Account") -> Chat:
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
return contact.create_chat()
|
|
155
|
+
"""Create a 1:1 chat with another account."""
|
|
156
|
+
return self.create_contact(account).create_chat()
|
|
154
157
|
|
|
155
158
|
def get_device_chat(self) -> Chat:
|
|
156
159
|
"""Return device chat."""
|
|
@@ -334,24 +337,15 @@ class Account:
|
|
|
334
337
|
|
|
335
338
|
def wait_for_incoming_msg_event(self):
|
|
336
339
|
"""Wait for incoming message event and return it."""
|
|
337
|
-
|
|
338
|
-
event = self.wait_for_event()
|
|
339
|
-
if event.kind == EventType.INCOMING_MSG:
|
|
340
|
-
return event
|
|
340
|
+
return self.wait_for_event(EventType.INCOMING_MSG)
|
|
341
341
|
|
|
342
342
|
def wait_for_msgs_changed_event(self):
|
|
343
343
|
"""Wait for messages changed event and return it."""
|
|
344
|
-
|
|
345
|
-
event = self.wait_for_event()
|
|
346
|
-
if event.kind == EventType.MSGS_CHANGED:
|
|
347
|
-
return event
|
|
344
|
+
return self.wait_for_event(EventType.MSGS_CHANGED)
|
|
348
345
|
|
|
349
346
|
def wait_for_msgs_noticed_event(self):
|
|
350
347
|
"""Wait for messages noticed event and return it."""
|
|
351
|
-
|
|
352
|
-
event = self.wait_for_event()
|
|
353
|
-
if event.kind == EventType.MSGS_NOTICED:
|
|
354
|
-
return event
|
|
348
|
+
return self.wait_for_event(EventType.MSGS_NOTICED)
|
|
355
349
|
|
|
356
350
|
def wait_for_incoming_msg(self):
|
|
357
351
|
"""Wait for incoming message and return it.
|
|
@@ -372,10 +366,7 @@ class Account:
|
|
|
372
366
|
break
|
|
373
367
|
|
|
374
368
|
def wait_for_reactions_changed(self):
|
|
375
|
-
|
|
376
|
-
event = self.wait_for_event()
|
|
377
|
-
if event.kind == EventType.REACTIONS_CHANGED:
|
|
378
|
-
return event
|
|
369
|
+
return self.wait_for_event(EventType.REACTIONS_CHANGED)
|
|
379
370
|
|
|
380
371
|
def get_fresh_messages_in_arrival_order(self) -> list[Message]:
|
|
381
372
|
"""Return fresh messages list sorted in the order of their arrival, with ascending IDs."""
|
|
@@ -4,6 +4,7 @@ import os
|
|
|
4
4
|
import random
|
|
5
5
|
from typing import AsyncGenerator, Optional
|
|
6
6
|
|
|
7
|
+
import py
|
|
7
8
|
import pytest
|
|
8
9
|
|
|
9
10
|
from . import Account, AttrDict, Bot, Chat, Client, DeltaChat, EventType, Message
|
|
@@ -11,14 +12,6 @@ from ._utils import futuremethod
|
|
|
11
12
|
from .rpc import Rpc
|
|
12
13
|
|
|
13
14
|
|
|
14
|
-
def get_temp_credentials() -> dict:
|
|
15
|
-
domain = os.getenv("CHATMAIL_DOMAIN")
|
|
16
|
-
username = "ci-" + "".join(random.choice("2345789acdefghjkmnpqrstuvwxyz") for i in range(6))
|
|
17
|
-
password = f"{username}${username}"
|
|
18
|
-
addr = f"{username}@{domain}"
|
|
19
|
-
return {"email": addr, "password": password}
|
|
20
|
-
|
|
21
|
-
|
|
22
15
|
class ACFactory:
|
|
23
16
|
def __init__(self, deltachat: DeltaChat) -> None:
|
|
24
17
|
self.deltachat = deltachat
|
|
@@ -31,26 +24,25 @@ class ACFactory:
|
|
|
31
24
|
def get_unconfigured_bot(self) -> Bot:
|
|
32
25
|
return Bot(self.get_unconfigured_account())
|
|
33
26
|
|
|
34
|
-
def
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
account.set_config("addr", credentials["email"])
|
|
39
|
-
account.set_config("mail_pw", credentials["password"])
|
|
40
|
-
assert not account.is_configured()
|
|
41
|
-
return account
|
|
27
|
+
def get_credentials(self) -> (str, str):
|
|
28
|
+
domain = os.getenv("CHATMAIL_DOMAIN")
|
|
29
|
+
username = "ci-" + "".join(random.choice("2345789acdefghjkmnpqrstuvwxyz") for i in range(6))
|
|
30
|
+
return f"{username}@{domain}", f"{username}${username}"
|
|
42
31
|
|
|
43
32
|
@futuremethod
|
|
44
33
|
def new_configured_account(self):
|
|
45
|
-
|
|
46
|
-
|
|
34
|
+
addr, password = self.get_credentials()
|
|
35
|
+
account = self.get_unconfigured_account()
|
|
36
|
+
params = {"addr": addr, "password": password}
|
|
37
|
+
yield account._rpc.add_transport.future(account.id, params)
|
|
38
|
+
|
|
47
39
|
assert account.is_configured()
|
|
48
40
|
return account
|
|
49
41
|
|
|
50
42
|
def new_configured_bot(self) -> Bot:
|
|
51
|
-
|
|
43
|
+
addr, password = self.get_credentials()
|
|
52
44
|
bot = self.get_unconfigured_bot()
|
|
53
|
-
bot.configure(
|
|
45
|
+
bot.configure(addr, password)
|
|
54
46
|
return bot
|
|
55
47
|
|
|
56
48
|
@futuremethod
|
|
@@ -124,3 +116,50 @@ def rpc(tmp_path) -> AsyncGenerator:
|
|
|
124
116
|
@pytest.fixture
|
|
125
117
|
def acfactory(rpc) -> AsyncGenerator:
|
|
126
118
|
return ACFactory(DeltaChat(rpc))
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@pytest.fixture
|
|
122
|
+
def data():
|
|
123
|
+
"""Test data."""
|
|
124
|
+
|
|
125
|
+
class Data:
|
|
126
|
+
def __init__(self) -> None:
|
|
127
|
+
for path in reversed(py.path.local(__file__).parts()):
|
|
128
|
+
datadir = path.join("test-data")
|
|
129
|
+
if datadir.isdir():
|
|
130
|
+
self.path = datadir
|
|
131
|
+
return
|
|
132
|
+
raise Exception("Data path cannot be found")
|
|
133
|
+
|
|
134
|
+
def get_path(self, bn):
|
|
135
|
+
"""return path of file or None if it doesn't exist."""
|
|
136
|
+
fn = os.path.join(self.path, *bn.split("/"))
|
|
137
|
+
assert os.path.exists(fn)
|
|
138
|
+
return fn
|
|
139
|
+
|
|
140
|
+
def read_path(self, bn, mode="r"):
|
|
141
|
+
fn = self.get_path(bn)
|
|
142
|
+
if fn is not None:
|
|
143
|
+
with open(fn, mode) as f:
|
|
144
|
+
return f.read()
|
|
145
|
+
return None
|
|
146
|
+
|
|
147
|
+
return Data()
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
@pytest.fixture
|
|
151
|
+
def log():
|
|
152
|
+
"""Log printer fixture."""
|
|
153
|
+
|
|
154
|
+
class Printer:
|
|
155
|
+
def section(self, msg: str) -> None:
|
|
156
|
+
print()
|
|
157
|
+
print("=" * 10, msg, "=" * 10)
|
|
158
|
+
|
|
159
|
+
def step(self, msg: str) -> None:
|
|
160
|
+
print("-" * 5, "step " + msg, "-" * 5)
|
|
161
|
+
|
|
162
|
+
def indent(self, msg: str) -> None:
|
|
163
|
+
print(" " + msg)
|
|
164
|
+
|
|
165
|
+
return Printer()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: deltachat-rpc-client
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.158.0
|
|
4
4
|
Summary: Python client for Delta Chat core JSON-RPC interface
|
|
5
5
|
Classifier: Development Status :: 5 - Production/Stable
|
|
6
6
|
Classifier: Intended Audience :: Developers
|
|
@@ -19,6 +19,7 @@ Classifier: Topic :: Communications :: Email
|
|
|
19
19
|
Requires-Python: >=3.8
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
21
|
License-File: LICENSE
|
|
22
|
+
Dynamic: license-file
|
|
22
23
|
|
|
23
24
|
# Delta Chat RPC python client
|
|
24
25
|
|
|
@@ -13,10 +13,11 @@ def test_event_on_configuration(acfactory: ACFactory) -> None:
|
|
|
13
13
|
Test if ACCOUNTS_ITEM_CHANGED event is emitted on configure
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
addr, password = acfactory.get_credentials()
|
|
17
|
+
account = acfactory.get_unconfigured_account()
|
|
17
18
|
account.clear_all_events()
|
|
18
19
|
assert not account.is_configured()
|
|
19
|
-
future = account.
|
|
20
|
+
future = account._rpc.add_transport.future(account.id, {"addr": addr, "password": password})
|
|
20
21
|
while True:
|
|
21
22
|
event = account.wait_for_event()
|
|
22
23
|
if event.kind == EventType.ACCOUNTS_ITEM_CHANGED:
|
|
@@ -48,8 +48,7 @@ def test_delivery_status(acfactory: ACFactory) -> None:
|
|
|
48
48
|
"""
|
|
49
49
|
alice, bob = acfactory.get_online_accounts(2)
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
alice_contact_bob = alice.create_contact(bob_addr, "Bob")
|
|
51
|
+
alice_contact_bob = alice.create_contact(bob, "Bob")
|
|
53
52
|
alice_chat_bob = alice_contact_bob.create_chat()
|
|
54
53
|
|
|
55
54
|
alice.clear_all_events()
|
|
@@ -119,8 +118,7 @@ def test_download_on_demand(acfactory: ACFactory) -> None:
|
|
|
119
118
|
"""
|
|
120
119
|
alice, bob = acfactory.get_online_accounts(2)
|
|
121
120
|
|
|
122
|
-
|
|
123
|
-
alice_contact_bob = alice.create_contact(bob_addr, "Bob")
|
|
121
|
+
alice_contact_bob = alice.create_contact(bob, "Bob")
|
|
124
122
|
alice_chat_bob = alice_contact_bob.create_chat()
|
|
125
123
|
alice_chat_bob.send_text("hi")
|
|
126
124
|
|
|
@@ -150,8 +148,7 @@ def test_download_on_demand(acfactory: ACFactory) -> None:
|
|
|
150
148
|
def get_multi_account_test_setup(acfactory: ACFactory) -> [Account, Account, Account]:
|
|
151
149
|
alice, bob = acfactory.get_online_accounts(2)
|
|
152
150
|
|
|
153
|
-
|
|
154
|
-
alice_contact_bob = alice.create_contact(bob_addr, "Bob")
|
|
151
|
+
alice_contact_bob = alice.create_contact(bob, "Bob")
|
|
155
152
|
alice_chat_bob = alice_contact_bob.create_chat()
|
|
156
153
|
alice_chat_bob.send_text("hi")
|
|
157
154
|
|
|
@@ -175,17 +175,11 @@ def test_no_duplicate_messages(acfactory, path_to_webxdc):
|
|
|
175
175
|
|
|
176
176
|
threading.Thread(target=thread_run, daemon=True).start()
|
|
177
177
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
if event.kind == EventType.WEBXDC_REALTIME_DATA:
|
|
181
|
-
n = int(bytes(event.data).decode())
|
|
182
|
-
break
|
|
178
|
+
event = ac2.wait_for_event(EventType.WEBXDC_REALTIME_DATA)
|
|
179
|
+
n = int(bytes(event.data).decode())
|
|
183
180
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
if event.kind == EventType.WEBXDC_REALTIME_DATA:
|
|
187
|
-
assert int(bytes(event.data).decode()) > n
|
|
188
|
-
break
|
|
181
|
+
event = ac2.wait_for_event(EventType.WEBXDC_REALTIME_DATA)
|
|
182
|
+
assert int(bytes(event.data).decode()) > n
|
|
189
183
|
|
|
190
184
|
|
|
191
185
|
def test_no_reordering(acfactory, path_to_webxdc):
|
|
@@ -229,8 +223,5 @@ def test_advertisement_after_chatting(acfactory, path_to_webxdc):
|
|
|
229
223
|
ac2_hello_msg_snapshot.chat.accept()
|
|
230
224
|
|
|
231
225
|
ac2_webxdc_msg.send_webxdc_realtime_advertisement()
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
if event.kind == EventType.WEBXDC_REALTIME_ADVERTISEMENT_RECEIVED:
|
|
235
|
-
assert event.msg_id == ac1_webxdc_msg.id
|
|
236
|
-
break
|
|
226
|
+
event = ac1.wait_for_event(EventType.WEBXDC_REALTIME_ADVERTISEMENT_RECEIVED)
|
|
227
|
+
assert event.msg_id == ac1_webxdc_msg.id
|
|
@@ -21,6 +21,7 @@ def test_autocrypt_setup_message_key_transfer(acfactory):
|
|
|
21
21
|
alice2.set_config("addr", alice1.get_config("addr"))
|
|
22
22
|
alice2.set_config("mail_pw", alice1.get_config("mail_pw"))
|
|
23
23
|
alice2.configure()
|
|
24
|
+
alice2.bring_online()
|
|
24
25
|
|
|
25
26
|
setup_code = alice1.initiate_autocrypt_key_transfer()
|
|
26
27
|
msg = wait_for_autocrypt_setup_message(alice2)
|
|
@@ -34,10 +35,12 @@ def test_autocrypt_setup_message_key_transfer(acfactory):
|
|
|
34
35
|
|
|
35
36
|
def test_ac_setup_message_twice(acfactory):
|
|
36
37
|
alice1 = acfactory.get_online_account()
|
|
38
|
+
|
|
37
39
|
alice2 = acfactory.get_unconfigured_account()
|
|
38
40
|
alice2.set_config("addr", alice1.get_config("addr"))
|
|
39
41
|
alice2.set_config("mail_pw", alice1.get_config("mail_pw"))
|
|
40
42
|
alice2.configure()
|
|
43
|
+
alice2.bring_online()
|
|
41
44
|
|
|
42
45
|
# Send the first Autocrypt Setup Message and ignore it.
|
|
43
46
|
_setup_code = alice1.initiate_autocrypt_key_transfer()
|
|
@@ -76,17 +76,11 @@ def test_qr_securejoin(acfactory, protect):
|
|
|
76
76
|
bob.secure_join(qr_code)
|
|
77
77
|
|
|
78
78
|
# Alice deletes "vg-request".
|
|
79
|
-
|
|
80
|
-
event = alice.wait_for_event()
|
|
81
|
-
if event["kind"] == "ImapMessageDeleted":
|
|
82
|
-
break
|
|
79
|
+
alice.wait_for_event(EventType.IMAP_MESSAGE_DELETED)
|
|
83
80
|
alice.wait_for_securejoin_inviter_success()
|
|
84
81
|
# Bob deletes "vg-auth-required", Alice deletes "vg-request-with-auth".
|
|
85
82
|
for ac in [alice, bob]:
|
|
86
|
-
|
|
87
|
-
event = ac.wait_for_event()
|
|
88
|
-
if event["kind"] == "ImapMessageDeleted":
|
|
89
|
-
break
|
|
83
|
+
ac.wait_for_event(EventType.IMAP_MESSAGE_DELETED)
|
|
90
84
|
bob.wait_for_securejoin_joiner_success()
|
|
91
85
|
|
|
92
86
|
# Test that Alice verified Bob's profile.
|
|
@@ -123,8 +117,7 @@ def test_qr_securejoin_contact_request(acfactory) -> None:
|
|
|
123
117
|
"""Alice invites Bob to a group when Bob's chat with Alice is in a contact request mode."""
|
|
124
118
|
alice, bob = acfactory.get_online_accounts(2)
|
|
125
119
|
|
|
126
|
-
|
|
127
|
-
alice_contact_bob = alice.create_contact(bob_addr, "Bob")
|
|
120
|
+
alice_contact_bob = alice.create_contact(bob, "Bob")
|
|
128
121
|
alice_chat_bob = alice_contact_bob.create_chat()
|
|
129
122
|
alice_chat_bob.send_text("Hello!")
|
|
130
123
|
|
|
@@ -161,11 +154,8 @@ def test_qr_readreceipt(acfactory) -> None:
|
|
|
161
154
|
logging.info("Alice creates a verified group")
|
|
162
155
|
group = alice.create_group("Group", protect=True)
|
|
163
156
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
alice_contact_bob = alice.create_contact(bob_addr, "Bob")
|
|
168
|
-
alice_contact_charlie = alice.create_contact(charlie_addr, "Charlie")
|
|
157
|
+
alice_contact_bob = alice.create_contact(bob, "Bob")
|
|
158
|
+
alice_contact_charlie = alice.create_contact(charlie, "Charlie")
|
|
169
159
|
|
|
170
160
|
group.add_contact(alice_contact_bob)
|
|
171
161
|
group.add_contact(alice_contact_charlie)
|
|
@@ -192,7 +182,7 @@ def test_qr_readreceipt(acfactory) -> None:
|
|
|
192
182
|
charlie_snapshot = charlie_message.get_snapshot()
|
|
193
183
|
assert charlie_snapshot.text == "Hi from Bob!"
|
|
194
184
|
|
|
195
|
-
bob_contact_charlie = bob.create_contact(
|
|
185
|
+
bob_contact_charlie = bob.create_contact(charlie, "Charlie")
|
|
196
186
|
assert not bob.get_chat_by_contact(bob_contact_charlie)
|
|
197
187
|
|
|
198
188
|
logging.info("Charlie reads Bob's message")
|
|
@@ -463,12 +453,12 @@ def test_qr_new_group_unblocked(acfactory):
|
|
|
463
453
|
assert ac2_msg.chat.get_basic_snapshot().is_contact_request
|
|
464
454
|
|
|
465
455
|
|
|
456
|
+
@pytest.mark.skip(reason="AEAP is disabled for now")
|
|
466
457
|
def test_aeap_flow_verified(acfactory):
|
|
467
458
|
"""Test that a new address is added to a contact when it changes its address."""
|
|
468
459
|
ac1, ac2 = acfactory.get_online_accounts(2)
|
|
469
460
|
|
|
470
|
-
|
|
471
|
-
ac1new = acfactory.new_preconfigured_account()
|
|
461
|
+
addr, password = acfactory.get_credentials()
|
|
472
462
|
|
|
473
463
|
logging.info("ac1: create verified-group QR, ac2 scans and joins")
|
|
474
464
|
chat = ac1.create_group("hello", protect=True)
|
|
@@ -488,8 +478,8 @@ def test_aeap_flow_verified(acfactory):
|
|
|
488
478
|
assert msg_in_1.text == msg_out.text
|
|
489
479
|
|
|
490
480
|
logging.info("changing email account")
|
|
491
|
-
ac1.set_config("addr",
|
|
492
|
-
ac1.set_config("mail_pw",
|
|
481
|
+
ac1.set_config("addr", addr)
|
|
482
|
+
ac1.set_config("mail_pw", password)
|
|
493
483
|
ac1.stop_io()
|
|
494
484
|
ac1.configure()
|
|
495
485
|
ac1.start_io()
|
|
@@ -502,11 +492,9 @@ def test_aeap_flow_verified(acfactory):
|
|
|
502
492
|
msg_in_2_snapshot = msg_in_2.get_snapshot()
|
|
503
493
|
assert msg_in_2_snapshot.text == msg_out.text
|
|
504
494
|
assert msg_in_2_snapshot.chat.id == msg_in_1.chat.id
|
|
505
|
-
assert msg_in_2.get_sender_contact().get_snapshot().address ==
|
|
495
|
+
assert msg_in_2.get_sender_contact().get_snapshot().address == addr
|
|
506
496
|
assert len(msg_in_2_snapshot.chat.get_contacts()) == 2
|
|
507
|
-
assert
|
|
508
|
-
contact.get_snapshot().address for contact in msg_in_2_snapshot.chat.get_contacts()
|
|
509
|
-
]
|
|
497
|
+
assert addr in [contact.get_snapshot().address for contact in msg_in_2_snapshot.chat.get_contacts()]
|
|
510
498
|
|
|
511
499
|
|
|
512
500
|
def test_gossip_verification(acfactory) -> None:
|
|
@@ -522,9 +510,9 @@ def test_gossip_verification(acfactory) -> None:
|
|
|
522
510
|
bob.secure_join(qr_code)
|
|
523
511
|
bob.wait_for_securejoin_joiner_success()
|
|
524
512
|
|
|
525
|
-
bob_contact_alice = bob.create_contact(alice
|
|
526
|
-
bob_contact_carol = bob.create_contact(carol
|
|
527
|
-
carol_contact_alice = carol.create_contact(alice
|
|
513
|
+
bob_contact_alice = bob.create_contact(alice, "Alice")
|
|
514
|
+
bob_contact_carol = bob.create_contact(carol, "Carol")
|
|
515
|
+
carol_contact_alice = carol.create_contact(alice, "Alice")
|
|
528
516
|
|
|
529
517
|
logging.info("Bob creates an Autocrypt group")
|
|
530
518
|
bob_group_chat = bob.create_group("Autocrypt Group")
|
|
@@ -584,7 +572,7 @@ def test_securejoin_after_contact_resetup(acfactory) -> None:
|
|
|
584
572
|
ac2.wait_for_securejoin_joiner_success()
|
|
585
573
|
|
|
586
574
|
# ac1 is verified for ac2.
|
|
587
|
-
ac2_contact_ac1 = ac2.create_contact(ac1
|
|
575
|
+
ac2_contact_ac1 = ac2.create_contact(ac1, "")
|
|
588
576
|
assert ac2_contact_ac1.get_snapshot().is_verified
|
|
589
577
|
|
|
590
578
|
# ac1 resetups the account.
|
|
@@ -599,7 +587,7 @@ def test_securejoin_after_contact_resetup(acfactory) -> None:
|
|
|
599
587
|
# header sent by old ac1.
|
|
600
588
|
while True:
|
|
601
589
|
# ac1 sends a message to ac2.
|
|
602
|
-
ac1_contact_ac2 = ac1.create_contact(ac2
|
|
590
|
+
ac1_contact_ac2 = ac1.create_contact(ac2, "")
|
|
603
591
|
ac1_chat_ac2 = ac1_contact_ac2.create_chat()
|
|
604
592
|
ac1_chat_ac2.send_text("Hello!")
|
|
605
593
|
|
|
@@ -61,61 +61,83 @@ def test_acfactory(acfactory) -> None:
|
|
|
61
61
|
|
|
62
62
|
|
|
63
63
|
def test_configure_starttls(acfactory) -> None:
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
64
|
+
addr, password = acfactory.get_credentials()
|
|
65
|
+
account = acfactory.get_unconfigured_account()
|
|
66
|
+
account._rpc.add_transport(
|
|
67
|
+
account.id,
|
|
68
|
+
{
|
|
69
|
+
"addr": addr,
|
|
70
|
+
"password": password,
|
|
71
|
+
"imapSecurity": "starttls",
|
|
72
|
+
"smtpSecurity": "starttls",
|
|
73
|
+
},
|
|
74
|
+
)
|
|
70
75
|
assert account.is_configured()
|
|
71
76
|
|
|
72
77
|
|
|
73
78
|
def test_configure_ip(acfactory) -> None:
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
ip_address = socket.gethostbyname(domain)
|
|
79
|
+
addr, password = acfactory.get_credentials()
|
|
80
|
+
account = acfactory.get_unconfigured_account()
|
|
81
|
+
ip_address = socket.gethostbyname(addr.rsplit("@")[-1])
|
|
78
82
|
|
|
79
|
-
# This should fail TLS check.
|
|
80
|
-
account.set_config("mail_server", ip_address)
|
|
81
83
|
with pytest.raises(JsonRpcError):
|
|
82
|
-
account.
|
|
84
|
+
account._rpc.add_transport(
|
|
85
|
+
account.id,
|
|
86
|
+
{
|
|
87
|
+
"addr": addr,
|
|
88
|
+
"password": password,
|
|
89
|
+
# This should fail TLS check.
|
|
90
|
+
"imapServer": ip_address,
|
|
91
|
+
},
|
|
92
|
+
)
|
|
83
93
|
|
|
84
94
|
|
|
85
95
|
def test_configure_alternative_port(acfactory) -> None:
|
|
86
96
|
"""Test that configuration with alternative port 443 works."""
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
account.
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
+
addr, password = acfactory.get_credentials()
|
|
98
|
+
account = acfactory.get_unconfigured_account()
|
|
99
|
+
account._rpc.add_transport(
|
|
100
|
+
account.id,
|
|
101
|
+
{
|
|
102
|
+
"addr": addr,
|
|
103
|
+
"password": password,
|
|
104
|
+
"imapPort": 443,
|
|
105
|
+
"smtpPort": 443,
|
|
106
|
+
},
|
|
107
|
+
)
|
|
108
|
+
assert account.is_configured()
|
|
97
109
|
|
|
98
|
-
addr = account.get_config("addr")
|
|
99
|
-
account.set_config("mail_user", addr)
|
|
100
|
-
account.configure()
|
|
101
110
|
|
|
102
|
-
|
|
111
|
+
def test_list_transports(acfactory) -> None:
|
|
112
|
+
addr, password = acfactory.get_credentials()
|
|
113
|
+
account = acfactory.get_unconfigured_account()
|
|
114
|
+
account._rpc.add_transport(
|
|
115
|
+
account.id,
|
|
116
|
+
{
|
|
117
|
+
"addr": addr,
|
|
118
|
+
"password": password,
|
|
119
|
+
"imapUser": addr,
|
|
120
|
+
},
|
|
121
|
+
)
|
|
122
|
+
transports = account._rpc.list_transports(account.id)
|
|
123
|
+
assert len(transports) == 1
|
|
124
|
+
params = transports[0]
|
|
125
|
+
assert params["addr"] == addr
|
|
126
|
+
assert params["password"] == password
|
|
127
|
+
assert params["imapUser"] == addr
|
|
103
128
|
|
|
104
129
|
|
|
105
130
|
def test_account(acfactory) -> None:
|
|
106
131
|
alice, bob = acfactory.get_online_accounts(2)
|
|
107
132
|
|
|
108
133
|
bob_addr = bob.get_config("addr")
|
|
109
|
-
alice_contact_bob = alice.create_contact(
|
|
134
|
+
alice_contact_bob = alice.create_contact(bob, "Bob")
|
|
110
135
|
alice_chat_bob = alice_contact_bob.create_chat()
|
|
111
136
|
alice_chat_bob.send_text("Hello!")
|
|
112
137
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
chat_id = event.chat_id
|
|
117
|
-
msg_id = event.msg_id
|
|
118
|
-
break
|
|
138
|
+
event = bob.wait_for_incoming_msg_event()
|
|
139
|
+
chat_id = event.chat_id
|
|
140
|
+
msg_id = event.msg_id
|
|
119
141
|
|
|
120
142
|
message = bob.get_message_by_id(msg_id)
|
|
121
143
|
snapshot = message.get_snapshot()
|
|
@@ -174,8 +196,7 @@ def test_account(acfactory) -> None:
|
|
|
174
196
|
def test_chat(acfactory) -> None:
|
|
175
197
|
alice, bob = acfactory.get_online_accounts(2)
|
|
176
198
|
|
|
177
|
-
|
|
178
|
-
alice_contact_bob = alice.create_contact(bob_addr, "Bob")
|
|
199
|
+
alice_contact_bob = alice.create_contact(bob, "Bob")
|
|
179
200
|
alice_chat_bob = alice_contact_bob.create_chat()
|
|
180
201
|
alice_chat_bob.send_text("Hello!")
|
|
181
202
|
|
|
@@ -241,7 +262,7 @@ def test_contact(acfactory) -> None:
|
|
|
241
262
|
alice, bob = acfactory.get_online_accounts(2)
|
|
242
263
|
|
|
243
264
|
bob_addr = bob.get_config("addr")
|
|
244
|
-
alice_contact_bob = alice.create_contact(
|
|
265
|
+
alice_contact_bob = alice.create_contact(bob, "Bob")
|
|
245
266
|
|
|
246
267
|
assert alice_contact_bob == alice.get_contact_by_id(alice_contact_bob.id)
|
|
247
268
|
assert repr(alice_contact_bob)
|
|
@@ -258,8 +279,7 @@ def test_contact(acfactory) -> None:
|
|
|
258
279
|
def test_message(acfactory) -> None:
|
|
259
280
|
alice, bob = acfactory.get_online_accounts(2)
|
|
260
281
|
|
|
261
|
-
|
|
262
|
-
alice_contact_bob = alice.create_contact(bob_addr, "Bob")
|
|
282
|
+
alice_contact_bob = alice.create_contact(bob, "Bob")
|
|
263
283
|
alice_chat_bob = alice_contact_bob.create_chat()
|
|
264
284
|
alice_chat_bob.send_text("Hello!")
|
|
265
285
|
|
|
@@ -287,13 +307,37 @@ def test_message(acfactory) -> None:
|
|
|
287
307
|
assert reactions == snapshot.reactions
|
|
288
308
|
|
|
289
309
|
|
|
310
|
+
def test_selfavatar_sync(acfactory, data, log) -> None:
|
|
311
|
+
alice = acfactory.get_online_account()
|
|
312
|
+
|
|
313
|
+
log.section("Alice adds a second device")
|
|
314
|
+
alice2 = alice.clone()
|
|
315
|
+
|
|
316
|
+
log.section("Second device goes online")
|
|
317
|
+
alice2.start_io()
|
|
318
|
+
|
|
319
|
+
log.section("First device changes avatar")
|
|
320
|
+
image = data.get_path("image/avatar1000x1000.jpg")
|
|
321
|
+
alice.set_config("selfavatar", image)
|
|
322
|
+
avatar_config = alice.get_config("selfavatar")
|
|
323
|
+
avatar_hash = os.path.basename(avatar_config)
|
|
324
|
+
print("Info: avatar hash is ", avatar_hash)
|
|
325
|
+
|
|
326
|
+
log.section("First device receives avatar change")
|
|
327
|
+
alice2.wait_for_event(EventType.SELFAVATAR_CHANGED)
|
|
328
|
+
avatar_config2 = alice2.get_config("selfavatar")
|
|
329
|
+
avatar_hash2 = os.path.basename(avatar_config2)
|
|
330
|
+
print("Info: avatar hash on second device is ", avatar_hash2)
|
|
331
|
+
assert avatar_hash == avatar_hash2
|
|
332
|
+
assert avatar_config != avatar_config2
|
|
333
|
+
|
|
334
|
+
|
|
290
335
|
def test_reaction_seen_on_another_dev(acfactory) -> None:
|
|
291
336
|
alice, bob = acfactory.get_online_accounts(2)
|
|
292
337
|
alice2 = alice.clone()
|
|
293
338
|
alice2.start_io()
|
|
294
339
|
|
|
295
|
-
|
|
296
|
-
alice_contact_bob = alice.create_contact(bob_addr, "Bob")
|
|
340
|
+
alice_contact_bob = alice.create_contact(bob, "Bob")
|
|
297
341
|
alice_chat_bob = alice_contact_bob.create_chat()
|
|
298
342
|
alice_chat_bob.send_text("Hello!")
|
|
299
343
|
|
|
@@ -305,20 +349,12 @@ def test_reaction_seen_on_another_dev(acfactory) -> None:
|
|
|
305
349
|
snapshot.chat.accept()
|
|
306
350
|
message.send_reaction("😎")
|
|
307
351
|
for a in [alice, alice2]:
|
|
308
|
-
|
|
309
|
-
event = a.wait_for_event()
|
|
310
|
-
if event.kind == EventType.INCOMING_REACTION:
|
|
311
|
-
break
|
|
352
|
+
a.wait_for_event(EventType.INCOMING_REACTION)
|
|
312
353
|
|
|
313
354
|
alice2.clear_all_events()
|
|
314
355
|
alice_chat_bob.mark_noticed()
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
if event.kind == EventType.MSGS_NOTICED:
|
|
318
|
-
chat_id = event.chat_id
|
|
319
|
-
break
|
|
320
|
-
alice2_contact_bob = alice2.get_contact_by_addr(bob_addr)
|
|
321
|
-
alice2_chat_bob = alice2_contact_bob.create_chat()
|
|
356
|
+
chat_id = alice2.wait_for_event(EventType.MSGS_NOTICED).chat_id
|
|
357
|
+
alice2_chat_bob = alice2.create_chat(bob)
|
|
322
358
|
assert chat_id == alice2_chat_bob.id
|
|
323
359
|
|
|
324
360
|
|
|
@@ -326,24 +362,19 @@ def test_is_bot(acfactory) -> None:
|
|
|
326
362
|
"""Test that we can recognize messages submitted by bots."""
|
|
327
363
|
alice, bob = acfactory.get_online_accounts(2)
|
|
328
364
|
|
|
329
|
-
|
|
330
|
-
alice_contact_bob = alice.create_contact(bob_addr, "Bob")
|
|
365
|
+
alice_contact_bob = alice.create_contact(bob, "Bob")
|
|
331
366
|
alice_chat_bob = alice_contact_bob.create_chat()
|
|
332
367
|
|
|
333
368
|
# Alice becomes a bot.
|
|
334
369
|
alice.set_config("bot", "1")
|
|
335
370
|
alice_chat_bob.send_text("Hello!")
|
|
336
371
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
assert snapshot.chat_id == event.chat_id
|
|
344
|
-
assert snapshot.text == "Hello!"
|
|
345
|
-
assert snapshot.is_bot
|
|
346
|
-
break
|
|
372
|
+
event = bob.wait_for_incoming_msg_event()
|
|
373
|
+
message = bob.get_message_by_id(event.msg_id)
|
|
374
|
+
snapshot = message.get_snapshot()
|
|
375
|
+
assert snapshot.chat_id == event.chat_id
|
|
376
|
+
assert snapshot.text == "Hello!"
|
|
377
|
+
assert snapshot.is_bot
|
|
347
378
|
|
|
348
379
|
|
|
349
380
|
def test_bot(acfactory) -> None:
|
|
@@ -390,9 +421,11 @@ def test_wait_next_messages(acfactory) -> None:
|
|
|
390
421
|
alice = acfactory.new_configured_account()
|
|
391
422
|
|
|
392
423
|
# Create a bot account so it does not receive device messages in the beginning.
|
|
393
|
-
|
|
424
|
+
addr, password = acfactory.get_credentials()
|
|
425
|
+
bot = acfactory.get_unconfigured_account()
|
|
394
426
|
bot.set_config("bot", "1")
|
|
395
|
-
bot.
|
|
427
|
+
bot._rpc.add_transport(bot.id, {"addr": addr, "password": password})
|
|
428
|
+
assert bot.is_configured()
|
|
396
429
|
|
|
397
430
|
# There are no old messages and the call returns immediately.
|
|
398
431
|
assert not bot.wait_next_messages()
|
|
@@ -401,8 +434,7 @@ def test_wait_next_messages(acfactory) -> None:
|
|
|
401
434
|
# Bot starts waiting for messages.
|
|
402
435
|
next_messages_task = executor.submit(bot.wait_next_messages)
|
|
403
436
|
|
|
404
|
-
|
|
405
|
-
alice_contact_bot = alice.create_contact(bot_addr, "Bot")
|
|
437
|
+
alice_contact_bot = alice.create_contact(bot, "Bot")
|
|
406
438
|
alice_chat_bot = alice_contact_bot.create_chat()
|
|
407
439
|
alice_chat_bot.send_text("Hello!")
|
|
408
440
|
|
|
@@ -426,9 +458,7 @@ def test_import_export_backup(acfactory, tmp_path) -> None:
|
|
|
426
458
|
def test_import_export_keys(acfactory, tmp_path) -> None:
|
|
427
459
|
alice, bob = acfactory.get_online_accounts(2)
|
|
428
460
|
|
|
429
|
-
|
|
430
|
-
alice_contact_bob = alice.create_contact(bob_addr, "Bob")
|
|
431
|
-
alice_chat_bob = alice_contact_bob.create_chat()
|
|
461
|
+
alice_chat_bob = alice.create_chat(bob)
|
|
432
462
|
alice_chat_bob.send_text("Hello Bob!")
|
|
433
463
|
|
|
434
464
|
snapshot = bob.get_message_by_id(bob.wait_for_incoming_msg_event().msg_id).get_snapshot()
|
|
@@ -478,9 +508,7 @@ def test_provider_info(rpc) -> None:
|
|
|
478
508
|
def test_mdn_doesnt_break_autocrypt(acfactory) -> None:
|
|
479
509
|
alice, bob = acfactory.get_online_accounts(2)
|
|
480
510
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
alice_contact_bob = alice.create_contact(bob_addr, "Bob")
|
|
511
|
+
alice_contact_bob = alice.create_contact(bob, "Bob")
|
|
484
512
|
|
|
485
513
|
# Bob creates chat manually so chat with Alice is accepted.
|
|
486
514
|
alice_chat_bob = alice_contact_bob.create_chat()
|
|
@@ -504,10 +532,7 @@ def test_mdn_doesnt_break_autocrypt(acfactory) -> None:
|
|
|
504
532
|
|
|
505
533
|
# Alice reads Bob's message.
|
|
506
534
|
message.mark_seen()
|
|
507
|
-
|
|
508
|
-
event = bob.wait_for_event()
|
|
509
|
-
if event.kind == EventType.MSG_READ:
|
|
510
|
-
break
|
|
535
|
+
bob.wait_for_event(EventType.MSG_READ)
|
|
511
536
|
|
|
512
537
|
# Bob sends a message to Alice, it should also be encrypted.
|
|
513
538
|
bob_chat_alice.send_text("Hi Alice!")
|
|
@@ -579,9 +604,13 @@ def test_reactions_for_a_reordering_move(acfactory, direct_imap):
|
|
|
579
604
|
messages they refer to and thus dropped.
|
|
580
605
|
"""
|
|
581
606
|
(ac1,) = acfactory.get_online_accounts(1)
|
|
582
|
-
|
|
583
|
-
|
|
607
|
+
|
|
608
|
+
addr, password = acfactory.get_credentials()
|
|
609
|
+
ac2 = acfactory.get_unconfigured_account()
|
|
610
|
+
ac2._rpc.add_transport(ac2.id, {"addr": addr, "password": password})
|
|
584
611
|
ac2.set_config("mvbox_move", "1")
|
|
612
|
+
assert ac2.is_configured()
|
|
613
|
+
|
|
585
614
|
ac2.bring_online()
|
|
586
615
|
chat1 = acfactory.get_accepted_chat(ac1, ac2)
|
|
587
616
|
ac2.stop_io()
|
|
@@ -625,9 +654,7 @@ def test_download_limit_chat_assignment(acfactory, tmp_path, n_accounts):
|
|
|
625
654
|
chat.send_text("Hello Alice!")
|
|
626
655
|
assert alice.get_message_by_id(alice.wait_for_incoming_msg_event().msg_id).get_snapshot().text == "Hello Alice!"
|
|
627
656
|
|
|
628
|
-
|
|
629
|
-
contact = alice.create_contact(contact_addr, "")
|
|
630
|
-
|
|
657
|
+
contact = alice.create_contact(account)
|
|
631
658
|
alice_group.add_contact(contact)
|
|
632
659
|
|
|
633
660
|
if n_accounts == 2:
|
|
@@ -677,10 +704,7 @@ def test_markseen_contact_request(acfactory):
|
|
|
677
704
|
assert message2.get_snapshot().state == MessageState.IN_FRESH
|
|
678
705
|
|
|
679
706
|
message.mark_seen()
|
|
680
|
-
|
|
681
|
-
event = bob2.wait_for_event()
|
|
682
|
-
if event.kind == EventType.MSGS_NOTICED:
|
|
683
|
-
break
|
|
707
|
+
bob2.wait_for_event(EventType.MSGS_NOTICED)
|
|
684
708
|
assert message2.get_snapshot().state == MessageState.IN_SEEN
|
|
685
709
|
|
|
686
710
|
|
|
@@ -728,6 +752,8 @@ def test_no_old_msg_is_fresh(acfactory):
|
|
|
728
752
|
assert ac1.create_chat(ac2).get_fresh_message_count() == 1
|
|
729
753
|
assert len(list(ac1.get_fresh_messages())) == 1
|
|
730
754
|
|
|
755
|
+
ac1.wait_for_event(EventType.IMAP_INBOX_IDLE)
|
|
756
|
+
|
|
731
757
|
logging.info("Send a message from ac1_clone to ac2 and check that ac1 marks the first message as 'noticed'")
|
|
732
758
|
ac1_clone_chat.send_text("Hi back")
|
|
733
759
|
ev = ac1.wait_for_msgs_noticed_event()
|
|
@@ -735,3 +761,39 @@ def test_no_old_msg_is_fresh(acfactory):
|
|
|
735
761
|
assert ev.chat_id == first_msg.get_snapshot().chat_id
|
|
736
762
|
assert ac1.create_chat(ac2).get_fresh_message_count() == 0
|
|
737
763
|
assert len(list(ac1.get_fresh_messages())) == 0
|
|
764
|
+
|
|
765
|
+
|
|
766
|
+
def test_rename_synchronization(acfactory):
|
|
767
|
+
"""Test synchronization of contact renaming."""
|
|
768
|
+
alice, bob = acfactory.get_online_accounts(2)
|
|
769
|
+
alice2 = alice.clone()
|
|
770
|
+
alice2.bring_online()
|
|
771
|
+
|
|
772
|
+
bob.set_config("displayname", "Bob")
|
|
773
|
+
bob.create_chat(alice).send_text("Hello!")
|
|
774
|
+
alice_msg = alice.wait_for_incoming_msg().get_snapshot()
|
|
775
|
+
alice2_msg = alice2.wait_for_incoming_msg().get_snapshot()
|
|
776
|
+
|
|
777
|
+
assert alice2_msg.sender.get_snapshot().display_name == "Bob"
|
|
778
|
+
alice_msg.sender.set_name("Bobby")
|
|
779
|
+
alice2.wait_for_event(EventType.CONTACTS_CHANGED)
|
|
780
|
+
assert alice2_msg.sender.get_snapshot().display_name == "Bobby"
|
|
781
|
+
|
|
782
|
+
|
|
783
|
+
def test_rename_group(acfactory):
|
|
784
|
+
"""Test renaming the group."""
|
|
785
|
+
alice, bob = acfactory.get_online_accounts(2)
|
|
786
|
+
|
|
787
|
+
alice_group = alice.create_group("Test group")
|
|
788
|
+
alice_contact_bob = alice.create_contact(bob)
|
|
789
|
+
alice_group.add_contact(alice_contact_bob)
|
|
790
|
+
alice_group.send_text("Hello!")
|
|
791
|
+
|
|
792
|
+
bob_msg = bob.wait_for_incoming_msg()
|
|
793
|
+
bob_chat = bob_msg.get_snapshot().chat
|
|
794
|
+
assert bob_chat.get_basic_snapshot().name == "Test group"
|
|
795
|
+
|
|
796
|
+
for name in ["Baz", "Foo bar", "Xyzzy"]:
|
|
797
|
+
alice_group.set_name(name)
|
|
798
|
+
bob.wait_for_incoming_msg_event()
|
|
799
|
+
assert bob_chat.get_basic_snapshot().name == name
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
from deltachat_rpc_client import EventType
|
|
2
|
-
|
|
3
|
-
|
|
4
1
|
def test_webxdc(acfactory) -> None:
|
|
5
2
|
alice, bob = acfactory.get_online_accounts(2)
|
|
6
3
|
|
|
@@ -9,12 +6,9 @@ def test_webxdc(acfactory) -> None:
|
|
|
9
6
|
alice_chat_bob = alice_contact_bob.create_chat()
|
|
10
7
|
alice_chat_bob.send_message(text="Let's play chess!", file="../test-data/webxdc/chess.xdc")
|
|
11
8
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
bob_chat_alice = bob.get_chat_by_id(event.chat_id)
|
|
16
|
-
message = bob.get_message_by_id(event.msg_id)
|
|
17
|
-
break
|
|
9
|
+
event = bob.wait_for_incoming_msg_event()
|
|
10
|
+
bob_chat_alice = bob.get_chat_by_id(event.chat_id)
|
|
11
|
+
message = bob.get_message_by_id(event.msg_id)
|
|
18
12
|
|
|
19
13
|
webxdc_info = message.get_webxdc_info()
|
|
20
14
|
assert webxdc_info == {
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client/__init__.py
RENAMED
|
File without changes
|
{deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client/_utils.py
RENAMED
|
File without changes
|
{deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client/chat.py
RENAMED
|
File without changes
|
{deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client/client.py
RENAMED
|
File without changes
|
{deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client/const.py
RENAMED
|
File without changes
|
{deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client/contact.py
RENAMED
|
File without changes
|
{deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client/deltachat.py
RENAMED
|
File without changes
|
{deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client/events.py
RENAMED
|
File without changes
|
{deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client/message.py
RENAMED
|
File without changes
|
{deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client/py.typed
RENAMED
|
File without changes
|
{deltachat_rpc_client-1.157.2 → deltachat_rpc_client-1.158.0}/src/deltachat_rpc_client/rpc.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|