deltachat-rpc-client 2.38.0__tar.gz → 2.40.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.38.0/src/deltachat_rpc_client.egg-info → deltachat_rpc_client-2.40.0}/PKG-INFO +1 -1
  2. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/pyproject.toml +1 -1
  3. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/src/deltachat_rpc_client/chat.py +2 -2
  4. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/src/deltachat_rpc_client/client.py +1 -1
  5. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/src/deltachat_rpc_client/pytestplugin.py +1 -1
  6. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0/src/deltachat_rpc_client.egg-info}/PKG-INFO +1 -1
  7. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/tests/test_calls.py +24 -32
  8. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/tests/test_folders.py +17 -68
  9. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/tests/test_multitransport.py +10 -1
  10. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/tests/test_something.py +15 -7
  11. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/LICENSE +0 -0
  12. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/README.md +0 -0
  13. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/setup.cfg +0 -0
  14. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/src/deltachat_rpc_client/__init__.py +0 -0
  15. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/src/deltachat_rpc_client/_utils.py +0 -0
  16. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/src/deltachat_rpc_client/account.py +0 -0
  17. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/src/deltachat_rpc_client/const.py +0 -0
  18. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/src/deltachat_rpc_client/contact.py +0 -0
  19. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/src/deltachat_rpc_client/deltachat.py +0 -0
  20. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/src/deltachat_rpc_client/events.py +0 -0
  21. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/src/deltachat_rpc_client/message.py +0 -0
  22. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/src/deltachat_rpc_client/py.typed +0 -0
  23. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/src/deltachat_rpc_client/rpc.py +0 -0
  24. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/src/deltachat_rpc_client.egg-info/SOURCES.txt +0 -0
  25. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/src/deltachat_rpc_client.egg-info/dependency_links.txt +0 -0
  26. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/src/deltachat_rpc_client.egg-info/entry_points.txt +0 -0
  27. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/src/deltachat_rpc_client.egg-info/top_level.txt +0 -0
  28. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/tests/test_account_events.py +0 -0
  29. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/tests/test_chatlist_events.py +0 -0
  30. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/tests/test_cross_core.py +0 -0
  31. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/tests/test_iroh_webxdc.py +0 -0
  32. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/tests/test_key_transfer.py +0 -0
  33. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/tests/test_multidevice.py +0 -0
  34. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/tests/test_securejoin.py +0 -0
  35. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.0}/tests/test_vcard.py +0 -0
  36. {deltachat_rpc_client-2.38.0 → deltachat_rpc_client-2.40.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.38.0
3
+ Version: 2.40.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.38.0"
7
+ version = "2.40.0"
8
8
  license = "MPL-2.0"
9
9
  description = "Python client for Delta Chat core JSON-RPC interface"
10
10
  classifiers = [
@@ -303,7 +303,7 @@ class Chat:
303
303
  f.flush()
304
304
  self._rpc.send_msg(self.account.id, self.id, {"viewtype": ViewType.VCARD, "file": f.name})
305
305
 
306
- def place_outgoing_call(self, place_call_info: str) -> Message:
306
+ def place_outgoing_call(self, place_call_info: str, has_video_initially: bool) -> Message:
307
307
  """Starts an outgoing call."""
308
- msg_id = self._rpc.place_outgoing_call(self.account.id, self.id, place_call_info)
308
+ msg_id = self._rpc.place_outgoing_call(self.account.id, self.id, place_call_info, has_video_initially)
309
309
  return Message(self.account, msg_id)
@@ -104,7 +104,7 @@ class Client:
104
104
 
105
105
  def _process_events(
106
106
  self,
107
- until_func: Callable[[AttrDict], bool],
107
+ until_func: Callable[[AttrDict], bool] = _forever,
108
108
  until_event: EventType = False,
109
109
  ) -> AttrDict:
110
110
  """Process events until the given callable evaluates to True,
@@ -22,7 +22,7 @@ from .rpc import Rpc
22
22
  E2EE_INFO_MSGS = 1
23
23
  """
24
24
  The number of info messages added to new e2ee chats.
25
- Currently this is "End-to-end encryption available".
25
+ Currently this is "Messages are end-to-end encrypted."
26
26
  """
27
27
 
28
28
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deltachat-rpc-client
3
- Version: 2.38.0
3
+ Version: 2.40.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
@@ -10,15 +10,15 @@ def test_calls(acfactory) -> None:
10
10
  alice_contact_bob = alice.create_contact(bob, "Bob")
11
11
  alice_chat_bob = alice_contact_bob.create_chat()
12
12
  bob.create_chat(alice) # Accept the chat so incoming call causes a notification.
13
- outgoing_call_message = alice_chat_bob.place_outgoing_call(place_call_info)
13
+ outgoing_call_message = alice_chat_bob.place_outgoing_call(place_call_info, has_video_initially=True)
14
14
  assert outgoing_call_message.get_call_info().state.kind == "Alerting"
15
15
 
16
16
  incoming_call_event = bob.wait_for_event(EventType.INCOMING_CALL)
17
17
  assert incoming_call_event.place_call_info == place_call_info
18
- assert not incoming_call_event.has_video # Cannot be parsed as SDP, so false by default
18
+ assert incoming_call_event.has_video
19
19
  incoming_call_message = Message(bob, incoming_call_event.msg_id)
20
20
  assert incoming_call_message.get_call_info().state.kind == "Alerting"
21
- assert not incoming_call_message.get_call_info().has_video
21
+ assert incoming_call_message.get_call_info().has_video
22
22
 
23
23
  incoming_call_message.accept_incoming_call(accept_call_info)
24
24
  assert incoming_call_message.get_call_info().sdp_offer == place_call_info
@@ -41,46 +41,38 @@ def test_video_call(acfactory) -> None:
41
41
  #
42
42
  # `s=` cannot be empty according to RFC 3264,
43
43
  # so it is more clear as `s=-`.
44
- place_call_info = """v=0\r
45
- o=alice 2890844526 2890844526 IN IP6 2001:db8::3\r
46
- s=-\r
47
- c=IN IP6 2001:db8::3\r
48
- t=0 0\r
49
- a=group:BUNDLE foo bar\r
50
- \r
51
- m=audio 10000 RTP/AVP 0 8 97\r
52
- b=AS:200\r
53
- a=mid:foo\r
54
- a=rtcp-mux\r
55
- a=rtpmap:0 PCMU/8000\r
56
- a=rtpmap:8 PCMA/8000\r
57
- a=rtpmap:97 iLBC/8000\r
58
- a=extmap:1 urn:ietf:params:rtp-hdrext:sdes:mid\r
59
- \r
60
- m=video 10002 RTP/AVP 31 32\r
61
- b=AS:1000\r
62
- a=mid:bar\r
63
- a=rtcp-mux\r
64
- a=rtpmap:31 H261/90000\r
65
- a=rtpmap:32 MPV/90000\r
66
- a=extmap:1 urn:ietf:params:rtp-hdrext:sdes:mid\r
67
- """
68
44
 
69
45
  alice, bob = acfactory.get_online_accounts(2)
70
46
 
71
47
  bob.create_chat(alice) # Accept the chat so incoming call causes a notification.
72
48
  alice_contact_bob = alice.create_contact(bob, "Bob")
73
49
  alice_chat_bob = alice_contact_bob.create_chat()
74
- alice_chat_bob.place_outgoing_call(place_call_info)
50
+ alice_chat_bob.place_outgoing_call("offer", has_video_initially=True)
75
51
 
76
52
  incoming_call_event = bob.wait_for_event(EventType.INCOMING_CALL)
77
- assert incoming_call_event.place_call_info == place_call_info
53
+ assert incoming_call_event.place_call_info == "offer"
78
54
  assert incoming_call_event.has_video
79
55
 
80
56
  incoming_call_message = Message(bob, incoming_call_event.msg_id)
81
57
  assert incoming_call_message.get_call_info().has_video
82
58
 
83
59
 
60
+ def test_audio_call(acfactory) -> None:
61
+ alice, bob = acfactory.get_online_accounts(2)
62
+
63
+ bob.create_chat(alice) # Accept the chat so incoming call causes a notification.
64
+ alice_contact_bob = alice.create_contact(bob, "Bob")
65
+ alice_chat_bob = alice_contact_bob.create_chat()
66
+ alice_chat_bob.place_outgoing_call("offer", has_video_initially=False)
67
+
68
+ incoming_call_event = bob.wait_for_event(EventType.INCOMING_CALL)
69
+ assert incoming_call_event.place_call_info == "offer"
70
+ assert not incoming_call_event.has_video
71
+
72
+ incoming_call_message = Message(bob, incoming_call_event.msg_id)
73
+ assert not incoming_call_message.get_call_info().has_video
74
+
75
+
84
76
  def test_ice_servers(acfactory) -> None:
85
77
  alice = acfactory.get_online_account()
86
78
 
@@ -92,7 +84,7 @@ def test_no_contact_request_call(acfactory) -> None:
92
84
  alice, bob = acfactory.get_online_accounts(2)
93
85
 
94
86
  alice_chat_bob = alice.create_chat(bob)
95
- alice_chat_bob.place_outgoing_call("offer")
87
+ alice_chat_bob.place_outgoing_call("offer", has_video_initially=True)
96
88
  alice_chat_bob.send_text("Hello!")
97
89
 
98
90
  # Notification for "Hello!" message should arrive
@@ -119,7 +111,7 @@ def test_who_can_call_me_nobody(acfactory) -> None:
119
111
  bob.create_chat(alice)
120
112
 
121
113
  alice_chat_bob = alice.create_chat(bob)
122
- alice_chat_bob.place_outgoing_call("offer")
114
+ alice_chat_bob.place_outgoing_call("offer", has_video_initially=True)
123
115
  alice_chat_bob.send_text("Hello!")
124
116
 
125
117
  # Notification for "Hello!" message should arrive
@@ -144,7 +136,7 @@ def test_who_can_call_me_everybody(acfactory) -> None:
144
136
  bob.set_config("who_can_call_me", "0")
145
137
 
146
138
  alice_chat_bob = alice.create_chat(bob)
147
- alice_chat_bob.place_outgoing_call("offer")
139
+ alice_chat_bob.place_outgoing_call("offer", has_video_initially=True)
148
140
  incoming_call_event = bob.wait_for_event(EventType.INCOMING_CALL)
149
141
 
150
142
  incoming_call_message = Message(bob, incoming_call_event.msg_id)
@@ -8,8 +8,10 @@ from imap_tools import AND, U
8
8
  from deltachat_rpc_client import Contact, EventType, Message
9
9
 
10
10
 
11
- def test_move_works(acfactory):
11
+ def test_move_works(acfactory, direct_imap):
12
12
  ac1, ac2 = acfactory.get_online_accounts(2)
13
+ ac2_direct_imap = direct_imap(ac2)
14
+ ac2_direct_imap.create_folder("DeltaChat")
13
15
  ac2.set_config("mvbox_move", "1")
14
16
  ac2.bring_online()
15
17
 
@@ -34,6 +36,8 @@ def test_move_avoids_loop(acfactory, direct_imap):
34
36
  We do not want to move this message from `INBOX.DeltaChat` to `DeltaChat` again.
35
37
  """
36
38
  ac1, ac2 = acfactory.get_online_accounts(2)
39
+ ac2_direct_imap = direct_imap(ac2)
40
+ ac2_direct_imap.create_folder("DeltaChat")
37
41
  ac2.set_config("mvbox_move", "1")
38
42
  ac2.set_config("delete_server_after", "0")
39
43
  ac2.bring_online()
@@ -97,6 +101,8 @@ def test_reactions_for_a_reordering_move(acfactory, direct_imap):
97
101
  addr, password = acfactory.get_credentials()
98
102
  ac2 = acfactory.get_unconfigured_account()
99
103
  ac2.add_or_update_transport({"addr": addr, "password": password})
104
+ ac2_direct_imap = direct_imap(ac2)
105
+ ac2_direct_imap.create_folder("DeltaChat")
100
106
  ac2.set_config("mvbox_move", "1")
101
107
  assert ac2.is_configured()
102
108
 
@@ -130,30 +136,6 @@ def test_reactions_for_a_reordering_move(acfactory, direct_imap):
130
136
  assert list(reactions.reactions_by_contact.values())[0] == [react_str]
131
137
 
132
138
 
133
- def test_delete_deltachat_folder(acfactory, direct_imap):
134
- """Test that DeltaChat folder is recreated if user deletes it manually."""
135
- ac1 = acfactory.new_configured_account()
136
- ac1.set_config("mvbox_move", "1")
137
- ac1.bring_online()
138
-
139
- ac1_direct_imap = direct_imap(ac1)
140
- ac1_direct_imap.conn.folder.delete("DeltaChat")
141
- assert "DeltaChat" not in ac1_direct_imap.list_folders()
142
-
143
- # Wait until new folder is created and UIDVALIDITY is updated.
144
- while True:
145
- event = ac1.wait_for_event()
146
- if event.kind == EventType.INFO and "transport 1: UID validity for folder DeltaChat changed from " in event.msg:
147
- break
148
-
149
- ac2 = acfactory.get_online_account()
150
- ac2.create_chat(ac1).send_text("hello")
151
- msg = ac1.wait_for_incoming_msg().get_snapshot()
152
- assert msg.text == "hello"
153
-
154
- assert "DeltaChat" in ac1_direct_imap.list_folders()
155
-
156
-
157
139
  def test_dont_show_emails(acfactory, direct_imap, log):
158
140
  """Most mailboxes have a "Drafts" folder where constantly new emails appear but we don't actually want to show them.
159
141
  So: If it's outgoing AND there is no Received header, then ignore the email.
@@ -294,10 +276,12 @@ def test_dont_show_emails(acfactory, direct_imap, log):
294
276
  assert len(msg.chat.get_messages()) == 2
295
277
 
296
278
 
297
- def test_move_works_on_self_sent(acfactory):
279
+ def test_move_works_on_self_sent(acfactory, direct_imap):
298
280
  ac1, ac2 = acfactory.get_online_accounts(2)
299
281
 
300
- # Enable movebox and wait until it is created.
282
+ # Create and enable movebox.
283
+ ac1_direct_imap = direct_imap(ac1)
284
+ ac1_direct_imap.create_folder("DeltaChat")
301
285
  ac1.set_config("mvbox_move", "1")
302
286
  ac1.set_config("bcc_self", "1")
303
287
  ac1.bring_online()
@@ -314,6 +298,8 @@ def test_move_works_on_self_sent(acfactory):
314
298
  def test_moved_markseen(acfactory, direct_imap):
315
299
  """Test that message already moved to DeltaChat folder is marked as seen."""
316
300
  ac1, ac2 = acfactory.get_online_accounts(2)
301
+ ac2_direct_imap = direct_imap(ac2)
302
+ ac2_direct_imap.create_folder("DeltaChat")
317
303
  ac2.set_config("mvbox_move", "1")
318
304
  ac2.set_config("delete_server_after", "0")
319
305
  ac2.set_config("sync_msgs", "0") # Do not send a sync message when accepting a contact request.
@@ -356,6 +342,8 @@ def test_markseen_message_and_mdn(acfactory, direct_imap, mvbox_move):
356
342
  for ac in ac1, ac2:
357
343
  ac.set_config("delete_server_after", "0")
358
344
  if mvbox_move:
345
+ ac_direct_imap = direct_imap(ac)
346
+ ac_direct_imap.create_folder("DeltaChat")
359
347
  ac.set_config("mvbox_move", "1")
360
348
  ac.bring_online()
361
349
 
@@ -390,31 +378,6 @@ def test_markseen_message_and_mdn(acfactory, direct_imap, mvbox_move):
390
378
  assert len(list(ac2_direct_imap.conn.fetch(AND(seen=True), mark_seen=False))) == 1
391
379
 
392
380
 
393
- def test_mvbox_and_trash(acfactory, direct_imap, log):
394
- log.section("ac1: start with mvbox")
395
- ac1 = acfactory.get_online_account()
396
- ac1.set_config("mvbox_move", "1")
397
- ac1.bring_online()
398
-
399
- log.section("ac2: start without a mvbox")
400
- ac2 = acfactory.get_online_account()
401
-
402
- log.section("ac1: create trash")
403
- ac1_direct_imap = direct_imap(ac1)
404
- ac1_direct_imap.create_folder("Trash")
405
- ac1.set_config("scan_all_folders_debounce_secs", "0")
406
- ac1.stop_io()
407
- ac1.start_io()
408
-
409
- log.section("ac1: send message and wait for ac2 to receive it")
410
- acfactory.get_accepted_chat(ac1, ac2).send_text("message1")
411
- assert ac2.wait_for_incoming_msg().get_snapshot().text == "message1"
412
-
413
- assert ac1.get_config("configured_mvbox_folder") == "DeltaChat"
414
- while ac1.get_config("configured_trash_folder") != "Trash":
415
- ac1.wait_for_event(EventType.CONNECTIVITY_CHANGED)
416
-
417
-
418
381
  @pytest.mark.parametrize(
419
382
  ("folder", "move", "expected_destination"),
420
383
  [
@@ -490,20 +453,8 @@ def test_trash_multiple_messages(acfactory, direct_imap, log):
490
453
  ac1, ac2 = acfactory.get_online_accounts(2)
491
454
  ac2.stop_io()
492
455
 
493
- # Create the Trash folder on IMAP server and configure deletion to it. There was a bug that if
494
- # Trash wasn't configured initially, it can't be configured later, let's check this.
495
- log.section("Creating trash folder")
496
- ac2_direct_imap = direct_imap(ac2)
497
- ac2_direct_imap.create_folder("Trash")
498
456
  ac2.set_config("delete_server_after", "0")
499
457
  ac2.set_config("sync_msgs", "0")
500
- ac2.set_config("delete_to_trash", "1")
501
-
502
- log.section("Check that Trash can be configured initially as well")
503
- ac3 = ac2.clone()
504
- ac3.bring_online()
505
- assert ac3.get_config("configured_trash_folder")
506
- ac3.stop_io()
507
458
 
508
459
  ac2.start_io()
509
460
  chat12 = acfactory.get_accepted_chat(ac1, ac2)
@@ -520,17 +471,15 @@ def test_trash_multiple_messages(acfactory, direct_imap, log):
520
471
  assert msg.text in texts
521
472
  if text != "second":
522
473
  to_delete.append(msg)
523
- # ac2 has received some messages, this is impossible w/o the trash folder configured, let's
524
- # check the configuration.
525
- assert ac2.get_config("configured_trash_folder") == "Trash"
526
474
 
527
475
  log.section("ac2: deleting all messages except second")
528
476
  assert len(to_delete) == len(texts) - 1
529
477
  ac2.delete_messages(to_delete)
530
478
 
531
479
  log.section("ac2: test that only one message is left")
480
+ ac2_direct_imap = direct_imap(ac2)
532
481
  while 1:
533
- ac2.wait_for_event(EventType.IMAP_MESSAGE_MOVED)
482
+ ac2.wait_for_event(EventType.IMAP_MESSAGE_DELETED)
534
483
  ac2_direct_imap.select_config_folder("inbox")
535
484
  nr_msgs = len(ac2_direct_imap.get_all_messages())
536
485
  assert nr_msgs > 0
@@ -209,7 +209,7 @@ def test_transport_synchronization(acfactory, log) -> None:
209
209
 
210
210
  def test_transport_sync_new_as_primary(acfactory, log) -> None:
211
211
  """Test synchronization of new transport as primary between devices."""
212
- ac1 = acfactory.get_online_account()
212
+ ac1, bob = acfactory.get_online_accounts(2)
213
213
  ac1_clone = ac1.clone()
214
214
  ac1_clone.bring_online()
215
215
 
@@ -229,6 +229,15 @@ def test_transport_sync_new_as_primary(acfactory, log) -> None:
229
229
  ac1_clone.wait_for_event(EventType.TRANSPORTS_MODIFIED)
230
230
  assert ac1_clone.get_config("configured_addr") == transport2["addr"]
231
231
 
232
+ log.section("ac1_clone receives a message via the new primary transport")
233
+ ac1_chat = ac1.create_chat(bob)
234
+ ac1_chat.send_text("Hello!")
235
+ bob_chat_id = bob.wait_for_incoming_msg_event().chat_id
236
+ bob_chat = bob.get_chat_by_id(bob_chat_id)
237
+ bob_chat.accept()
238
+ bob_chat.send_text("hello back")
239
+ assert ac1_clone.wait_for_incoming_msg().get_snapshot().text == "hello back"
240
+
232
241
 
233
242
  def test_recognize_self_address(acfactory) -> None:
234
243
  alice, bob = acfactory.get_online_accounts(2)
@@ -5,6 +5,7 @@ import logging
5
5
  import os
6
6
  import socket
7
7
  import subprocess
8
+ import time
8
9
  from unittest.mock import MagicMock
9
10
 
10
11
  import pytest
@@ -387,22 +388,29 @@ def test_dont_move_sync_msgs(acfactory, direct_imap):
387
388
  ac1.set_config("bcc_self", "1")
388
389
  ac1.set_config("fix_is_chatmail", "1")
389
390
  ac1.add_or_update_transport({"addr": addr, "password": password})
390
- ac1.bring_online()
391
+ ac1.start_io()
391
392
  ac1_direct_imap = direct_imap(ac1)
392
393
 
393
- ac1_direct_imap.select_folder("Inbox")
394
394
  # Sync messages may also be sent during configuration.
395
- inbox_msg_cnt = len(ac1_direct_imap.get_all_messages())
395
+ ac1.wait_for_event(EventType.MSG_DELIVERED)
396
+ ac1_direct_imap.select_folder("Inbox")
397
+ while True:
398
+ if len(ac1_direct_imap.get_all_messages()) == 1:
399
+ break
400
+ time.sleep(1)
396
401
 
397
402
  ac1.set_config("displayname", "Alice")
398
403
  ac1.wait_for_event(EventType.MSG_DELIVERED)
399
404
  ac1.set_config("displayname", "Bob")
400
405
  ac1.wait_for_event(EventType.MSG_DELIVERED)
401
- ac1_direct_imap.select_folder("Inbox")
402
- assert len(ac1_direct_imap.get_all_messages()) == inbox_msg_cnt + 2
403
406
 
404
- ac1_direct_imap.select_folder("DeltaChat")
405
- assert len(ac1_direct_imap.get_all_messages()) == 0
407
+ # Message may not be delivered to IMAP immediately
408
+ # after sending over SMTP,
409
+ # retry until they are delivered to IMAP.
410
+ while True:
411
+ if len(ac1_direct_imap.get_all_messages()) == 3:
412
+ break
413
+ time.sleep(1)
406
414
 
407
415
 
408
416
  def test_reaction_seen_on_another_dev(acfactory) -> None: