deltachat-rpc-client 2.33.0__tar.gz → 2.35.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.
Files changed (36) hide show
  1. {deltachat_rpc_client-2.33.0/src/deltachat_rpc_client.egg-info → deltachat_rpc_client-2.35.0}/PKG-INFO +1 -1
  2. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/pyproject.toml +1 -1
  3. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/src/deltachat_rpc_client/chat.py +12 -4
  4. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0/src/deltachat_rpc_client.egg-info}/PKG-INFO +1 -1
  5. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/tests/test_cross_core.py +13 -0
  6. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/tests/test_multitransport.py +59 -0
  7. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/tests/test_something.py +49 -8
  8. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/LICENSE +0 -0
  9. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/README.md +0 -0
  10. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/setup.cfg +0 -0
  11. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/src/deltachat_rpc_client/__init__.py +0 -0
  12. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/src/deltachat_rpc_client/_utils.py +0 -0
  13. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/src/deltachat_rpc_client/account.py +0 -0
  14. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/src/deltachat_rpc_client/client.py +0 -0
  15. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/src/deltachat_rpc_client/const.py +0 -0
  16. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/src/deltachat_rpc_client/contact.py +0 -0
  17. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/src/deltachat_rpc_client/deltachat.py +0 -0
  18. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/src/deltachat_rpc_client/events.py +0 -0
  19. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/src/deltachat_rpc_client/message.py +0 -0
  20. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/src/deltachat_rpc_client/py.typed +0 -0
  21. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/src/deltachat_rpc_client/pytestplugin.py +0 -0
  22. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/src/deltachat_rpc_client/rpc.py +0 -0
  23. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/src/deltachat_rpc_client.egg-info/SOURCES.txt +0 -0
  24. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/src/deltachat_rpc_client.egg-info/dependency_links.txt +0 -0
  25. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/src/deltachat_rpc_client.egg-info/entry_points.txt +0 -0
  26. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/src/deltachat_rpc_client.egg-info/top_level.txt +0 -0
  27. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/tests/test_account_events.py +0 -0
  28. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/tests/test_calls.py +0 -0
  29. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/tests/test_chatlist_events.py +0 -0
  30. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/tests/test_folders.py +0 -0
  31. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/tests/test_iroh_webxdc.py +0 -0
  32. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/tests/test_key_transfer.py +0 -0
  33. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/tests/test_multidevice.py +0 -0
  34. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/tests/test_securejoin.py +0 -0
  35. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/tests/test_vcard.py +0 -0
  36. {deltachat_rpc_client-2.33.0 → deltachat_rpc_client-2.35.0}/tests/test_webxdc.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deltachat-rpc-client
3
- Version: 2.33.0
3
+ Version: 2.35.0
4
4
  Summary: Python client for Delta Chat core JSON-RPC interface
5
5
  License-Expression: MPL-2.0
6
6
  Classifier: Development Status :: 5 - Production/Stable
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "deltachat-rpc-client"
7
- version = "2.33.0"
7
+ version = "2.35.0"
8
8
  license = "MPL-2.0"
9
9
  description = "Python client for Delta Chat core JSON-RPC interface"
10
10
  classifiers = [
@@ -219,10 +219,12 @@ class Chat:
219
219
  """Mark all messages in this chat as noticed."""
220
220
  self._rpc.marknoticed_chat(self.account.id, self.id)
221
221
 
222
- def add_contact(self, *contact: Union[int, str, Contact]) -> None:
222
+ def add_contact(self, *contact: Union[int, str, Contact, "Account"]) -> None:
223
223
  """Add contacts to this group."""
224
+ from .account import Account
225
+
224
226
  for cnt in contact:
225
- if isinstance(cnt, str):
227
+ if isinstance(cnt, (str, Account)):
226
228
  contact_id = self.account.create_contact(cnt).id
227
229
  elif not isinstance(cnt, int):
228
230
  contact_id = cnt.id
@@ -230,10 +232,12 @@ class Chat:
230
232
  contact_id = cnt
231
233
  self._rpc.add_contact_to_chat(self.account.id, self.id, contact_id)
232
234
 
233
- def remove_contact(self, *contact: Union[int, str, Contact]) -> None:
235
+ def remove_contact(self, *contact: Union[int, str, Contact, "Account"]) -> None:
234
236
  """Remove members from this group."""
237
+ from .account import Account
238
+
235
239
  for cnt in contact:
236
- if isinstance(cnt, str):
240
+ if isinstance(cnt, (str, Account)):
237
241
  contact_id = self.account.create_contact(cnt).id
238
242
  elif not isinstance(cnt, int):
239
243
  contact_id = cnt.id
@@ -249,6 +253,10 @@ class Chat:
249
253
  contacts = self._rpc.get_chat_contacts(self.account.id, self.id)
250
254
  return [Contact(self.account, contact_id) for contact_id in contacts]
251
255
 
256
+ def num_contacts(self) -> int:
257
+ """Return number of contacts in this chat."""
258
+ return len(self.get_contacts())
259
+
252
260
  def get_past_contacts(self) -> list[Contact]:
253
261
  """Get past contacts for this chat."""
254
262
  past_contacts = self._rpc.get_past_chat_contacts(self.account.id, self.id)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deltachat-rpc-client
3
- Version: 2.33.0
3
+ Version: 2.35.0
4
4
  Summary: Python client for Delta Chat core JSON-RPC interface
5
5
  License-Expression: MPL-2.0
6
6
  Classifier: Development Status :: 5 - Production/Stable
@@ -42,3 +42,16 @@ def test_send_and_receive_message(alice_and_remote_bob) -> None:
42
42
 
43
43
  msg = alice.wait_for_incoming_msg()
44
44
  assert msg.get_snapshot().text == "hello"
45
+
46
+
47
+ def test_second_device(acfactory, alice_and_remote_bob) -> None:
48
+ """Test setting up current version as a second device for old version."""
49
+ _alice, alice_contact_bob, remote_eval = alice_and_remote_bob("2.20.0")
50
+
51
+ remote_eval("locals().setdefault('future', bob._rpc.provide_backup.future(bob.id))")
52
+ qr = remote_eval("bob._rpc.get_backup_qr(bob.id)")
53
+ new_account = acfactory.get_unconfigured_account()
54
+ new_account._rpc.get_backup(new_account.id, qr)
55
+ remote_eval("locals()['future']()")
56
+
57
+ assert new_account.get_config("addr") == remote_eval("bob.get_config('addr')")
@@ -188,6 +188,10 @@ def test_transport_synchronization(acfactory, log) -> None:
188
188
  log.section("ac1 changes the primary transport")
189
189
  ac1.set_config("configured_addr", transport3["addr"])
190
190
 
191
+ ac1_clone.wait_for_event(EventType.TRANSPORTS_MODIFIED)
192
+ [transport1, transport3] = ac1_clone.list_transports()
193
+ assert ac1_clone.get_config("configured_addr") == addr3
194
+
191
195
  log.section("ac1 removes the first transport")
192
196
  ac1.delete_transport(transport1["addr"])
193
197
 
@@ -217,3 +221,58 @@ def test_recognize_self_address(acfactory) -> None:
217
221
  bob_chat.send_text("Hello!")
218
222
  msg = alice.wait_for_incoming_msg().get_snapshot()
219
223
  assert msg.chat == alice.create_chat(bob)
224
+
225
+
226
+ def test_transport_limit(acfactory) -> None:
227
+ """Test transports limit."""
228
+ account = acfactory.get_online_account()
229
+ qr = acfactory.get_account_qr()
230
+
231
+ limit = 5
232
+
233
+ for _ in range(1, limit):
234
+ account.add_transport_from_qr(qr)
235
+
236
+ assert len(account.list_transports()) == limit
237
+
238
+ with pytest.raises(JsonRpcError):
239
+ account.add_transport_from_qr(qr)
240
+
241
+ second_addr = account.list_transports()[1]["addr"]
242
+ account.delete_transport(second_addr)
243
+
244
+ # test that adding a transport after deleting one works again
245
+ account.add_transport_from_qr(qr)
246
+
247
+
248
+ def test_message_info_imap_urls(acfactory, log) -> None:
249
+ """Test that message info contains IMAP URLs of where the message was received."""
250
+ alice, bob = acfactory.get_online_accounts(2)
251
+
252
+ log.section("Alice adds ac1 clone removes second transport")
253
+ qr = acfactory.get_account_qr()
254
+ for i in range(3):
255
+ alice.add_transport_from_qr(qr)
256
+ # Wait for all transports to go IDLE after adding each one.
257
+ for _ in range(i + 1):
258
+ alice.bring_online()
259
+
260
+ new_alice_addr = alice.list_transports()[2]["addr"]
261
+ alice.set_config("configured_addr", new_alice_addr)
262
+
263
+ # Enable multi-device mode so messages are not deleted immediately.
264
+ alice.set_config("bcc_self", "1")
265
+
266
+ # Bob creates chat, learning about Alice's currently selected transport.
267
+ # This is where he will send the message.
268
+ bob_chat = bob.create_chat(alice)
269
+
270
+ # Alice changes the transport again.
271
+ alice.set_config("configured_addr", alice.list_transports()[3]["addr"])
272
+
273
+ bob_chat.send_text("Hello!")
274
+
275
+ msg = alice.wait_for_incoming_msg()
276
+ for alice_transport in alice.list_transports():
277
+ addr = alice_transport["addr"]
278
+ assert (addr == new_alice_addr) == (addr in msg.get_info())
@@ -90,12 +90,9 @@ def test_lowercase_address(acfactory) -> None:
90
90
  assert account.get_config("configured_addr") == addr
91
91
  assert account.list_transports()[0]["addr"] == addr
92
92
 
93
- for param in [
94
- account.get_info()["used_account_settings"],
95
- account.get_info()["entered_account_settings"],
96
- ]:
97
- assert addr in param
98
- assert addr_upper not in param
93
+ param = account.get_info()["used_transport_settings"]
94
+ assert addr in param
95
+ assert addr_upper not in param
99
96
 
100
97
 
101
98
  def test_configure_ip(acfactory) -> None:
@@ -733,7 +730,7 @@ def test_configured_imap_certificate_checks(acfactory):
733
730
  alice = acfactory.new_configured_account()
734
731
 
735
732
  # Certificate checks should be configured (not None)
736
- assert "cert_strict" in alice.get_info().used_account_settings
733
+ assert "cert_strict" in alice.get_info().used_transport_settings
737
734
 
738
735
  # "cert_old_automatic" is the value old Delta Chat core versions used
739
736
  # to mean user entered "imap_certificate_checks=0" (Automatic)
@@ -746,7 +743,7 @@ def test_configured_imap_certificate_checks(acfactory):
746
743
  #
747
744
  # Core 1.142.4, 1.142.5 and 1.142.6 saved this value due to bug.
748
745
  # This test is a regression test to prevent this happening again.
749
- assert "cert_old_automatic" not in alice.get_info().used_account_settings
746
+ assert "cert_old_automatic" not in alice.get_info().used_transport_settings
750
747
 
751
748
 
752
749
  def test_no_old_msg_is_fresh(acfactory):
@@ -1012,3 +1009,47 @@ def test_message_exists(acfactory):
1012
1009
  ac1.remove()
1013
1010
  assert not message1.exists()
1014
1011
  assert not message2.exists()
1012
+
1013
+
1014
+ def test_synchronize_member_list_on_group_rejoin(acfactory, log):
1015
+ """
1016
+ Test that user recreates group member list when it joins the group again.
1017
+ ac1 creates a group with two other accounts: ac2 and ac3
1018
+ Then it removes ac2, removes ac3 and adds ac2 back.
1019
+ ac2 did not see that ac3 is removed, so it should rebuild member list from scratch.
1020
+ """
1021
+ log.section("setting up accounts, accepted with each other")
1022
+ ac1, ac2, ac3 = accounts = acfactory.get_online_accounts(3)
1023
+
1024
+ log.section("ac1: creating group chat with 2 other members")
1025
+ chat = ac1.create_group("title1")
1026
+ chat.add_contact(ac2)
1027
+ chat.add_contact(ac3)
1028
+
1029
+ log.section("ac1: send message to new group chat")
1030
+ msg = chat.send_text("hello")
1031
+ assert chat.num_contacts() == 3
1032
+
1033
+ log.section("checking that the chat arrived correctly")
1034
+ for ac in accounts[1:]:
1035
+ msg = ac.wait_for_incoming_msg().get_snapshot()
1036
+ assert msg.text == "hello"
1037
+ assert msg.chat.num_contacts() == 3
1038
+ msg.chat.accept()
1039
+
1040
+ log.section("ac1: removing ac2")
1041
+ chat.remove_contact(ac2)
1042
+
1043
+ log.section("ac2: wait for a message about removal from the chat")
1044
+ ac2.wait_for_incoming_msg()
1045
+ log.section("ac1: removing ac3")
1046
+ chat.remove_contact(ac3)
1047
+
1048
+ log.section("ac1: adding ac2 back")
1049
+ chat.add_contact(ac2)
1050
+
1051
+ log.section("ac2: check that ac3 is removed")
1052
+ msg = ac2.wait_for_incoming_msg()
1053
+
1054
+ assert chat.num_contacts() == 2
1055
+ assert msg.get_snapshot().chat.num_contacts() == 2