deltachat-rpc-client 2.27.0__tar.gz → 2.28.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-2.27.0/src/deltachat_rpc_client.egg-info → deltachat_rpc_client-2.28.0}/PKG-INFO +1 -1
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/pyproject.toml +1 -1
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client/account.py +4 -0
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client/pytestplugin.py +8 -2
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0/src/deltachat_rpc_client.egg-info}/PKG-INFO +1 -1
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client.egg-info/SOURCES.txt +1 -0
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/tests/test_folders.py +1 -1
- deltachat_rpc_client-2.28.0/tests/test_multitransport.py +158 -0
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/tests/test_securejoin.py +8 -8
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/tests/test_something.py +7 -6
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/LICENSE +0 -0
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/README.md +0 -0
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/setup.cfg +0 -0
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client/__init__.py +0 -0
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client/_utils.py +0 -0
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client/chat.py +0 -0
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client/client.py +0 -0
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client/const.py +0 -0
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client/contact.py +0 -0
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client/deltachat.py +0 -0
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client/events.py +0 -0
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client/message.py +0 -0
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client/py.typed +0 -0
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client/rpc.py +0 -0
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client.egg-info/dependency_links.txt +0 -0
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client.egg-info/entry_points.txt +0 -0
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client.egg-info/top_level.txt +0 -0
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/tests/test_account_events.py +0 -0
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/tests/test_calls.py +0 -0
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/tests/test_chatlist_events.py +0 -0
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/tests/test_iroh_webxdc.py +0 -0
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/tests/test_key_transfer.py +0 -0
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/tests/test_multidevice.py +0 -0
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/tests/test_vcard.py +0 -0
- {deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/tests/test_webxdc.py +0 -0
{deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client/account.py
RENAMED
|
@@ -130,6 +130,10 @@ class Account:
|
|
|
130
130
|
"""Add a new transport using a QR code."""
|
|
131
131
|
yield self._rpc.add_transport_from_qr.future(self.id, qr)
|
|
132
132
|
|
|
133
|
+
def delete_transport(self, addr: str):
|
|
134
|
+
"""Delete a transport."""
|
|
135
|
+
self._rpc.delete_transport(self.id, addr)
|
|
136
|
+
|
|
133
137
|
@futuremethod
|
|
134
138
|
def list_transports(self):
|
|
135
139
|
"""Return the list of all email accounts that are used as a transport in the current profile."""
|
{deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client/pytestplugin.py
RENAMED
|
@@ -40,12 +40,17 @@ class ACFactory:
|
|
|
40
40
|
username = "ci-" + "".join(random.choice("2345789acdefghjkmnpqrstuvwxyz") for i in range(6))
|
|
41
41
|
return f"{username}@{domain}", f"{username}${username}"
|
|
42
42
|
|
|
43
|
+
def get_account_qr(self):
|
|
44
|
+
"""Return "dcaccount:" QR code for testing chatmail relay."""
|
|
45
|
+
domain = os.getenv("CHATMAIL_DOMAIN")
|
|
46
|
+
return f"dcaccount:{domain}"
|
|
47
|
+
|
|
43
48
|
@futuremethod
|
|
44
49
|
def new_configured_account(self):
|
|
45
50
|
"""Create a new configured account."""
|
|
46
51
|
account = self.get_unconfigured_account()
|
|
47
|
-
|
|
48
|
-
yield account.add_transport_from_qr.future(
|
|
52
|
+
qr = self.get_account_qr()
|
|
53
|
+
yield account.add_transport_from_qr.future(qr)
|
|
49
54
|
|
|
50
55
|
assert account.is_configured()
|
|
51
56
|
return account
|
|
@@ -77,6 +82,7 @@ class ACFactory:
|
|
|
77
82
|
ac_clone = self.get_unconfigured_account()
|
|
78
83
|
for transport in transports:
|
|
79
84
|
ac_clone.add_or_update_transport(transport)
|
|
85
|
+
ac_clone.bring_online()
|
|
80
86
|
return ac_clone
|
|
81
87
|
|
|
82
88
|
def get_accepted_chat(self, ac1: Account, ac2: Account) -> Chat:
|
|
@@ -143,7 +143,7 @@ def test_delete_deltachat_folder(acfactory, direct_imap):
|
|
|
143
143
|
# Wait until new folder is created and UIDVALIDITY is updated.
|
|
144
144
|
while True:
|
|
145
145
|
event = ac1.wait_for_event()
|
|
146
|
-
if event.kind == EventType.INFO and "
|
|
146
|
+
if event.kind == EventType.INFO and "transport 1: UID validity for folder DeltaChat changed from " in event.msg:
|
|
147
147
|
break
|
|
148
148
|
|
|
149
149
|
ac2 = acfactory.get_online_account()
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from deltachat_rpc_client.rpc import JsonRpcError
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_add_second_address(acfactory) -> None:
|
|
7
|
+
account = acfactory.new_configured_account()
|
|
8
|
+
assert len(account.list_transports()) == 1
|
|
9
|
+
|
|
10
|
+
# When the first transport is created,
|
|
11
|
+
# mvbox_move and only_fetch_mvbox should be disabled.
|
|
12
|
+
assert account.get_config("mvbox_move") == "0"
|
|
13
|
+
assert account.get_config("only_fetch_mvbox") == "0"
|
|
14
|
+
assert account.get_config("show_emails") == "2"
|
|
15
|
+
|
|
16
|
+
qr = acfactory.get_account_qr()
|
|
17
|
+
account.add_transport_from_qr(qr)
|
|
18
|
+
assert len(account.list_transports()) == 2
|
|
19
|
+
|
|
20
|
+
account.add_transport_from_qr(qr)
|
|
21
|
+
assert len(account.list_transports()) == 3
|
|
22
|
+
|
|
23
|
+
first_addr = account.list_transports()[0]["addr"]
|
|
24
|
+
second_addr = account.list_transports()[1]["addr"]
|
|
25
|
+
|
|
26
|
+
# Cannot delete the first address.
|
|
27
|
+
with pytest.raises(JsonRpcError):
|
|
28
|
+
account.delete_transport(first_addr)
|
|
29
|
+
|
|
30
|
+
account.delete_transport(second_addr)
|
|
31
|
+
assert len(account.list_transports()) == 2
|
|
32
|
+
|
|
33
|
+
# Enabling mvbox_move or only_fetch_mvbox
|
|
34
|
+
# is not allowed when multi-transport is enabled.
|
|
35
|
+
for option in ["mvbox_move", "only_fetch_mvbox"]:
|
|
36
|
+
with pytest.raises(JsonRpcError):
|
|
37
|
+
account.set_config(option, "1")
|
|
38
|
+
|
|
39
|
+
with pytest.raises(JsonRpcError):
|
|
40
|
+
account.set_config("show_emails", "0")
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@pytest.mark.parametrize("key", ["mvbox_move", "only_fetch_mvbox"])
|
|
44
|
+
def test_no_second_transport_with_mvbox(acfactory, key) -> None:
|
|
45
|
+
"""Test that second transport cannot be configured if mvbox is used."""
|
|
46
|
+
account = acfactory.new_configured_account()
|
|
47
|
+
assert len(account.list_transports()) == 1
|
|
48
|
+
|
|
49
|
+
assert account.get_config("mvbox_move") == "0"
|
|
50
|
+
assert account.get_config("only_fetch_mvbox") == "0"
|
|
51
|
+
|
|
52
|
+
qr = acfactory.get_account_qr()
|
|
53
|
+
account.set_config(key, "1")
|
|
54
|
+
|
|
55
|
+
with pytest.raises(JsonRpcError):
|
|
56
|
+
account.add_transport_from_qr(qr)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def test_no_second_transport_without_classic_emails(acfactory) -> None:
|
|
60
|
+
"""Test that second transport cannot be configured if classic emails are not fetched."""
|
|
61
|
+
account = acfactory.new_configured_account()
|
|
62
|
+
assert len(account.list_transports()) == 1
|
|
63
|
+
|
|
64
|
+
assert account.get_config("show_emails") == "2"
|
|
65
|
+
|
|
66
|
+
qr = acfactory.get_account_qr()
|
|
67
|
+
account.set_config("show_emails", "0")
|
|
68
|
+
|
|
69
|
+
with pytest.raises(JsonRpcError):
|
|
70
|
+
account.add_transport_from_qr(qr)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def test_change_address(acfactory) -> None:
|
|
74
|
+
"""Test Alice configuring a second transport and setting it as a primary one."""
|
|
75
|
+
alice, bob = acfactory.get_online_accounts(2)
|
|
76
|
+
|
|
77
|
+
bob_addr = bob.get_config("configured_addr")
|
|
78
|
+
bob.create_chat(alice)
|
|
79
|
+
|
|
80
|
+
alice_chat_bob = alice.create_chat(bob)
|
|
81
|
+
alice_chat_bob.send_text("Hello!")
|
|
82
|
+
|
|
83
|
+
msg1 = bob.wait_for_incoming_msg().get_snapshot()
|
|
84
|
+
sender_addr1 = msg1.sender.get_snapshot().address
|
|
85
|
+
|
|
86
|
+
alice.stop_io()
|
|
87
|
+
old_alice_addr = alice.get_config("configured_addr")
|
|
88
|
+
alice_vcard = alice.self_contact.make_vcard()
|
|
89
|
+
assert old_alice_addr in alice_vcard
|
|
90
|
+
qr = acfactory.get_account_qr()
|
|
91
|
+
alice.add_transport_from_qr(qr)
|
|
92
|
+
new_alice_addr = alice.list_transports()[1]["addr"]
|
|
93
|
+
with pytest.raises(JsonRpcError):
|
|
94
|
+
# Cannot use the address that is not
|
|
95
|
+
# configured for any transport.
|
|
96
|
+
alice.set_config("configured_addr", bob_addr)
|
|
97
|
+
|
|
98
|
+
# Load old address so it is cached.
|
|
99
|
+
assert alice.get_config("configured_addr") == old_alice_addr
|
|
100
|
+
alice.set_config("configured_addr", new_alice_addr)
|
|
101
|
+
# Make sure that setting `configured_addr` invalidated the cache.
|
|
102
|
+
assert alice.get_config("configured_addr") == new_alice_addr
|
|
103
|
+
|
|
104
|
+
alice_vcard = alice.self_contact.make_vcard()
|
|
105
|
+
assert old_alice_addr not in alice_vcard
|
|
106
|
+
assert new_alice_addr in alice_vcard
|
|
107
|
+
with pytest.raises(JsonRpcError):
|
|
108
|
+
alice.delete_transport(new_alice_addr)
|
|
109
|
+
alice.start_io()
|
|
110
|
+
|
|
111
|
+
alice_chat_bob.send_text("Hello again!")
|
|
112
|
+
|
|
113
|
+
msg2 = bob.wait_for_incoming_msg().get_snapshot()
|
|
114
|
+
sender_addr2 = msg2.sender.get_snapshot().address
|
|
115
|
+
|
|
116
|
+
assert msg1.sender == msg2.sender
|
|
117
|
+
assert sender_addr1 != sender_addr2
|
|
118
|
+
assert sender_addr1 == old_alice_addr
|
|
119
|
+
assert sender_addr2 == new_alice_addr
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
@pytest.mark.parametrize("is_chatmail", ["0", "1"])
|
|
123
|
+
def test_mvbox_move_first_transport(acfactory, is_chatmail) -> None:
|
|
124
|
+
"""Test that mvbox_move is disabled by default even for non-chatmail accounts.
|
|
125
|
+
Disabling mvbox_move is required to be able to setup a second transport.
|
|
126
|
+
"""
|
|
127
|
+
account = acfactory.get_unconfigured_account()
|
|
128
|
+
|
|
129
|
+
account.set_config("fix_is_chatmail", "1")
|
|
130
|
+
account.set_config("is_chatmail", is_chatmail)
|
|
131
|
+
|
|
132
|
+
# The default value when the setting is unset is "1".
|
|
133
|
+
# This is not changed for compatibility with old databases
|
|
134
|
+
# imported from backups.
|
|
135
|
+
assert account.get_config("mvbox_move") == "1"
|
|
136
|
+
|
|
137
|
+
qr = acfactory.get_account_qr()
|
|
138
|
+
account.add_transport_from_qr(qr)
|
|
139
|
+
|
|
140
|
+
# Once the first transport is set up,
|
|
141
|
+
# mvbox_move is disabled.
|
|
142
|
+
assert account.get_config("mvbox_move") == "0"
|
|
143
|
+
assert account.get_config("is_chatmail") == is_chatmail
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def test_reconfigure_transport(acfactory) -> None:
|
|
147
|
+
"""Test that reconfiguring the transport works
|
|
148
|
+
even if settings not supported for multi-transport
|
|
149
|
+
like mvbox_move are enabled."""
|
|
150
|
+
account = acfactory.get_online_account()
|
|
151
|
+
account.set_config("mvbox_move", "1")
|
|
152
|
+
|
|
153
|
+
[transport] = account.list_transports()
|
|
154
|
+
account.add_or_update_transport(transport)
|
|
155
|
+
|
|
156
|
+
# Reconfiguring the transport should not reset
|
|
157
|
+
# the settings as if when configuring the first transport.
|
|
158
|
+
assert account.get_config("mvbox_move") == "1"
|
|
@@ -158,29 +158,29 @@ def test_qr_securejoin_broadcast(acfactory, all_devices_online):
|
|
|
158
158
|
chat = get_broadcast(ac)
|
|
159
159
|
chat_msgs = chat.get_messages()
|
|
160
160
|
|
|
161
|
+
encrypted_msg = chat_msgs.pop(0).get_snapshot()
|
|
162
|
+
assert encrypted_msg.text == "Messages are end-to-end encrypted."
|
|
163
|
+
assert encrypted_msg.is_info
|
|
164
|
+
|
|
161
165
|
if please_wait_info_msg:
|
|
162
166
|
first_msg = chat_msgs.pop(0).get_snapshot()
|
|
163
|
-
assert
|
|
167
|
+
assert "invited you to join this channel" in first_msg.text
|
|
164
168
|
assert first_msg.is_info
|
|
165
169
|
|
|
166
|
-
|
|
167
|
-
assert encrypted_msg.text == "Messages are end-to-end encrypted."
|
|
168
|
-
assert encrypted_msg.is_info
|
|
169
|
-
|
|
170
|
-
member_added_msg = chat_msgs[1].get_snapshot()
|
|
170
|
+
member_added_msg = chat_msgs.pop(0).get_snapshot()
|
|
171
171
|
if inviter_side:
|
|
172
172
|
assert member_added_msg.text == f"Member {contact_snapshot.display_name} added."
|
|
173
173
|
else:
|
|
174
174
|
assert member_added_msg.text == "You joined the channel."
|
|
175
175
|
assert member_added_msg.is_info
|
|
176
176
|
|
|
177
|
-
hello_msg = chat_msgs
|
|
177
|
+
hello_msg = chat_msgs.pop(0).get_snapshot()
|
|
178
178
|
assert hello_msg.text == "Hello everyone!"
|
|
179
179
|
assert not hello_msg.is_info
|
|
180
180
|
assert hello_msg.show_padlock
|
|
181
181
|
assert hello_msg.error is None
|
|
182
182
|
|
|
183
|
-
assert len(chat_msgs) ==
|
|
183
|
+
assert len(chat_msgs) == 0
|
|
184
184
|
|
|
185
185
|
chat_snapshot = chat.get_full_snapshot()
|
|
186
186
|
assert chat_snapshot.is_encrypted
|
|
@@ -467,7 +467,7 @@ def test_bot(acfactory) -> None:
|
|
|
467
467
|
|
|
468
468
|
|
|
469
469
|
def test_wait_next_messages(acfactory) -> None:
|
|
470
|
-
alice = acfactory.
|
|
470
|
+
alice = acfactory.get_online_account()
|
|
471
471
|
|
|
472
472
|
# Create a bot account so it does not receive device messages in the beginning.
|
|
473
473
|
addr, password = acfactory.get_credentials()
|
|
@@ -475,6 +475,7 @@ def test_wait_next_messages(acfactory) -> None:
|
|
|
475
475
|
bot.set_config("bot", "1")
|
|
476
476
|
bot.add_or_update_transport({"addr": addr, "password": password})
|
|
477
477
|
assert bot.is_configured()
|
|
478
|
+
bot.bring_online()
|
|
478
479
|
|
|
479
480
|
# There are no old messages and the call returns immediately.
|
|
480
481
|
assert not bot.wait_next_messages()
|
|
@@ -867,15 +868,15 @@ def test_leave_broadcast(acfactory, all_devices_online):
|
|
|
867
868
|
contact_snapshot = contact.get_snapshot()
|
|
868
869
|
chat_msgs = chat.get_messages()
|
|
869
870
|
|
|
870
|
-
if please_wait_info_msg:
|
|
871
|
-
first_msg = chat_msgs.pop(0).get_snapshot()
|
|
872
|
-
assert first_msg.text == "Establishing guaranteed end-to-end encryption, please wait…"
|
|
873
|
-
assert first_msg.is_info
|
|
874
|
-
|
|
875
871
|
encrypted_msg = chat_msgs.pop(0).get_snapshot()
|
|
876
872
|
assert encrypted_msg.text == "Messages are end-to-end encrypted."
|
|
877
873
|
assert encrypted_msg.is_info
|
|
878
874
|
|
|
875
|
+
if please_wait_info_msg:
|
|
876
|
+
first_msg = chat_msgs.pop(0).get_snapshot()
|
|
877
|
+
assert "invited you to join this channel" in first_msg.text
|
|
878
|
+
assert first_msg.is_info
|
|
879
|
+
|
|
879
880
|
member_added_msg = chat_msgs.pop(0).get_snapshot()
|
|
880
881
|
if inviter_side:
|
|
881
882
|
assert member_added_msg.text == f"Member {contact_snapshot.display_name} added."
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client/__init__.py
RENAMED
|
File without changes
|
{deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client/_utils.py
RENAMED
|
File without changes
|
{deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client/chat.py
RENAMED
|
File without changes
|
{deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client/client.py
RENAMED
|
File without changes
|
{deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client/const.py
RENAMED
|
File without changes
|
{deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client/contact.py
RENAMED
|
File without changes
|
{deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client/deltachat.py
RENAMED
|
File without changes
|
{deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client/events.py
RENAMED
|
File without changes
|
{deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client/message.py
RENAMED
|
File without changes
|
{deltachat_rpc_client-2.27.0 → deltachat_rpc_client-2.28.0}/src/deltachat_rpc_client/py.typed
RENAMED
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|