rims 0.2.4 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -329,7 +329,7 @@ module RIMS::Test
329
329
 
330
330
  def test_mail_folder
331
331
  mbox_id = @mail_store.add_mbox('INBOX')
332
- folder = @mail_store.select_mbox(mbox_id)
332
+ folder = @mail_store.open_folder(mbox_id)
333
333
  assert_equal(mbox_id, folder.mbox_id)
334
334
  assert_equal(false, folder.read_only)
335
335
  assert_equal(true, folder.updated?)
@@ -371,7 +371,7 @@ module RIMS::Test
371
371
  end
372
372
  @mail_store.expunge_mbox(mbox_id)
373
373
 
374
- folder = @mail_store.select_mbox(mbox_id).reload
374
+ folder = @mail_store.open_folder(mbox_id).reload
375
375
 
376
376
  assert_equal([ 1 ].to_set, folder.parse_msg_set('1'))
377
377
  assert_equal([ 1 ].to_set, folder.parse_msg_set('1', uid: false))
@@ -398,7 +398,7 @@ module RIMS::Test
398
398
  def test_mail_folder_parse_msg_set_empty
399
399
  mbox_id = @mail_store.add_mbox('INBOX')
400
400
  assert_equal([], @mail_store.each_msg_uid(mbox_id).to_a)
401
- folder = @mail_store.select_mbox(mbox_id).reload
401
+ folder = @mail_store.open_folder(mbox_id).reload
402
402
 
403
403
  assert_equal([ 1 ].to_set, folder.parse_msg_set('1'))
404
404
  assert_equal([ 1 ].to_set, folder.parse_msg_set('1', uid: false))
@@ -424,7 +424,7 @@ module RIMS::Test
424
424
  @mail_store.add_msg(mbox_id, 'g') # 7
425
425
  @mail_store.add_msg(mbox_id, 'h') # 8 deleted
426
426
 
427
- folder = @mail_store.select_mbox(mbox_id).reload
427
+ folder = @mail_store.open_folder(mbox_id).reload
428
428
  assert_equal(8, folder.each_msg.count)
429
429
 
430
430
  client_msg_list = folder.each_msg.to_a
@@ -441,6 +441,25 @@ module RIMS::Test
441
441
  assert_equal(folder.each_msg.map(&:uid), client_msg_list.map(&:uid))
442
442
  end
443
443
 
444
+ def test_folder_alive?
445
+ mbox_id = @mail_store.add_mbox('INBOX')
446
+ folder = @mail_store.open_folder(mbox_id).reload
447
+ assert_equal(true, folder.alive?)
448
+
449
+ @mail_store.del_mbox(mbox_id)
450
+ assert_equal(false, folder.alive?)
451
+ end
452
+
453
+ def test_folder_should_be_alive
454
+ mbox_id = @mail_store.add_mbox('INBOX')
455
+ folder = @mail_store.open_folder(mbox_id).reload
456
+ folder.should_be_alive
457
+
458
+ @mail_store.del_mbox(mbox_id)
459
+ error = assert_raise(RuntimeError) { folder.should_be_alive }
460
+ assert_match(/deleted folder:/, error.message)
461
+ end
462
+
444
463
  def test_close_open
445
464
  mbox_id1 = @mail_store.add_mbox('INBOX')
446
465
  msg_uid1 = @mail_store.add_msg(mbox_id1, 'foo', Time.local(2014, 5, 6, 12, 34, 56))
@@ -625,139 +644,6 @@ module RIMS::Test
625
644
  mail_store.close
626
645
  end
627
646
  end
628
-
629
- class MailStorePoolRefCountTest < Test::Unit::TestCase
630
- def setup
631
- @kvs = Hash.new{|h, k| h[k] = {} }
632
- @kvs_open = proc{|mbox_version, unique_user_id, db_name|
633
- RIMS::Hash_KeyValueStore.new(@kvs["#{mbox_version}/#{unique_user_id[0, 7]}/#{db_name}"])
634
- }
635
- @mail_store_pool = RIMS::MailStore.build_pool(@kvs_open, @kvs_open)
636
- end
637
-
638
- def teardown
639
- pp @kvs if $DEBUG
640
- end
641
-
642
- def assert_call_hook
643
- call_count = 0
644
- yield(proc{ call_count += 1 })
645
- assert_equal(1, call_count, 'a hook should be called once.')
646
- end
647
- private :assert_call_hook
648
-
649
- def test_holder_object_key
650
- unique_user_id = RIMS::Authentication.unique_user_id('foo')
651
- holder = @mail_store_pool.get(unique_user_id)
652
- assert_equal(unique_user_id, holder.object_key)
653
- assert_equal(unique_user_id, holder.unique_user_id)
654
- end
655
-
656
- def test_get
657
- unique_user_id = RIMS::Authentication.unique_user_id('foo')
658
- assert_call_hook{|hook|
659
- @mail_store_pool.get(unique_user_id) { hook.call }
660
- }
661
- end
662
-
663
- def test_get2
664
- unique_user_id = RIMS::Authentication.unique_user_id('foo')
665
- @mail_store_pool.get(unique_user_id)
666
- @mail_store_pool.get(unique_user_id) { flunk }
667
- end
668
-
669
- def test_get_multiuser
670
- unique_user_id = RIMS::Authentication.unique_user_id('foo')
671
- unique_user_id2 = RIMS::Authentication.unique_user_id('bar')
672
-
673
- assert_call_hook{|hook|
674
- @mail_store_pool.get(unique_user_id) { hook.call }
675
- }
676
- assert_call_hook{|hook|
677
- @mail_store_pool.get(unique_user_id2) { hook.call }
678
- }
679
-
680
- @mail_store_pool.get(unique_user_id) { flunk }
681
- @mail_store_pool.get(unique_user_id2) { flunk }
682
- end
683
-
684
- def test_return_pool
685
- unique_user_id = RIMS::Authentication.unique_user_id('foo')
686
-
687
- holder = @mail_store_pool.get(unique_user_id)
688
- assert_call_hook{|hook|
689
- holder.return_pool{ hook.call }
690
- }
691
- end
692
-
693
- def test_return_pool2
694
- unique_user_id = RIMS::Authentication.unique_user_id('foo')
695
-
696
- holders = []
697
- holders << @mail_store_pool.get(unique_user_id)
698
- holders << @mail_store_pool.get(unique_user_id)
699
- holders << @mail_store_pool.get(unique_user_id)
700
-
701
- holders.pop.return_pool{ flunk }
702
- holders.shift.return_pool{ flunk }
703
- assert_call_hook{|hook|
704
- holders.pop.return_pool{ hook.call }
705
- }
706
- end
707
-
708
- def test_return_pool_multiuser
709
- unique_user_id = RIMS::Authentication.unique_user_id('foo')
710
- unique_user_id2 = RIMS::Authentication.unique_user_id('bar')
711
-
712
- holders = []
713
- holders << @mail_store_pool.get(unique_user_id)
714
- holders << @mail_store_pool.get(unique_user_id)
715
- holders << @mail_store_pool.get(unique_user_id)
716
-
717
- holders2 = []
718
- holders2 << @mail_store_pool.get(unique_user_id2)
719
- holders2 << @mail_store_pool.get(unique_user_id2)
720
- holders2 << @mail_store_pool.get(unique_user_id2)
721
-
722
- holders.pop.return_pool{ flunk }
723
- holders2.shift.return_pool{ flunk }
724
- holders.pop.return_pool{ flunk }
725
- holders2.shift.return_pool{ flunk }
726
- assert_call_hook{|hook|
727
- holders2.shift.return_pool{ hook.call }
728
- }
729
- assert_call_hook{|hook|
730
- holders.pop.return_pool{ hook.call }
731
- }
732
- end
733
-
734
- def test_cycle
735
- unique_user_id = RIMS::Authentication.unique_user_id('foo')
736
-
737
- holders = []
738
- assert_call_hook{|hook|
739
- holders << @mail_store_pool.get(unique_user_id) { hook.call }
740
- }
741
- holders << @mail_store_pool.get(unique_user_id) { flunk }
742
- holders << @mail_store_pool.get(unique_user_id) { flunk }
743
-
744
- holders.pop.return_pool{ flunk }
745
- holders.pop.return_pool{ flunk }
746
- assert_call_hook{|hook|
747
- holders.pop.return_pool{ hook.call }
748
- }
749
-
750
- assert_call_hook{|hook|
751
- holders << @mail_store_pool.get(unique_user_id) { hook.call }
752
- }
753
- holders << @mail_store_pool.get(unique_user_id) { flunk }
754
-
755
- holders.shift.return_pool{ flunk }
756
- assert_call_hook{|hook|
757
- holders.shift.return_pool{ hook.call }
758
- }
759
- end
760
- end
761
647
  end
762
648
 
763
649
  # Local Variables:
@@ -30,7 +30,14 @@ module RIMS::Test
30
30
  @logger = Logger.new(STDOUT)
31
31
  @logger.level = ($DEBUG) ? Logger::DEBUG : Logger::FATAL
32
32
 
33
- @reader = RIMS::Protocol::AuthenticationReader.new(@auth, @input, @output, @logger)
33
+ input_gets = @input.method(:gets)
34
+ output_write = lambda{|res|
35
+ for line in res
36
+ @output << line
37
+ end
38
+ }
39
+
40
+ @reader = RIMS::Protocol::AuthenticationReader.new(@auth, input_gets, output_write, @logger)
34
41
  end
35
42
 
36
43
  def assert_input_output_stream(input_txt, expected_output_txt)
@@ -133,7 +133,13 @@ module RIMS::Test
133
133
  if (client_input_text) then
134
134
  input = StringIO.new(client_input_text, 'r')
135
135
  output = StringIO.new('', 'w')
136
- inout_args = [ input, output ]
136
+ input_gets = input.method(:gets)
137
+ output_write = lambda{|res|
138
+ for line in res
139
+ output << line
140
+ end
141
+ }
142
+ inout_args = [ input_gets, output_write ]
137
143
  inout_args << RIMS::Protocol::ConnectionTimer.new(@limits, input) if (cmd_id == :idle)
138
144
  cmd_args = inout_args + cmd_args
139
145
  end
@@ -236,21 +242,21 @@ module RIMS::Test
236
242
  extend Forwardable
237
243
 
238
244
  def open_mail_store
239
- mail_store_holder = @mail_store_pool.get(@unique_user_id)
240
- begin
241
- @mail_store = mail_store_holder.mail_store
242
- @mail_store.write_synchronize{
243
- yield
244
- }
245
- ensure
246
- @mail_store = nil
247
- mail_store_holder.return_pool
248
- end
245
+ @services.call_service(:engine, @unique_user_id) {|engine|
246
+ begin
247
+ @mail_store = engine.mail_store
248
+ @mail_store.write_synchronize{
249
+ yield
250
+ }
251
+ ensure
252
+ @mail_store = nil
253
+ end
254
+ }
249
255
  end
250
256
  private :open_mail_store
251
257
 
252
258
  def make_decoder
253
- RIMS::Protocol::Decoder.new_decoder(@mail_store_pool, @auth, @logger)
259
+ RIMS::Protocol::Decoder.new_decoder(@services, @auth, @logger)
254
260
  end
255
261
  private :make_decoder
256
262
 
@@ -273,13 +279,30 @@ module RIMS::Test
273
279
  private :command_test?
274
280
 
275
281
  def setup
282
+ @logger = Logger.new(STDOUT)
283
+ @logger.level = ($DEBUG) ? Logger::DEBUG : Logger::FATAL
284
+
276
285
  @kvs = Hash.new{|h, k| h[k] = {} }
277
286
  @kvs_open = proc{|mbox_version, unique_user_id, db_name|
278
287
  RIMS::Hash_KeyValueStore.new(@kvs["#{mbox_version}/#{unique_user_id[0, 7]}/#{db_name}"])
279
288
  }
280
289
  @unique_user_id = RIMS::Authentication.unique_user_id('foo')
281
290
 
282
- @mail_store_pool = RIMS::MailStore.build_pool(@kvs_open, @kvs_open)
291
+ @services = Riser::DRbServices.new(0)
292
+ @services.add_sticky_process_service(:engine,
293
+ Riser::ResourceSet.build{|builder|
294
+ builder.at_create{|unique_user_id|
295
+ mail_store = RIMS::MailStore.build(unique_user_id, @kvs_open, @kvs_open)
296
+ RIMS::Protocol::Decoder::Engine.new(unique_user_id, mail_store, @logger)
297
+ }
298
+ builder.at_destroy{|engine|
299
+ engine.destroy
300
+ }
301
+ builder.alias_unref(:destroy)
302
+ })
303
+ @services.start_server
304
+ @services.start_client
305
+
283
306
  open_mail_store{
284
307
  @inbox_id = @mail_store.mbox_id('INBOX')
285
308
  }
@@ -297,9 +320,6 @@ module RIMS::Test
297
320
  @pw.entry('#postman', 'password_of_mail_delivery_user')
298
321
  @auth.add_plug_in(@pw)
299
322
 
300
- @logger = Logger.new(STDOUT)
301
- @logger.level = ($DEBUG) ? Logger::DEBUG : Logger::FATAL
302
-
303
323
  @limits = RIMS::Protocol::ConnectionLimits.new(0.001, 60 * 30)
304
324
  @decoder = make_decoder
305
325
  @tag = 'T000'
@@ -308,8 +328,8 @@ module RIMS::Test
308
328
  end
309
329
 
310
330
  def teardown
311
- @decoder.cleanup
312
- assert(@mail_store_pool.empty?)
331
+ assert_equal(0, @services.get_service(:engine, @unique_user_id).proxy_count)
332
+ @services.stop_server
313
333
  pp @kvs if $DEBUG
314
334
  end
315
335
 
@@ -554,7 +574,7 @@ module RIMS::Test
554
574
 
555
575
  assert_imap_command("AUTHENTICATE plain #{client_plain_response_base64('foo', 'detarame')}",
556
576
  client_input_text: '') {|assert|
557
- assert.match(/^#{tag} NO /)
577
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/auth.* fail/)
558
578
  }
559
579
 
560
580
  assert_equal(false, @decoder.auth?) if command_test?
@@ -568,7 +588,7 @@ module RIMS::Test
568
588
 
569
589
  assert_imap_command("AUTHENTICATE plain #{client_plain_response_base64('foo', 'open_sesame')}",
570
590
  client_input_text: '') {|assert|
571
- assert.match(/^#{tag} NO /)
591
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/dup.* auth/)
572
592
  }
573
593
 
574
594
  assert_equal(true, @decoder.auth?) if command_test?
@@ -599,13 +619,13 @@ module RIMS::Test
599
619
 
600
620
  assert_imap_command('AUTHENTICATE plain', client_input_text: "*\r\n") {|assert|
601
621
  assert.equal('+ ')
602
- assert.match(/^#{tag} BAD /)
622
+ assert.match(/^#{tag} BAD AUTHENTICATE/, peek_next_line: true).match(/fail/)
603
623
  }
604
624
 
605
625
  assert_imap_command('AUTHENTICATE plain',
606
626
  client_input_text: client_plain_response_base64('foo', 'detarame') + "\r\n") {|assert|
607
627
  assert.equal('+ ')
608
- assert.match(/^#{tag} NO /)
628
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/auth.* fail/)
609
629
  }
610
630
 
611
631
  assert_equal(false, @decoder.auth?) if command_test?
@@ -619,7 +639,7 @@ module RIMS::Test
619
639
  assert_equal(true, @decoder.auth?) if command_test?
620
640
 
621
641
  assert_imap_command('AUTHENTICATE plain', client_input_text: '') {|assert|
622
- assert.match(/^#{tag} NO /, peek_next_line: true).match(/duplicated authentication/)
642
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/dup.* auth/)
623
643
  }
624
644
 
625
645
  assert_equal(true, @decoder.auth?) if command_test?
@@ -656,13 +676,13 @@ module RIMS::Test
656
676
 
657
677
  assert_imap_command('AUTHENTICATE cram-md5', client_input_text: "*\r\n") {|assert|
658
678
  assert.equal("+ #{server_client_data_base64_pair_list[0][0]}")
659
- assert.match(/^#{tag} BAD /)
679
+ assert.match(/^#{tag} BAD AUTHENTICATE/, peek_next_line: true).match(/fail/)
660
680
  }
661
681
 
662
682
  assert_imap_command('AUTHENTICATE cram-md5',
663
683
  client_input_text: server_client_data_base64_pair_list[1][1] + "\r\n") {|assert|
664
684
  assert.equal("+ #{server_client_data_base64_pair_list[1][0]}")
665
- assert.match(/^#{tag} NO /)
685
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/auth.* fail/)
666
686
  }
667
687
 
668
688
  assert_equal(false, @decoder.auth?) if command_test?
@@ -676,7 +696,7 @@ module RIMS::Test
676
696
  assert_equal(true, @decoder.auth?) if command_test?
677
697
 
678
698
  assert_imap_command('AUTHENTICATE cram-md5', client_input_text: '') {|assert|
679
- assert.match(/^#{tag} NO /, peek_next_line: true).match(/duplicated authentication/)
699
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/dup.* auth/)
680
700
  }
681
701
 
682
702
  assert_imap_command('LOGOUT') {|assert|
@@ -704,7 +724,7 @@ module RIMS::Test
704
724
  assert_equal(false, @decoder.auth?) if command_test?
705
725
 
706
726
  assert_imap_command('LOGIN foo detarame') {|assert|
707
- assert.match(/^#{tag} NO /)
727
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/fail.* login/)
708
728
  }
709
729
 
710
730
  assert_equal(false, @decoder.auth?) if command_test?
@@ -716,7 +736,7 @@ module RIMS::Test
716
736
  assert_equal(true, @decoder.auth?) if command_test?
717
737
 
718
738
  assert_imap_command('LOGIN foo open_sesame') {|assert|
719
- assert.match(/^#{tag} NO/)
739
+ assert.match(/^#{tag} NO/, peek_next_line: true).match(/dup.* login/)
720
740
  }
721
741
 
722
742
  assert_equal(true, @decoder.auth?) if command_test?
@@ -767,7 +787,7 @@ module RIMS::Test
767
787
  end
768
788
 
769
789
  assert_imap_command('SELECT INBOX') {|assert|
770
- assert.match(/^#{tag} NO /)
790
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/)
771
791
  }
772
792
 
773
793
  if (command_test?) then
@@ -898,7 +918,7 @@ module RIMS::Test
898
918
  end
899
919
 
900
920
  assert_imap_command('EXAMINE INBOX') {|assert|
901
- assert.match(/^#{tag} NO /)
921
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/)
902
922
  }
903
923
 
904
924
  if (command_test?) then
@@ -1008,7 +1028,7 @@ module RIMS::Test
1008
1028
  assert_equal(false, @decoder.auth?) if command_test?
1009
1029
 
1010
1030
  assert_imap_command('CREATE foo') {|assert|
1011
- assert.match(/^#{tag} NO /)
1031
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/)
1012
1032
  }
1013
1033
 
1014
1034
  assert_equal(false, @decoder.auth?) if command_test?
@@ -1031,7 +1051,7 @@ module RIMS::Test
1031
1051
  }
1032
1052
 
1033
1053
  assert_imap_command('CREATE inbox') {|assert|
1034
- assert.match(/^#{tag} NO /)
1054
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/dup.* mailbox/)
1035
1055
  }
1036
1056
 
1037
1057
  assert_imap_command('LOGOUT') {|assert|
@@ -1098,7 +1118,7 @@ module RIMS::Test
1098
1118
  assert_equal(false, @decoder.auth?) if command_test?
1099
1119
 
1100
1120
  assert_imap_command('DELETE foo') {|assert|
1101
- assert.match(/^#{tag} NO /)
1121
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/)
1102
1122
  }
1103
1123
 
1104
1124
  open_mail_store{
@@ -1124,7 +1144,7 @@ module RIMS::Test
1124
1144
  }
1125
1145
 
1126
1146
  assert_imap_command('DELETE bar') {|assert|
1127
- assert.match(/^#{tag} NO /)
1147
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not found.* mailbox/)
1128
1148
  }
1129
1149
 
1130
1150
  open_mail_store{
@@ -1133,7 +1153,7 @@ module RIMS::Test
1133
1153
  }
1134
1154
 
1135
1155
  assert_imap_command('DELETE inbox') {|assert|
1136
- assert.match(/^#{tag} NO /)
1156
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not delete.* [Ii][Nn][Bb][Oo][Xx]/)
1137
1157
  }
1138
1158
 
1139
1159
  if (command_test?) then
@@ -1211,7 +1231,7 @@ module RIMS::Test
1211
1231
  assert_equal(false, @decoder.auth?) if command_test?
1212
1232
 
1213
1233
  assert_imap_command('RENAME foo bar') {|assert|
1214
- assert.match(/^#{tag} NO /)
1234
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/)
1215
1235
  }
1216
1236
 
1217
1237
  open_mail_store{
@@ -1237,7 +1257,7 @@ module RIMS::Test
1237
1257
  }
1238
1258
 
1239
1259
  assert_imap_command('RENAME nobox baz') {|assert|
1240
- assert.match(/^#{tag} NO /)
1260
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not found.* mailbox/)
1241
1261
  }
1242
1262
 
1243
1263
  open_mail_store{
@@ -1245,7 +1265,7 @@ module RIMS::Test
1245
1265
  }
1246
1266
 
1247
1267
  assert_imap_command('RENAME INBOX baz') {|assert|
1248
- assert.match(/^#{tag} NO /)
1268
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not rename.* [Ii][Nn][Bb][Oo][Xx]/)
1249
1269
  }
1250
1270
 
1251
1271
  open_mail_store{
@@ -1254,7 +1274,7 @@ module RIMS::Test
1254
1274
  }
1255
1275
 
1256
1276
  assert_imap_command('RENAME bar inbox') {|assert|
1257
- assert.match(/^#{tag} NO /)
1277
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/dup.* mailbox/)
1258
1278
  }
1259
1279
 
1260
1280
  open_mail_store{
@@ -1331,7 +1351,7 @@ module RIMS::Test
1331
1351
  assert_equal(false, @decoder.auth?) if command_test?
1332
1352
 
1333
1353
  assert_imap_command('SUBSCRIBE INBOX') {|assert|
1334
- assert.match(/^#{tag} NO /)
1354
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/)
1335
1355
  }
1336
1356
 
1337
1357
  assert_equal(false, @decoder.auth?) if command_test?
@@ -1400,7 +1420,7 @@ module RIMS::Test
1400
1420
  assert_equal(false, @decoder.auth?) if command_test?
1401
1421
 
1402
1422
  assert_imap_command('UNSUBSCRIBE INBOX') {|assert|
1403
- assert.match(/^#{tag} NO /)
1423
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/)
1404
1424
  }
1405
1425
 
1406
1426
  assert_equal(false, @decoder.auth?) if command_test?
@@ -1412,7 +1432,7 @@ module RIMS::Test
1412
1432
  assert_equal(true, @decoder.auth?) if command_test?
1413
1433
 
1414
1434
  assert_imap_command('UNSUBSCRIBE INBOX') {|assert|
1415
- assert.equal("#{tag} NO not implemented subscribe/unsbscribe command")
1435
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not implemented/)
1416
1436
  }
1417
1437
  }
1418
1438
  end
@@ -1433,7 +1453,7 @@ module RIMS::Test
1433
1453
  assert_equal(false, @decoder.auth?) if command_test?
1434
1454
 
1435
1455
  assert_imap_command('LIST "" ""') {|assert|
1436
- assert.match(/^#{tag} NO /)
1456
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/)
1437
1457
  }
1438
1458
 
1439
1459
  assert_equal(false, @decoder.auth?) if command_test?
@@ -1548,7 +1568,7 @@ module RIMS::Test
1548
1568
  assert_equal(false, @decoder.auth?) if command_test?
1549
1569
 
1550
1570
  assert_imap_command('STATUS nobox (MESSAGES)') {|assert|
1551
- assert.match(/^#{tag} NO /)
1571
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/)
1552
1572
  }
1553
1573
 
1554
1574
  assert_equal(false, @decoder.auth?) if command_test?
@@ -1560,7 +1580,7 @@ module RIMS::Test
1560
1580
  assert_equal(true, @decoder.auth?) if command_test?
1561
1581
 
1562
1582
  assert_imap_command('STATUS nobox (MESSAGES)') {|assert|
1563
- assert.match(/^#{tag} NO /)
1583
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not found.* mailbox/)
1564
1584
  }
1565
1585
 
1566
1586
  assert_imap_command('STATUS INBOX (MESSAGES)') {|assert|
@@ -1618,12 +1638,17 @@ module RIMS::Test
1618
1638
  assert.equal("#{tag} OK STATUS completed")
1619
1639
  }
1620
1640
 
1641
+ assert_imap_command('STATUS INBOX ()') {|assert|
1642
+ assert.equal('* STATUS "INBOX" ()')
1643
+ assert.equal("#{tag} OK STATUS completed")
1644
+ }
1645
+
1621
1646
  assert_imap_command('STATUS INBOX MESSAGES') {|assert|
1622
- assert.match(/^#{tag} BAD /)
1647
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
1623
1648
  }
1624
1649
 
1625
1650
  assert_imap_command('STATUS INBOX (DETARAME)') {|assert|
1626
- assert.match(/^#{tag} BAD /)
1651
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
1627
1652
  }
1628
1653
 
1629
1654
  assert_imap_command('LOGOUT') {|assert|
@@ -1680,7 +1705,7 @@ module RIMS::Test
1680
1705
  assert_equal(false, @decoder.auth?) if command_test?
1681
1706
 
1682
1707
  assert_imap_command('LSUB "" *') {|assert|
1683
- assert.match(/^#{tag} NO /)
1708
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/)
1684
1709
  }
1685
1710
 
1686
1711
  assert_equal(false, @decoder.auth?) if command_test?
@@ -1747,7 +1772,7 @@ module RIMS::Test
1747
1772
  assert_equal(false, @decoder.auth?) if command_test?
1748
1773
 
1749
1774
  assert_imap_command('APPEND INBOX a') {|assert|
1750
- assert.match(/^#{tag} NO /, peek_next_line: true).no_match(/\[TRYCREATE\]/)
1775
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/, peek_next_line: true).no_match(/\[TRYCREATE\]/)
1751
1776
  }
1752
1777
 
1753
1778
  open_mail_store{
@@ -1805,7 +1830,7 @@ module RIMS::Test
1805
1830
  }
1806
1831
 
1807
1832
  assert_imap_command('APPEND INBOX (\Answered \Flagged \Deleted \Seen \Draft) "19-Nov-1975 12:34:56 +0900" NIL x') {|assert|
1808
- assert.match(/^#{tag} BAD /)
1833
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
1809
1834
  }
1810
1835
 
1811
1836
  open_mail_store{
@@ -1813,7 +1838,7 @@ module RIMS::Test
1813
1838
  }
1814
1839
 
1815
1840
  assert_imap_command('APPEND INBOX "19-Nov-1975 12:34:56 +0900" (\Answered \Flagged \Deleted \Seen \Draft) x') {|assert|
1816
- assert.match(/^#{tag} BAD /)
1841
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
1817
1842
  }
1818
1843
 
1819
1844
  open_mail_store{
@@ -1821,7 +1846,7 @@ module RIMS::Test
1821
1846
  }
1822
1847
 
1823
1848
  assert_imap_command('APPEND INBOX (\Recent) x') {|assert|
1824
- assert.match(/^#{tag} BAD /)
1849
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
1825
1850
  }
1826
1851
 
1827
1852
  open_mail_store{
@@ -1829,7 +1854,7 @@ module RIMS::Test
1829
1854
  }
1830
1855
 
1831
1856
  assert_imap_command('APPEND INBOX "bad date-time" x') {|assert|
1832
- assert.match(/^#{tag} BAD /)
1857
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
1833
1858
  }
1834
1859
 
1835
1860
  open_mail_store{
@@ -1837,7 +1862,7 @@ module RIMS::Test
1837
1862
  }
1838
1863
 
1839
1864
  assert_imap_command('APPEND nobox x') {|assert|
1840
- assert.match(/^#{tag} NO \[TRYCREATE\]/)
1865
+ assert.match(/^#{tag} NO \[TRYCREATE\]/, peek_next_line: true).match(/not found.* mailbox/)
1841
1866
  }
1842
1867
 
1843
1868
  open_mail_store{
@@ -1909,7 +1934,7 @@ module RIMS::Test
1909
1934
  end
1910
1935
 
1911
1936
  assert_imap_command('CHECK') {|assert|
1912
- assert.match(/^#{tag} NO /)
1937
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/)
1913
1938
  }
1914
1939
 
1915
1940
  if (command_test?) then
@@ -1927,7 +1952,7 @@ module RIMS::Test
1927
1952
  end
1928
1953
 
1929
1954
  assert_imap_command('CHECK') {|assert|
1930
- assert.match(/^#{tag} NO /)
1955
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not selected/)
1931
1956
  }
1932
1957
 
1933
1958
  assert_imap_command('SELECT INBOX') {|assert|
@@ -1988,7 +2013,7 @@ module RIMS::Test
1988
2013
  end
1989
2014
 
1990
2015
  assert_imap_command('CLOSE') {|assert|
1991
- assert.match(/^#{tag} NO /)
2016
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/)
1992
2017
  }
1993
2018
 
1994
2019
  if (command_test?) then
@@ -2006,7 +2031,7 @@ module RIMS::Test
2006
2031
  end
2007
2032
 
2008
2033
  assert_imap_command('CLOSE') {|assert|
2009
- assert.match(/^#{tag} NO /)
2034
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not selected/)
2010
2035
  }
2011
2036
 
2012
2037
  assert_imap_command('SELECT INBOX') {|assert|
@@ -2024,7 +2049,13 @@ module RIMS::Test
2024
2049
  end
2025
2050
 
2026
2051
  assert_imap_command('CLOSE') {|assert|
2027
- assert.equal("* 1 EXPUNGE")
2052
+ # see: RFC 3501 / 6.4.2. CLOSE Command
2053
+ # <https://tools.ietf.org/html/rfc3501#section-6.4.2>
2054
+ #
2055
+ # The CLOSE command permanently removes all messages that have the
2056
+ # \Deleted flag set from the currently selected mailbox, and returns
2057
+ # to the authenticated state from the selected state. No untagged
2058
+ # EXPUNGE responses are sent.
2028
2059
  assert.equal("#{tag} OK CLOSE completed")
2029
2060
  }
2030
2061
 
@@ -2093,7 +2124,7 @@ module RIMS::Test
2093
2124
  end
2094
2125
 
2095
2126
  assert_imap_command('CLOSE') {|assert|
2096
- assert.match(/^#{tag} NO /)
2127
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/)
2097
2128
  }
2098
2129
 
2099
2130
  if (command_test?) then
@@ -2111,7 +2142,7 @@ module RIMS::Test
2111
2142
  end
2112
2143
 
2113
2144
  assert_imap_command('CLOSE') {|assert|
2114
- assert.match(/^#{tag} NO /)
2145
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not selected/)
2115
2146
  }
2116
2147
 
2117
2148
  assert_imap_command('EXAMINE INBOX') {|assert|
@@ -2179,7 +2210,7 @@ module RIMS::Test
2179
2210
  end
2180
2211
 
2181
2212
  assert_imap_command('EXPUNGE') {|assert|
2182
- assert.match(/^#{tag} NO /)
2213
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/)
2183
2214
  }
2184
2215
 
2185
2216
  if (command_test?) then
@@ -2197,7 +2228,7 @@ module RIMS::Test
2197
2228
  end
2198
2229
 
2199
2230
  assert_imap_command('EXPUNGE') {|assert|
2200
- assert.match(/^#{tag} NO /)
2231
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not selected/)
2201
2232
  }
2202
2233
 
2203
2234
  assert_imap_command('SELECT INBOX') {|assert|
@@ -2338,7 +2369,7 @@ module RIMS::Test
2338
2369
  end
2339
2370
 
2340
2371
  assert_imap_command('EXPUNGE') {|assert|
2341
- assert.match(/^#{tag} NO /)
2372
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/)
2342
2373
  }
2343
2374
 
2344
2375
  if (command_test?) then
@@ -2356,7 +2387,7 @@ module RIMS::Test
2356
2387
  end
2357
2388
 
2358
2389
  assert_imap_command('EXPUNGE') {|assert|
2359
- assert.match(/^#{tag} NO /)
2390
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not selected/)
2360
2391
  }
2361
2392
 
2362
2393
  assert_imap_command('EXAMINE INBOX') {|assert|
@@ -2370,7 +2401,7 @@ module RIMS::Test
2370
2401
  end
2371
2402
 
2372
2403
  assert_imap_command('EXPUNGE') {|assert|
2373
- assert.match(/^#{tag} NO /)
2404
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/cannot expunge.* read-only/)
2374
2405
  }
2375
2406
 
2376
2407
  open_mail_store{
@@ -2405,7 +2436,7 @@ module RIMS::Test
2405
2436
  end
2406
2437
 
2407
2438
  assert_imap_command('SEARCH ALL') {|assert|
2408
- assert.match(/^#{tag} NO /)
2439
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/)
2409
2440
  }
2410
2441
 
2411
2442
  if (command_test?) then
@@ -2423,7 +2454,7 @@ module RIMS::Test
2423
2454
  end
2424
2455
 
2425
2456
  assert_imap_command('SEARCH ALL') {|assert|
2426
- assert.match(/^#{tag} NO /)
2457
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not selected/)
2427
2458
  }
2428
2459
 
2429
2460
  assert_imap_command('SELECT INBOX') {|assert|
@@ -2506,11 +2537,11 @@ module RIMS::Test
2506
2537
  }
2507
2538
 
2508
2539
  assert_imap_command('SEARCH bad-search-command') {|assert|
2509
- assert.match(/^#{tag} BAD /)
2540
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
2510
2541
  }
2511
2542
 
2512
2543
  assert_imap_command('SEARCH') {|assert|
2513
- assert.match(/^#{tag} BAD /)
2544
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
2514
2545
  }
2515
2546
 
2516
2547
  assert_imap_command('LOGOUT') {|assert|
@@ -2561,7 +2592,7 @@ module RIMS::Test
2561
2592
  end
2562
2593
 
2563
2594
  assert_imap_command('SEARCH CHARSET utf-8 ALL') {|assert|
2564
- assert.match(/^#{tag} NO /)
2595
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/)
2565
2596
  }
2566
2597
 
2567
2598
  if (command_test?) then
@@ -2579,7 +2610,7 @@ module RIMS::Test
2579
2610
  end
2580
2611
 
2581
2612
  assert_imap_command('SEARCH CHARSET utf-8 ALL') {|assert|
2582
- assert.match(/^#{tag} NO /)
2613
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not selected/)
2583
2614
  }
2584
2615
 
2585
2616
  assert_imap_command('SELECT INBOX') {|assert|
@@ -2609,11 +2640,23 @@ module RIMS::Test
2609
2640
 
2610
2641
  utf8_msg = "\u306F\u306B\u307B"
2611
2642
  assert_imap_command("SEARCH CHARSET utf-8 BODY {#{utf8_msg.bytesize}}\r\n#{utf8_msg}".b) {|assert|
2612
- assert.equal('+ continue')
2643
+ assert.match(/^\+ /)
2613
2644
  assert.equal("* SEARCH 4 5\r\n")
2614
2645
  assert.equal("#{tag} OK SEARCH completed\r\n")
2615
2646
  }
2616
2647
 
2648
+ assert_imap_command('SEARCH CHARSET') {|assert|
2649
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
2650
+ }
2651
+
2652
+ assert_imap_command('SEARCH CHARSET NIL') {|assert|
2653
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
2654
+ }
2655
+
2656
+ assert_imap_command('SEARCH CHARSET utf-8') {|assert|
2657
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
2658
+ }
2659
+
2617
2660
  assert_imap_command('LOGOUT') {|assert|
2618
2661
  assert.match(/^\* BYE /)
2619
2662
  assert.equal("#{tag} OK LOGOUT completed")
@@ -2663,7 +2706,7 @@ module RIMS::Test
2663
2706
  end
2664
2707
 
2665
2708
  assert_imap_command('SEARCH CHARSET utf-8 ALL') {|assert|
2666
- assert.match(/^#{tag} NO /)
2709
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/)
2667
2710
  }
2668
2711
 
2669
2712
  if (command_test?) then
@@ -2681,7 +2724,7 @@ module RIMS::Test
2681
2724
  end
2682
2725
 
2683
2726
  assert_imap_command('SEARCH CHARSET utf-8 ALL') {|assert|
2684
- assert.match(/^#{tag} NO /)
2727
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not selected/)
2685
2728
  }
2686
2729
 
2687
2730
  assert_imap_command('SELECT INBOX') {|assert|
@@ -2716,11 +2759,23 @@ module RIMS::Test
2716
2759
 
2717
2760
  utf8_msg = "\u306F\u306B\u307B"
2718
2761
  assert_imap_command("SEARCH CHARSET utf-8 TEXT {#{utf8_msg.bytesize}}\r\n#{utf8_msg}".b) {|assert|
2719
- assert.equal('+ continue')
2762
+ assert.match(/^\+ /)
2720
2763
  assert.equal("* SEARCH 4 5\r\n")
2721
2764
  assert.equal("#{tag} OK SEARCH completed\r\n")
2722
2765
  }
2723
2766
 
2767
+ assert_imap_command('SEARCH CHARSET') {|assert|
2768
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
2769
+ }
2770
+
2771
+ assert_imap_command('SEARCH CHARSET NIL') {|assert|
2772
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
2773
+ }
2774
+
2775
+ assert_imap_command('SEARCH CHARSET utf-8') {|assert|
2776
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
2777
+ }
2778
+
2724
2779
  assert_imap_command('LOGOUT') {|assert|
2725
2780
  assert.match(/^\* BYE /)
2726
2781
  assert.equal("#{tag} OK LOGOUT completed")
@@ -2756,7 +2811,7 @@ module RIMS::Test
2756
2811
  end
2757
2812
 
2758
2813
  assert_imap_command('FETCH 1:* FAST') {|assert|
2759
- assert.match(/^#{tag} NO /)
2814
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/)
2760
2815
  }
2761
2816
 
2762
2817
  assert_imap_command('LOGIN foo open_sesame') {|assert|
@@ -2769,7 +2824,7 @@ module RIMS::Test
2769
2824
  end
2770
2825
 
2771
2826
  assert_imap_command('FETCH 1:* FAST') {|assert|
2772
- assert.match(/^#{tag} NO /)
2827
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not selected/)
2773
2828
  }
2774
2829
 
2775
2830
  assert_imap_command('SELECT INBOX') {|assert|
@@ -2815,6 +2870,18 @@ module RIMS::Test
2815
2870
  assert_msg_flags(3, seen: false, recent: true)
2816
2871
  }
2817
2872
 
2873
+ assert(10 < @simple_mail.raw_source.bytesize)
2874
+ assert(10 + 10 < @simple_mail.raw_source.bytesize)
2875
+ assert_imap_command('FETCH 1 BODY[]<10.10>') {|assert|
2876
+ assert.equal_lines("* 1 FETCH (BODY[]<10> #{literal(@simple_mail.raw_source[10, 10])})".b)
2877
+ assert.equal("#{tag} OK FETCH completed")
2878
+ }
2879
+
2880
+ open_mail_store{
2881
+ assert_msg_flags(2, seen: true, recent: true)
2882
+ assert_msg_flags(3, seen: false, recent: true)
2883
+ }
2884
+
2818
2885
  assert_imap_command('FETCH 2 BODY.PEEK[1]') {|assert|
2819
2886
  assert.equal_lines(%Q'* 2 FETCH (BODY[1] "#{@mpart_mail.parts[0].body.raw_source}")'.b)
2820
2887
  assert.equal("#{tag} OK FETCH completed")
@@ -2835,6 +2902,18 @@ module RIMS::Test
2835
2902
  assert_msg_flags(3, seen: false, recent: true)
2836
2903
  }
2837
2904
 
2905
+ assert(10 < @simple_mail.raw_source.bytesize)
2906
+ assert(10 + 10 < @simple_mail.raw_source.bytesize)
2907
+ assert_imap_command('FETCH 2 BODY[]<10.10>', uid: true) {|assert|
2908
+ assert.equal_lines("* 1 FETCH (UID 2 BODY[]<10> #{literal(@simple_mail.raw_source[10, 10])})".b)
2909
+ assert.equal("#{tag} OK FETCH completed")
2910
+ }
2911
+
2912
+ open_mail_store{
2913
+ assert_msg_flags(2, seen: true, recent: true)
2914
+ assert_msg_flags(3, seen: false, recent: true)
2915
+ }
2916
+
2838
2917
  assert_imap_command('FETCH 3 (UID BODY.PEEK[1])', uid: true) {|assert|
2839
2918
  assert.equal_lines(%Q'* 2 FETCH (UID 3 BODY[1] "#{@mpart_mail.parts[0].body.raw_source}")'.b)
2840
2919
  assert.equal("#{tag} OK FETCH completed")
@@ -2845,6 +2924,10 @@ module RIMS::Test
2845
2924
  assert_msg_flags(3, seen: false, recent: true)
2846
2925
  }
2847
2926
 
2927
+ assert_imap_command('FETCH 1 bad-fetch-attr') {|assert|
2928
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
2929
+ }
2930
+
2848
2931
  assert_imap_command('LOGOUT') {|assert|
2849
2932
  assert.match(/^\* BYE /)
2850
2933
  assert.equal("#{tag} OK LOGOUT completed")
@@ -2880,7 +2963,7 @@ module RIMS::Test
2880
2963
  end
2881
2964
 
2882
2965
  assert_imap_command('FETCH 1:* FAST') {|assert|
2883
- assert.match(/^#{tag} NO /)
2966
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/)
2884
2967
  }
2885
2968
 
2886
2969
  assert_imap_command('LOGIN foo open_sesame') {|assert|
@@ -2893,7 +2976,7 @@ module RIMS::Test
2893
2976
  end
2894
2977
 
2895
2978
  assert_imap_command('FETCH 1:* FAST') {|assert|
2896
- assert.match(/^#{tag} NO /)
2979
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not selected/)
2897
2980
  }
2898
2981
 
2899
2982
  assert_imap_command('EXAMINE INBOX') {|assert|
@@ -2939,6 +3022,18 @@ module RIMS::Test
2939
3022
  assert_msg_flags(3, seen: false, recent: true)
2940
3023
  }
2941
3024
 
3025
+ assert(10 < @simple_mail.raw_source.bytesize)
3026
+ assert(10 + 10 < @simple_mail.raw_source.bytesize)
3027
+ assert_imap_command('FETCH 1 BODY[]<10.10>') {|assert|
3028
+ assert.equal_lines("* 1 FETCH (BODY[]<10> #{literal(@simple_mail.raw_source[10, 10])})".b)
3029
+ assert.equal("#{tag} OK FETCH completed")
3030
+ }
3031
+
3032
+ open_mail_store{
3033
+ assert_msg_flags(2, seen: false, recent: true)
3034
+ assert_msg_flags(3, seen: false, recent: true)
3035
+ }
3036
+
2942
3037
  assert_imap_command('FETCH 2 BODY.PEEK[1]') {|assert|
2943
3038
  assert.equal_lines(%Q'* 2 FETCH (BODY[1] "#{@mpart_mail.parts[0].body.raw_source}")'.b)
2944
3039
  assert.equal("#{tag} OK FETCH completed")
@@ -2959,6 +3054,18 @@ module RIMS::Test
2959
3054
  assert_msg_flags(3, seen: false, recent: true)
2960
3055
  }
2961
3056
 
3057
+ assert(10 < @simple_mail.raw_source.bytesize)
3058
+ assert(10 + 10 < @simple_mail.raw_source.bytesize)
3059
+ assert_imap_command('FETCH 2 BODY[]<10.10>', uid: true) {|assert|
3060
+ assert.equal_lines("* 1 FETCH (UID 2 BODY[]<10> #{literal(@simple_mail.raw_source[10, 10])})".b)
3061
+ assert.equal("#{tag} OK FETCH completed")
3062
+ }
3063
+
3064
+ open_mail_store{
3065
+ assert_msg_flags(2, seen: false, recent: true)
3066
+ assert_msg_flags(3, seen: false, recent: true)
3067
+ }
3068
+
2962
3069
  assert_imap_command('FETCH 3 (UID BODY.PEEK[1])', uid: true) {|assert|
2963
3070
  assert.equal_lines(%Q'* 2 FETCH (UID 3 BODY[1] "#{@mpart_mail.parts[0].body.raw_source}")'.b)
2964
3071
  assert.equal("#{tag} OK FETCH completed")
@@ -2969,6 +3076,10 @@ module RIMS::Test
2969
3076
  assert_msg_flags(3, seen: false, recent: true)
2970
3077
  }
2971
3078
 
3079
+ assert_imap_command('FETCH 1 bad-fetch-attr') {|assert|
3080
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
3081
+ }
3082
+
2972
3083
  assert_imap_command('LOGOUT') {|assert|
2973
3084
  assert.match(/^\* BYE /)
2974
3085
  assert.equal("#{tag} OK LOGOUT completed")
@@ -3012,7 +3123,7 @@ module RIMS::Test
3012
3123
  end
3013
3124
 
3014
3125
  assert_imap_command('STORE 1 +FLAGS (\Answered)') {|assert|
3015
- assert.match(/^#{tag} NO /)
3126
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/)
3016
3127
  }
3017
3128
 
3018
3129
  assert_imap_command('LOGIN foo open_sesame') {|assert|
@@ -3025,7 +3136,7 @@ module RIMS::Test
3025
3136
  end
3026
3137
 
3027
3138
  assert_imap_command('STORE 1 +FLAGS (\Answered)') {|assert|
3028
- assert.match(/^#{tag} NO /)
3139
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not selected/)
3029
3140
  }
3030
3141
 
3031
3142
  assert_imap_command('SELECT INBOX') {|assert|
@@ -3249,6 +3360,78 @@ module RIMS::Test
3249
3360
  assert_mbox_flag_num(answered: 4, flagged: 3, deleted: 2, seen: 1, draft: 0, recent: 5)
3250
3361
  }
3251
3362
 
3363
+ assert_imap_command('STORE 1:5 +FLAGS ()') {|assert|
3364
+ assert.equal('* 1 FETCH (FLAGS (\Recent))')
3365
+ assert.equal('* 2 FETCH (FLAGS (\Answered \Recent))')
3366
+ assert.equal('* 3 FETCH (FLAGS (\Answered \Flagged \Recent))')
3367
+ assert.equal('* 4 FETCH (FLAGS (\Answered \Flagged \Deleted \Recent))')
3368
+ assert.equal('* 5 FETCH (FLAGS (\Answered \Flagged \Deleted \Seen \Recent))')
3369
+ assert.equal("#{tag} OK STORE completed")
3370
+ }
3371
+
3372
+ open_mail_store{
3373
+ assert_msg_uid( 1, 3, 5, 7, 9)
3374
+ assert_flag_enabled_msgs('answered', 3, 5, 7, 9)
3375
+ assert_flag_enabled_msgs('flagged' , 5, 7, 9)
3376
+ assert_flag_enabled_msgs('deleted' , 7, 9)
3377
+ assert_flag_enabled_msgs('seen' , 9)
3378
+ assert_flag_enabled_msgs('draft' , )
3379
+ assert_flag_enabled_msgs('recent' , 1, 3, 5, 7, 9)
3380
+ assert_mbox_flag_num(answered: 4, flagged: 3, deleted: 2, seen: 1, draft: 0, recent: 5)
3381
+ }
3382
+
3383
+ assert_imap_command('STORE 1:5 -FLAGS ()') {|assert|
3384
+ assert.equal('* 1 FETCH (FLAGS (\Recent))')
3385
+ assert.equal('* 2 FETCH (FLAGS (\Answered \Recent))')
3386
+ assert.equal('* 3 FETCH (FLAGS (\Answered \Flagged \Recent))')
3387
+ assert.equal('* 4 FETCH (FLAGS (\Answered \Flagged \Deleted \Recent))')
3388
+ assert.equal('* 5 FETCH (FLAGS (\Answered \Flagged \Deleted \Seen \Recent))')
3389
+ assert.equal("#{tag} OK STORE completed")
3390
+ }
3391
+
3392
+ open_mail_store{
3393
+ assert_msg_uid( 1, 3, 5, 7, 9)
3394
+ assert_flag_enabled_msgs('answered', 3, 5, 7, 9)
3395
+ assert_flag_enabled_msgs('flagged' , 5, 7, 9)
3396
+ assert_flag_enabled_msgs('deleted' , 7, 9)
3397
+ assert_flag_enabled_msgs('seen' , 9)
3398
+ assert_flag_enabled_msgs('draft' , )
3399
+ assert_flag_enabled_msgs('recent' , 1, 3, 5, 7, 9)
3400
+ assert_mbox_flag_num(answered: 4, flagged: 3, deleted: 2, seen: 1, draft: 0, recent: 5)
3401
+ }
3402
+
3403
+ assert_imap_command('STORE 1:5 FLAGS ()') {|assert|
3404
+ assert.equal('* 1 FETCH (FLAGS (\Recent))')
3405
+ assert.equal('* 2 FETCH (FLAGS (\Recent))')
3406
+ assert.equal('* 3 FETCH (FLAGS (\Recent))')
3407
+ assert.equal('* 4 FETCH (FLAGS (\Recent))')
3408
+ assert.equal('* 5 FETCH (FLAGS (\Recent))')
3409
+ assert.equal("#{tag} OK STORE completed")
3410
+ }
3411
+
3412
+ open_mail_store{
3413
+ assert_msg_uid( 1, 3, 5, 7, 9)
3414
+ assert_flag_enabled_msgs('answered', )
3415
+ assert_flag_enabled_msgs('flagged' , )
3416
+ assert_flag_enabled_msgs('deleted' , )
3417
+ assert_flag_enabled_msgs('seen' , )
3418
+ assert_flag_enabled_msgs('draft' , )
3419
+ assert_flag_enabled_msgs('recent' , 1, 3, 5, 7, 9)
3420
+ assert_mbox_flag_num(answered: 0, flagged: 0, deleted: 0, seen: 0, draft: 0, recent: 5)
3421
+ }
3422
+
3423
+ assert_imap_command('STORE 1 DETARAME (\Flagged)') {|assert|
3424
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
3425
+ }
3426
+
3427
+ assert_imap_command('STORE 1 FLAGS (\Detarame)') {|assert|
3428
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
3429
+ }
3430
+
3431
+ assert_imap_command('STORE 1 FLAGS NIL') {|assert|
3432
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
3433
+ }
3434
+
3252
3435
  assert_imap_command('LOGOUT') {|assert|
3253
3436
  assert.match(/^\* BYE /)
3254
3437
  assert.equal("#{tag} OK LOGOUT completed")
@@ -3292,7 +3475,7 @@ module RIMS::Test
3292
3475
  end
3293
3476
 
3294
3477
  assert_imap_command('STORE 1 +FLAGS.SILENT (\Answered)') {|assert|
3295
- assert.match(/^#{tag} NO /)
3478
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/)
3296
3479
  }
3297
3480
 
3298
3481
  assert_imap_command('LOGIN foo open_sesame') {|assert|
@@ -3305,7 +3488,7 @@ module RIMS::Test
3305
3488
  end
3306
3489
 
3307
3490
  assert_imap_command('STORE 1 +FLAGS.SILENT (\Answered)') {|assert|
3308
- assert.match(/^#{tag} NO /)
3491
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not selected/)
3309
3492
  }
3310
3493
 
3311
3494
  assert_imap_command('SELECT INBOX') {|assert|
@@ -3494,6 +3677,63 @@ module RIMS::Test
3494
3677
  assert_mbox_flag_num(answered: 4, flagged: 3, deleted: 2, seen: 1, draft: 0, recent: 5)
3495
3678
  }
3496
3679
 
3680
+ assert_imap_command('STORE 1:5 +FLAGS.SILENT ()') {|assert|
3681
+ assert.equal("#{tag} OK STORE completed")
3682
+ }
3683
+
3684
+ open_mail_store{
3685
+ assert_msg_uid( 1, 3, 5, 7, 9)
3686
+ assert_flag_enabled_msgs('answered', 3, 5, 7, 9)
3687
+ assert_flag_enabled_msgs('flagged' , 5, 7, 9)
3688
+ assert_flag_enabled_msgs('deleted' , 7, 9)
3689
+ assert_flag_enabled_msgs('seen' , 9)
3690
+ assert_flag_enabled_msgs('draft' , )
3691
+ assert_flag_enabled_msgs('recent' , 1, 3, 5, 7, 9)
3692
+ assert_mbox_flag_num(answered: 4, flagged: 3, deleted: 2, seen: 1, draft: 0, recent: 5)
3693
+ }
3694
+
3695
+ assert_imap_command('STORE 1:5 -FLAGS.SILENT ()') {|assert|
3696
+ assert.equal("#{tag} OK STORE completed")
3697
+ }
3698
+
3699
+ open_mail_store{
3700
+ assert_msg_uid( 1, 3, 5, 7, 9)
3701
+ assert_flag_enabled_msgs('answered', 3, 5, 7, 9)
3702
+ assert_flag_enabled_msgs('flagged' , 5, 7, 9)
3703
+ assert_flag_enabled_msgs('deleted' , 7, 9)
3704
+ assert_flag_enabled_msgs('seen' , 9)
3705
+ assert_flag_enabled_msgs('draft' , )
3706
+ assert_flag_enabled_msgs('recent' , 1, 3, 5, 7, 9)
3707
+ assert_mbox_flag_num(answered: 4, flagged: 3, deleted: 2, seen: 1, draft: 0, recent: 5)
3708
+ }
3709
+
3710
+ assert_imap_command('STORE 1:5 FLAGS.SILENT ()') {|assert|
3711
+ assert.equal("#{tag} OK STORE completed")
3712
+ }
3713
+
3714
+ open_mail_store{
3715
+ assert_msg_uid( 1, 3, 5, 7, 9)
3716
+ assert_flag_enabled_msgs('answered', )
3717
+ assert_flag_enabled_msgs('flagged' , )
3718
+ assert_flag_enabled_msgs('deleted' , )
3719
+ assert_flag_enabled_msgs('seen' , )
3720
+ assert_flag_enabled_msgs('draft' , )
3721
+ assert_flag_enabled_msgs('recent' , 1, 3, 5, 7, 9)
3722
+ assert_mbox_flag_num(answered: 0, flagged: 0, deleted: 0, seen: 0, draft: 0, recent: 5)
3723
+ }
3724
+
3725
+ assert_imap_command('STORE 1 FLAGS.DETARAME (\Flagged)') {|assert|
3726
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
3727
+ }
3728
+
3729
+ assert_imap_command('STORE 1 FLAGS.SILENT (\Detarame)') {|assert|
3730
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
3731
+ }
3732
+
3733
+ assert_imap_command('STORE 1 FLAGS.SILENT NIL') {|assert|
3734
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
3735
+ }
3736
+
3497
3737
  assert_imap_command('LOGOUT') {|assert|
3498
3738
  assert.match(/^\* BYE /)
3499
3739
  assert.equal("#{tag} OK LOGOUT completed")
@@ -3537,7 +3777,7 @@ module RIMS::Test
3537
3777
  end
3538
3778
 
3539
3779
  assert_imap_command('STORE 1 +FLAGS (\Answered)', uid: true) {|assert|
3540
- assert.match(/^#{tag} NO /)
3780
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/)
3541
3781
  }
3542
3782
 
3543
3783
  assert_imap_command('LOGIN foo open_sesame') {|assert|
@@ -3550,7 +3790,7 @@ module RIMS::Test
3550
3790
  end
3551
3791
 
3552
3792
  assert_imap_command('STORE 1 +FLAGS (\Answered)', uid: true) {|assert|
3553
- assert.match(/^#{tag} NO /)
3793
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not selected/)
3554
3794
  }
3555
3795
 
3556
3796
  assert_imap_command('SELECT INBOX') {|assert|
@@ -3774,6 +4014,78 @@ module RIMS::Test
3774
4014
  assert_mbox_flag_num(answered: 4, flagged: 3, deleted: 2, seen: 1, draft: 0, recent: 5)
3775
4015
  }
3776
4016
 
4017
+ assert_imap_command('STORE 1,3,5,7,9 +FLAGS ()', uid: true) {|assert|
4018
+ assert.equal('* 1 FETCH (UID 1 FLAGS (\Recent))')
4019
+ assert.equal('* 2 FETCH (UID 3 FLAGS (\Answered \Recent))')
4020
+ assert.equal('* 3 FETCH (UID 5 FLAGS (\Answered \Flagged \Recent))')
4021
+ assert.equal('* 4 FETCH (UID 7 FLAGS (\Answered \Flagged \Deleted \Recent))')
4022
+ assert.equal('* 5 FETCH (UID 9 FLAGS (\Answered \Flagged \Deleted \Seen \Recent))')
4023
+ assert.equal("#{tag} OK STORE completed")
4024
+ }
4025
+
4026
+ open_mail_store{
4027
+ assert_msg_uid( 1, 3, 5, 7, 9)
4028
+ assert_flag_enabled_msgs('answered', 3, 5, 7, 9)
4029
+ assert_flag_enabled_msgs('flagged' , 5, 7, 9)
4030
+ assert_flag_enabled_msgs('deleted' , 7, 9)
4031
+ assert_flag_enabled_msgs('seen' , 9)
4032
+ assert_flag_enabled_msgs('draft' , )
4033
+ assert_flag_enabled_msgs('recent' , 1, 3, 5, 7, 9)
4034
+ assert_mbox_flag_num(answered: 4, flagged: 3, deleted: 2, seen: 1, draft: 0, recent: 5)
4035
+ }
4036
+
4037
+ assert_imap_command('STORE 1,3,5,7,9 -FLAGS ()', uid: true) {|assert|
4038
+ assert.equal('* 1 FETCH (UID 1 FLAGS (\Recent))')
4039
+ assert.equal('* 2 FETCH (UID 3 FLAGS (\Answered \Recent))')
4040
+ assert.equal('* 3 FETCH (UID 5 FLAGS (\Answered \Flagged \Recent))')
4041
+ assert.equal('* 4 FETCH (UID 7 FLAGS (\Answered \Flagged \Deleted \Recent))')
4042
+ assert.equal('* 5 FETCH (UID 9 FLAGS (\Answered \Flagged \Deleted \Seen \Recent))')
4043
+ assert.equal("#{tag} OK STORE completed")
4044
+ }
4045
+
4046
+ open_mail_store{
4047
+ assert_msg_uid( 1, 3, 5, 7, 9)
4048
+ assert_flag_enabled_msgs('answered', 3, 5, 7, 9)
4049
+ assert_flag_enabled_msgs('flagged' , 5, 7, 9)
4050
+ assert_flag_enabled_msgs('deleted' , 7, 9)
4051
+ assert_flag_enabled_msgs('seen' , 9)
4052
+ assert_flag_enabled_msgs('draft' , )
4053
+ assert_flag_enabled_msgs('recent' , 1, 3, 5, 7, 9)
4054
+ assert_mbox_flag_num(answered: 4, flagged: 3, deleted: 2, seen: 1, draft: 0, recent: 5)
4055
+ }
4056
+
4057
+ assert_imap_command('STORE 1,3,5,7,9 FLAGS ()', uid: true) {|assert|
4058
+ assert.equal('* 1 FETCH (UID 1 FLAGS (\Recent))')
4059
+ assert.equal('* 2 FETCH (UID 3 FLAGS (\Recent))')
4060
+ assert.equal('* 3 FETCH (UID 5 FLAGS (\Recent))')
4061
+ assert.equal('* 4 FETCH (UID 7 FLAGS (\Recent))')
4062
+ assert.equal('* 5 FETCH (UID 9 FLAGS (\Recent))')
4063
+ assert.equal("#{tag} OK STORE completed")
4064
+ }
4065
+
4066
+ open_mail_store{
4067
+ assert_msg_uid( 1, 3, 5, 7, 9)
4068
+ assert_flag_enabled_msgs('answered', )
4069
+ assert_flag_enabled_msgs('flagged' , )
4070
+ assert_flag_enabled_msgs('deleted' , )
4071
+ assert_flag_enabled_msgs('seen' , )
4072
+ assert_flag_enabled_msgs('draft' , )
4073
+ assert_flag_enabled_msgs('recent' , 1, 3, 5, 7, 9)
4074
+ assert_mbox_flag_num(answered: 0, flagged: 0, deleted: 0, seen: 0, draft: 0, recent: 5)
4075
+ }
4076
+
4077
+ assert_imap_command('STORE 1 DETARAME (\Flagged)', uid: true) {|assert|
4078
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
4079
+ }
4080
+
4081
+ assert_imap_command('STORE 1 FLAGS (\Detarame)', uid: true) {|assert|
4082
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
4083
+ }
4084
+
4085
+ assert_imap_command('STORE 1 FLAGS NIL', uid: true) {|assert|
4086
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
4087
+ }
4088
+
3777
4089
  assert_imap_command('LOGOUT') {|assert|
3778
4090
  assert.match(/^\* BYE /)
3779
4091
  assert.equal("#{tag} OK LOGOUT completed")
@@ -3817,7 +4129,7 @@ module RIMS::Test
3817
4129
  end
3818
4130
 
3819
4131
  assert_imap_command('STORE 1 +FLAGS.SILENT (\Answered)', uid: true) {|assert|
3820
- assert.match(/^#{tag} NO /)
4132
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/)
3821
4133
  }
3822
4134
 
3823
4135
  assert_imap_command('LOGIN foo open_sesame') {|assert|
@@ -3830,7 +4142,7 @@ module RIMS::Test
3830
4142
  end
3831
4143
 
3832
4144
  assert_imap_command('STORE 1 +FLAGS.SILENT (\Answered)', uid: true) {|assert|
3833
- assert.match(/^#{tag} NO /)
4145
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not selected/)
3834
4146
  }
3835
4147
 
3836
4148
  assert_imap_command('SELECT INBOX') {|assert|
@@ -4019,6 +4331,63 @@ module RIMS::Test
4019
4331
  assert_mbox_flag_num(answered: 4, flagged: 3, deleted: 2, seen: 1, draft: 0, recent: 5)
4020
4332
  }
4021
4333
 
4334
+ assert_imap_command('STORE 1,3,5,7,9 +FLAGS.SILENT ()', uid: true) {|assert|
4335
+ assert.equal("#{tag} OK STORE completed")
4336
+ }
4337
+
4338
+ open_mail_store{
4339
+ assert_msg_uid( 1, 3, 5, 7, 9)
4340
+ assert_flag_enabled_msgs('answered', 3, 5, 7, 9)
4341
+ assert_flag_enabled_msgs('flagged' , 5, 7, 9)
4342
+ assert_flag_enabled_msgs('deleted' , 7, 9)
4343
+ assert_flag_enabled_msgs('seen' , 9)
4344
+ assert_flag_enabled_msgs('draft' , )
4345
+ assert_flag_enabled_msgs('recent' , 1, 3, 5, 7, 9)
4346
+ assert_mbox_flag_num(answered: 4, flagged: 3, deleted: 2, seen: 1, draft: 0, recent: 5)
4347
+ }
4348
+
4349
+ assert_imap_command('STORE 1,3,5,7,9 -FLAGS.SILENT ()', uid: true) {|assert|
4350
+ assert.equal("#{tag} OK STORE completed")
4351
+ }
4352
+
4353
+ open_mail_store{
4354
+ assert_msg_uid( 1, 3, 5, 7, 9)
4355
+ assert_flag_enabled_msgs('answered', 3, 5, 7, 9)
4356
+ assert_flag_enabled_msgs('flagged' , 5, 7, 9)
4357
+ assert_flag_enabled_msgs('deleted' , 7, 9)
4358
+ assert_flag_enabled_msgs('seen' , 9)
4359
+ assert_flag_enabled_msgs('draft' , )
4360
+ assert_flag_enabled_msgs('recent' , 1, 3, 5, 7, 9)
4361
+ assert_mbox_flag_num(answered: 4, flagged: 3, deleted: 2, seen: 1, draft: 0, recent: 5)
4362
+ }
4363
+
4364
+ assert_imap_command('STORE 1,3,5,7,9 FLAGS.SILENT ()', uid: true) {|assert|
4365
+ assert.equal("#{tag} OK STORE completed")
4366
+ }
4367
+
4368
+ open_mail_store{
4369
+ assert_msg_uid( 1, 3, 5, 7, 9)
4370
+ assert_flag_enabled_msgs('answered', )
4371
+ assert_flag_enabled_msgs('flagged' , )
4372
+ assert_flag_enabled_msgs('deleted' , )
4373
+ assert_flag_enabled_msgs('seen' , )
4374
+ assert_flag_enabled_msgs('draft' , )
4375
+ assert_flag_enabled_msgs('recent' , 1, 3, 5, 7, 9)
4376
+ assert_mbox_flag_num(answered: 0, flagged: 0, deleted: 0, seen: 0, draft: 0, recent: 5)
4377
+ }
4378
+
4379
+ assert_imap_command('STORE 1 FLAGS.DETARAME (\Flagged)', uid: true) {|assert|
4380
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
4381
+ }
4382
+
4383
+ assert_imap_command('STORE 1 FLAGS.SILENT (\Detarame)', uid: true) {|assert|
4384
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
4385
+ }
4386
+
4387
+ assert_imap_command('STORE 1 FLAGS.SILENT NIL', uid: true) {|assert|
4388
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
4389
+ }
4390
+
4022
4391
  assert_imap_command('LOGOUT') {|assert|
4023
4392
  assert.match(/^\* BYE /)
4024
4393
  assert.equal("#{tag} OK LOGOUT completed")
@@ -4054,7 +4423,7 @@ module RIMS::Test
4054
4423
  end
4055
4424
 
4056
4425
  assert_imap_command('STORE 1 +FLAGS (\Answered \Flagged \Deleted \Seen \Draft)') {|assert|
4057
- assert.match(/^#{tag} NO /)
4426
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/)
4058
4427
  }
4059
4428
 
4060
4429
  open_mail_store{
@@ -4075,7 +4444,7 @@ module RIMS::Test
4075
4444
  end
4076
4445
 
4077
4446
  assert_imap_command('STORE 1 +FLAGS (\Answered \Flagged \Deleted \Seen \Draft)') {|assert|
4078
- assert.match(/^#{tag} NO /)
4447
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not selected/)
4079
4448
  }
4080
4449
 
4081
4450
  open_mail_store{
@@ -4093,7 +4462,7 @@ module RIMS::Test
4093
4462
  end
4094
4463
 
4095
4464
  assert_imap_command('STORE 1 +FLAGS (\Answered \Flagged \Deleted \Seen \Draft)') {|assert|
4096
- assert.match(/^#{tag} NO /)
4465
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/cannot store.* read-only/)
4097
4466
  }
4098
4467
 
4099
4468
  open_mail_store{
@@ -4101,7 +4470,7 @@ module RIMS::Test
4101
4470
  }
4102
4471
 
4103
4472
  assert_imap_command('STORE 1 FLAGS (\Answered \Flagged \Deleted \Seen \Draft)') {|assert|
4104
- assert.match(/^#{tag} NO /)
4473
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/cannot store.* read-only/)
4105
4474
  }
4106
4475
 
4107
4476
  open_mail_store{
@@ -4109,7 +4478,7 @@ module RIMS::Test
4109
4478
  }
4110
4479
 
4111
4480
  assert_imap_command('STORE 1 -FLAGS (\Answered \Flagged \Deleted \Seen \Draft)') {|assert|
4112
- assert.match(/^#{tag} NO /)
4481
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/cannot store.* read-only/)
4113
4482
  }
4114
4483
 
4115
4484
  open_mail_store{
@@ -4117,7 +4486,7 @@ module RIMS::Test
4117
4486
  }
4118
4487
 
4119
4488
  assert_imap_command('STORE 1 +FLAGS.SILENT (\Answered \Flagged \Deleted \Seen \Draft)') {|assert|
4120
- assert.match(/^#{tag} NO /)
4489
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/cannot store.* read-only/)
4121
4490
  }
4122
4491
 
4123
4492
  open_mail_store{
@@ -4125,7 +4494,7 @@ module RIMS::Test
4125
4494
  }
4126
4495
 
4127
4496
  assert_imap_command('STORE 1 FLAGS.SILENT (\Answered \Flagged \Deleted \Seen \Draft)') {|assert|
4128
- assert.match(/^#{tag} NO /)
4497
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/cannot store.* read-only/)
4129
4498
  }
4130
4499
 
4131
4500
  open_mail_store{
@@ -4133,7 +4502,7 @@ module RIMS::Test
4133
4502
  }
4134
4503
 
4135
4504
  assert_imap_command('STORE 1 -FLAGS.SILENT (\Answered \Flagged \Deleted \Seen \Draft)') {|assert|
4136
- assert.match(/^#{tag} NO /)
4505
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/cannot store.* read-only/)
4137
4506
  }
4138
4507
 
4139
4508
  open_mail_store{
@@ -4141,7 +4510,7 @@ module RIMS::Test
4141
4510
  }
4142
4511
 
4143
4512
  assert_imap_command('STORE 1 +FLAGS (\Answered \Flagged \Deleted \Seen \Draft)', uid: true) {|assert|
4144
- assert.match(/^#{tag} NO /)
4513
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/cannot store.* read-only/)
4145
4514
  }
4146
4515
 
4147
4516
  open_mail_store{
@@ -4149,7 +4518,7 @@ module RIMS::Test
4149
4518
  }
4150
4519
 
4151
4520
  assert_imap_command('STORE 1 FLAGS (\Answered \Flagged \Deleted \Seen \Draft)', uid: true) {|assert|
4152
- assert.match(/^#{tag} NO /)
4521
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/cannot store.* read-only/)
4153
4522
  }
4154
4523
 
4155
4524
  open_mail_store{
@@ -4157,7 +4526,7 @@ module RIMS::Test
4157
4526
  }
4158
4527
 
4159
4528
  assert_imap_command('STORE 1 -FLAGS (\Answered \Flagged \Deleted \Seen \Draft)', uid: true) {|assert|
4160
- assert.match(/^#{tag} NO /)
4529
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/cannot store.* read-only/)
4161
4530
  }
4162
4531
 
4163
4532
  open_mail_store{
@@ -4165,7 +4534,7 @@ module RIMS::Test
4165
4534
  }
4166
4535
 
4167
4536
  assert_imap_command('STORE 1 +FLAGS.SILENT (\Answered \Flagged \Deleted \Seen \Draft)', uid: true) {|assert|
4168
- assert.match(/^#{tag} NO /)
4537
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/cannot store.* read-only/)
4169
4538
  }
4170
4539
 
4171
4540
  open_mail_store{
@@ -4173,7 +4542,7 @@ module RIMS::Test
4173
4542
  }
4174
4543
 
4175
4544
  assert_imap_command('STORE 1 FLAGS.SILENT (\Answered \Flagged \Deleted \Seen \Draft)', uid: true) {|assert|
4176
- assert.match(/^#{tag} NO /)
4545
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/cannot store.* read-only/)
4177
4546
  }
4178
4547
 
4179
4548
  open_mail_store{
@@ -4181,7 +4550,7 @@ module RIMS::Test
4181
4550
  }
4182
4551
 
4183
4552
  assert_imap_command('STORE 1 -FLAGS.SILENT (\Answered \Flagged \Deleted \Seen \Draft)', uid: true) {|assert|
4184
- assert.match(/^#{tag} NO /)
4553
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/cannot store.* read-only/)
4185
4554
  }
4186
4555
 
4187
4556
  open_mail_store{
@@ -4247,7 +4616,7 @@ module RIMS::Test
4247
4616
  end
4248
4617
 
4249
4618
  assert_imap_command('COPY 2:4 WORK') {|assert|
4250
- assert.match(/^#{tag} NO /, peek_next_line: true).no_match(/\[TRYCREATE\]/)
4619
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/, peek_next_line: true).no_match(/\[TRYCREATE\]/)
4251
4620
  }
4252
4621
 
4253
4622
  if (command_test?) then
@@ -4265,7 +4634,7 @@ module RIMS::Test
4265
4634
  end
4266
4635
 
4267
4636
  assert_imap_command('COPY 2:4 WORK') {|assert|
4268
- assert.match(/^#{tag} NO /, peek_next_line: true).no_match(/\[TRYCREATE\]/)
4637
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not selected/, peek_next_line: true).no_match(/\[TRYCREATE\]/)
4269
4638
  }
4270
4639
 
4271
4640
  assert_imap_command('SELECT INBOX') {|assert|
@@ -4389,7 +4758,7 @@ module RIMS::Test
4389
4758
  }
4390
4759
 
4391
4760
  assert_imap_command('COPY 1:* nobox') {|assert|
4392
- assert.match(/^#{tag} NO \[TRYCREATE\]/)
4761
+ assert.match(/^#{tag} NO \[TRYCREATE\]/, peek_next_line: true).match(/not found.* mailbox/)
4393
4762
  }
4394
4763
 
4395
4764
  assert_imap_command('LOGOUT') {|assert|
@@ -4451,7 +4820,7 @@ module RIMS::Test
4451
4820
  end
4452
4821
 
4453
4822
  assert_imap_command('COPY 3,5,7 WORK', uid: true) {|assert|
4454
- assert.match(/^#{tag} NO /, peek_next_line: true).no_match(/\[TRYCREATE\]/)
4823
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not auth/, peek_next_line: true).no_match(/\[TRYCREATE\]/)
4455
4824
  }
4456
4825
 
4457
4826
  if (command_test?) then
@@ -4469,7 +4838,7 @@ module RIMS::Test
4469
4838
  end
4470
4839
 
4471
4840
  assert_imap_command('COPY 3,5,7 WORK', uid: true) {|assert|
4472
- assert.match(/^#{tag} NO /, peek_next_line: true).no_match(/\[TRYCREATE\]/)
4841
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not selected/, peek_next_line: true).no_match(/\[TRYCREATE\]/)
4473
4842
  }
4474
4843
 
4475
4844
  assert_imap_command('SELECT INBOX') {|assert|
@@ -4593,7 +4962,7 @@ module RIMS::Test
4593
4962
  }
4594
4963
 
4595
4964
  assert_imap_command('COPY 1:* nobox', uid: true) {|assert|
4596
- assert.match(/^#{tag} NO \[TRYCREATE\]/)
4965
+ assert.match(/^#{tag} NO \[TRYCREATE\]/, peek_next_line: true).match(/not found.* mailbox/)
4597
4966
  }
4598
4967
 
4599
4968
  assert_imap_command('LOGOUT') {|assert|
@@ -4794,24 +5163,24 @@ module RIMS::Test
4794
5163
  end
4795
5164
 
4796
5165
  assert_imap_command('IDLE', client_input_text: "DONE\r\n") {|assert|
4797
- assert.equal('+ continue')
5166
+ assert.match(/^\+ /)
4798
5167
  assert.equal("#{tag} OK IDLE terminated")
4799
5168
  }
4800
5169
 
4801
5170
  assert_imap_command('IDLE', client_input_text: "done\r\n") {|assert|
4802
- assert.equal('+ continue')
5171
+ assert.match(/^\+ /)
4803
5172
  assert.equal("#{tag} OK IDLE terminated")
4804
5173
  }
4805
5174
 
4806
5175
  assert_imap_command('IDLE', client_input_text: "detarame\r\n") {|assert|
4807
- assert.equal('+ continue')
5176
+ assert.match(/^\+ /)
4808
5177
  assert.equal("#{tag} BAD unexpected client response")
4809
5178
  }
4810
5179
 
4811
5180
  if (command_test?) then
4812
5181
  # not be able to close client input in stream test
4813
5182
  assert_imap_command('IDLE', client_input_text: '') {|assert|
4814
- assert.equal('+ continue')
5183
+ assert.match(/^\+ /)
4815
5184
  assert.equal("#{tag} BAD unexpected client connection close")
4816
5185
  }
4817
5186
  end
@@ -4840,7 +5209,7 @@ module RIMS::Test
4840
5209
  end
4841
5210
 
4842
5211
  assert_imap_command('IDLE', client_input_text: "DONE\r\n") {|assert|
4843
- assert.equal('+ continue')
5212
+ assert.match(/^\+ /)
4844
5213
  assert.equal("#{tag} OK IDLE terminated")
4845
5214
  }
4846
5215
 
@@ -4950,71 +5319,71 @@ module RIMS::Test
4950
5319
  }
4951
5320
 
4952
5321
  assert_imap_command('SELECT INBOX') {|assert|
4953
- assert.match(/#{tag} NO not allowed command/)
5322
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not allowed/)
4954
5323
  }
4955
5324
 
4956
5325
  assert_imap_command('EXAMINE INBOX') {|assert|
4957
- assert.match(/#{tag} NO not allowed command/)
5326
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not allowed/)
4958
5327
  }
4959
5328
 
4960
5329
  assert_imap_command('CREATE foo') {|assert|
4961
- assert.match(/#{tag} NO not allowed command/)
5330
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not allowed/)
4962
5331
  }
4963
5332
 
4964
5333
  assert_imap_command('DELETE foo') {|assert|
4965
- assert.match(/#{tag} NO not allowed command/)
5334
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not allowed/)
4966
5335
  }
4967
5336
 
4968
5337
  assert_imap_command('RENAME foo bar') {|assert|
4969
- assert.match(/#{tag} NO not allowed command/)
5338
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not allowed/)
4970
5339
  }
4971
5340
 
4972
5341
  assert_imap_command('SUBSCRIBE foo') {|assert|
4973
- assert.match(/#{tag} NO not allowed command/)
5342
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not allowed/)
4974
5343
  }
4975
5344
 
4976
5345
  assert_imap_command('UNSUBSCRIBE foo') {|assert|
4977
- assert.match(/#{tag} NO not allowed command/)
5346
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not allowed/)
4978
5347
  }
4979
5348
 
4980
5349
  assert_imap_command('LIST "" *') {|assert|
4981
- assert.match(/#{tag} NO not allowed command/)
5350
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not allowed/)
4982
5351
  }
4983
5352
 
4984
5353
  assert_imap_command('LSUB "" *') {|assert|
4985
- assert.match(/#{tag} NO not allowed command/)
5354
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not allowed/)
4986
5355
  }
4987
5356
 
4988
5357
  assert_imap_command('STATUS INBOX (MESSAGES RECENT UIDNEXT UIDVALIDITY UNSEEN)') {|assert|
4989
- assert.match(/#{tag} NO not allowed command/)
5358
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not allowed/)
4990
5359
  }
4991
5360
 
4992
5361
  assert_imap_command('CHECK') {|assert|
4993
- assert.match(/#{tag} NO not allowed command/)
5362
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not allowed/)
4994
5363
  }
4995
5364
 
4996
5365
  assert_imap_command('CLOSE') {|assert|
4997
- assert.match(/#{tag} NO not allowed command/)
5366
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not allowed/)
4998
5367
  }
4999
5368
 
5000
5369
  assert_imap_command('EXPUNGE') {|assert|
5001
- assert.match(/#{tag} NO not allowed command/)
5370
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not allowed/)
5002
5371
  }
5003
5372
 
5004
5373
  assert_imap_command('SEARCH *') {|assert|
5005
- assert.match(/#{tag} NO not allowed command/)
5374
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not allowed/)
5006
5375
  }
5007
5376
 
5008
5377
  assert_imap_command('FETCH * RFC822') {|assert|
5009
- assert.match(/#{tag} NO not allowed command/)
5378
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not allowed/)
5010
5379
  }
5011
5380
 
5012
5381
  assert_imap_command('STORE 1 +FLAGS (\Answered \Flagged \Deleted \Seen \Draft)') {|assert|
5013
- assert.match(/#{tag} NO not allowed command/)
5382
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not allowed/)
5014
5383
  }
5015
5384
 
5016
5385
  assert_imap_command('COPY * foo') {|assert|
5017
- assert.match(/#{tag} NO not allowed command/)
5386
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not allowed/)
5018
5387
  }
5019
5388
 
5020
5389
  base64_foo = RIMS::Protocol.encode_base64('foo')
@@ -5042,7 +5411,7 @@ module RIMS::Test
5042
5411
  }
5043
5412
 
5044
5413
  assert_imap_command(%Q'APPEND "b64user-mbox #{base64_foo} nobox" x') {|assert|
5045
- assert.match(/^#{tag} NO \[TRYCREATE\]/)
5414
+ assert.match(/^#{tag} NO \[TRYCREATE\]/, peek_next_line: true).match(/not found.* mailbox/)
5046
5415
  }
5047
5416
 
5048
5417
  open_mail_store{
@@ -5050,7 +5419,7 @@ module RIMS::Test
5050
5419
  }
5051
5420
 
5052
5421
  assert_imap_command(%Q'APPEND "b64user-mbox #{base64_nouser} INBOX" x') {|assert|
5053
- assert.match(/^#{tag} NO not found a user/)
5422
+ assert.match(/^#{tag} NO/, peek_next_line: true).match(/not found.* user/)
5054
5423
  }
5055
5424
 
5056
5425
  open_mail_store{
@@ -5058,7 +5427,7 @@ module RIMS::Test
5058
5427
  }
5059
5428
 
5060
5429
  assert_imap_command(%Q'APPEND "unknown-encode-type #{base64_foo} INBOX" x') {|assert|
5061
- assert.match(/^#{tag} BAD /)
5430
+ assert.match(/^#{tag} BAD /, peek_next_line: true).match(/syntax error/)
5062
5431
  }
5063
5432
 
5064
5433
  open_mail_store{
@@ -5264,7 +5633,7 @@ module RIMS::Test
5264
5633
  }
5265
5634
 
5266
5635
  assert_imap_command('IDLE', client_input_text: '') {|assert|
5267
- assert.equal('+ continue')
5636
+ assert.match(/^\+ /)
5268
5637
  }
5269
5638
 
5270
5639
  @limits.command_wait_timeout_seconds = 0.1
@@ -5292,7 +5661,7 @@ module RIMS::Test
5292
5661
  }
5293
5662
 
5294
5663
  assert_imap_command('IDLE', client_input_text: '') {|assert|
5295
- assert.equal('+ continue')
5664
+ assert.match(/^\+ /)
5296
5665
  }
5297
5666
 
5298
5667
  @limits.command_wait_timeout_seconds = 0
@@ -5334,67 +5703,70 @@ module RIMS::Test
5334
5703
  another_decoder = another_decoder.next_decoder
5335
5704
  assert_equal(true, another_decoder.selected?)
5336
5705
 
5706
+ n = 1
5337
5707
  another_decoder.append('tag', 'INBOX', [ :group, '\Deleted' ], 'test', &another_writer)
5338
5708
  assert_imap_command('NOOP') {|assert|
5339
- assert.equal('* 1 EXISTS')
5340
- assert.equal('* 1 RECENT')
5709
+ assert.equal("* #{n} EXISTS")
5710
+ assert.equal("* #{n} RECENT")
5341
5711
  assert.equal("#{tag} OK NOOP completed")
5342
5712
  }
5343
5713
 
5714
+ n += 1
5344
5715
  another_decoder.copy('tag', '1', 'INBOX', &another_writer)
5345
5716
  assert_imap_command('NOOP') {|assert|
5346
- assert.equal('* 2 EXISTS')
5347
- assert.equal('* 2 RECENT')
5717
+ assert.equal("* #{n} EXISTS")
5718
+ assert.equal("* #{n} RECENT")
5348
5719
  assert.equal("#{tag} OK NOOP completed")
5349
5720
  }
5350
5721
 
5722
+ n -= 1
5351
5723
  another_decoder.expunge('tag', &another_writer)
5352
5724
  assert_imap_command('NOOP') {|assert|
5353
5725
  assert.equal('* 1 EXPUNGE')
5354
5726
  assert.equal("#{tag} OK NOOP completed")
5355
5727
  }
5356
- n = 2
5357
5728
 
5729
+ n += 1
5358
5730
  another_decoder.append('tag', 'INBOX', 'test', &another_writer)
5359
5731
  assert_imap_command('CREATE foo') {|assert|
5360
5732
  assert.equal("* #{n} EXISTS")
5361
5733
  assert.equal("* #{n} RECENT")
5362
5734
  assert.equal("#{tag} OK CREATE completed")
5363
5735
  }
5364
- n += 1
5365
5736
 
5737
+ n += 1
5366
5738
  another_decoder.append('tag', 'INBOX', 'test', &another_writer)
5367
5739
  assert_imap_command('RENAME foo bar') {|assert|
5368
5740
  assert.equal("* #{n} EXISTS")
5369
5741
  assert.equal("* #{n} RECENT")
5370
5742
  assert.equal("#{tag} OK RENAME completed")
5371
5743
  }
5372
- n += 1
5373
5744
 
5745
+ n += 1
5374
5746
  another_decoder.append('tag', 'INBOX', 'test', &another_writer)
5375
5747
  assert_imap_command('DELETE bar') {|assert|
5376
5748
  assert.equal("* #{n} EXISTS")
5377
5749
  assert.equal("* #{n} RECENT")
5378
5750
  assert.equal("#{tag} OK DELETE completed")
5379
5751
  }
5380
- n += 1
5381
5752
 
5753
+ n += 1
5382
5754
  another_decoder.append('tag', 'INBOX', 'test', &another_writer)
5383
5755
  assert_imap_command('SUBSCRIBE INBOX') {|assert|
5384
5756
  assert.equal("* #{n} EXISTS")
5385
5757
  assert.equal("* #{n} RECENT")
5386
5758
  assert.equal("#{tag} OK SUBSCRIBE completed")
5387
5759
  }
5388
- n += 1
5389
5760
 
5761
+ n += 1
5390
5762
  another_decoder.append('tag', 'INBOX', 'test', &another_writer)
5391
5763
  assert_imap_command('UNSUBSCRIBE INBOX') {|assert|
5392
5764
  assert.equal("* #{n} EXISTS")
5393
5765
  assert.equal("* #{n} RECENT")
5394
- assert.equal("#{tag} NO not implemented subscribe/unsbscribe command")
5766
+ assert.match(/^#{tag} NO /, peek_next_line: true).match(/not implemented/)
5395
5767
  }
5396
- n += 1
5397
5768
 
5769
+ n += 1
5398
5770
  another_decoder.append('tag', 'INBOX', 'test', &another_writer)
5399
5771
  assert_imap_command('LIST "" *') {|assert|
5400
5772
  assert.equal("* #{n} EXISTS")
@@ -5402,8 +5774,8 @@ module RIMS::Test
5402
5774
  assert.equal('* LIST (\Noinferiors \Marked) NIL "INBOX"')
5403
5775
  assert.equal("#{tag} OK LIST completed")
5404
5776
  }
5405
- n += 1
5406
5777
 
5778
+ n += 1
5407
5779
  another_decoder.append('tag', 'INBOX', 'test', &another_writer)
5408
5780
  assert_imap_command('LSUB "" *') {|assert|
5409
5781
  assert.equal("* #{n} EXISTS")
@@ -5411,8 +5783,8 @@ module RIMS::Test
5411
5783
  assert.equal('* LSUB (\Noinferiors \Marked) NIL "INBOX"')
5412
5784
  assert.equal("#{tag} OK LSUB completed")
5413
5785
  }
5414
- n += 1
5415
5786
 
5787
+ n += 1
5416
5788
  another_decoder.append('tag', 'INBOX', 'test', &another_writer)
5417
5789
  assert_imap_command('STATUS INBOX (MESSAGES RECENT UIDNEXT UIDVALIDITY UNSEEN)') {|assert|
5418
5790
  assert.equal("* #{n} EXISTS")
@@ -5420,34 +5792,35 @@ module RIMS::Test
5420
5792
  assert.equal("* STATUS \"INBOX\" (MESSAGES #{n} RECENT #{n} UIDNEXT #{(n+1).succ} UIDVALIDITY #{@inbox_id} UNSEEN #{n})")
5421
5793
  assert.equal("#{tag} OK STATUS completed")
5422
5794
  }
5423
- n += 1
5424
5795
 
5796
+ n += 1
5425
5797
  another_decoder.append('tag', 'INBOX', 'test', &another_writer)
5798
+ n += 1
5426
5799
  assert_imap_command('APPEND INBOX test') {|assert|
5800
+ assert.equal("* #{n-1} EXISTS")
5801
+ assert.equal("* #{n-1} RECENT")
5427
5802
  assert.equal("* #{n} EXISTS")
5428
5803
  assert.equal("* #{n} RECENT")
5429
- assert.equal("* #{n+1} EXISTS")
5430
- assert.equal("* #{n+1} RECENT")
5431
- assert.equal("#{tag} OK [APPENDUID 1 #{n+2}] APPEND completed")
5804
+ assert.equal("#{tag} OK [APPENDUID 1 #{n+1}] APPEND completed")
5432
5805
  }
5433
- n += 2
5434
5806
 
5807
+ n += 1
5435
5808
  another_decoder.append('tag', 'INBOX', 'test', &another_writer)
5436
5809
  assert_imap_command('CHECK') {|assert|
5437
5810
  assert.equal("* #{n} EXISTS")
5438
5811
  assert.equal("* #{n} RECENT")
5439
5812
  assert.equal("#{tag} OK CHECK completed")
5440
5813
  }
5441
- n += 1
5442
5814
 
5815
+ n += 1
5443
5816
  another_decoder.append('tag', 'INBOX', 'test', &another_writer)
5444
5817
  assert_imap_command('EXPUNGE') {|assert|
5445
5818
  assert.equal("* #{n} EXISTS")
5446
5819
  assert.equal("* #{n} RECENT")
5447
5820
  assert.equal("#{tag} OK EXPUNGE completed")
5448
5821
  }
5449
- n += 1
5450
5822
 
5823
+ n += 1
5451
5824
  another_decoder.append('tag', 'INBOX', 'test', &another_writer)
5452
5825
  assert_imap_command('SEARCH *') {|assert|
5453
5826
  assert.equal("* #{n} EXISTS\r\n")
@@ -5455,8 +5828,8 @@ module RIMS::Test
5455
5828
  assert.equal("* SEARCH #{n}\r\n")
5456
5829
  assert.equal("#{tag} OK SEARCH completed\r\n")
5457
5830
  }
5458
- n += 1
5459
5831
 
5832
+ n += 1
5460
5833
  another_decoder.append('tag', 'INBOX', 'test', &another_writer)
5461
5834
  assert_imap_command('FETCH 1 BODY.PEEK[]') {|assert|
5462
5835
  assert.equal("* #{n} EXISTS")
@@ -5464,8 +5837,8 @@ module RIMS::Test
5464
5837
  assert.equal(%Q'* 1 FETCH (BODY[] "test")')
5465
5838
  assert.equal("#{tag} OK FETCH completed")
5466
5839
  }
5467
- n += 1
5468
5840
 
5841
+ n += 1
5469
5842
  another_decoder.append('tag', 'INBOX', 'test', &another_writer)
5470
5843
  assert_imap_command('STORE 1 +FLAGS (\Flagged)') {|assert|
5471
5844
  assert.equal("* #{n} EXISTS")
@@ -5473,20 +5846,19 @@ module RIMS::Test
5473
5846
  assert.equal('* 1 FETCH (FLAGS (\Flagged \Recent))')
5474
5847
  assert.equal("#{tag} OK STORE completed")
5475
5848
  }
5476
- n += 1
5477
5849
 
5850
+ n += 2
5478
5851
  another_decoder.append('tag', 'INBOX', 'test', &another_writer)
5479
5852
  assert_imap_command('COPY 1 INBOX') {|assert|
5853
+ assert.equal("* #{n-1} EXISTS")
5854
+ assert.equal("* #{n-1} RECENT")
5480
5855
  assert.equal("* #{n} EXISTS")
5481
5856
  assert.equal("* #{n} RECENT")
5482
- assert.equal("* #{n+1} EXISTS")
5483
- assert.equal("* #{n+1} RECENT")
5484
- assert.equal("#{tag} OK [COPYUID 1 2 #{n+2}] COPY completed")
5857
+ assert.equal("#{tag} OK [COPYUID 1 2 #{n+1}] COPY completed")
5485
5858
  }
5486
- n += 2
5487
5859
 
5488
5860
  open_mail_store{
5489
- f = @mail_store.examine_mbox(@inbox_id)
5861
+ f = @mail_store.open_folder(@inbox_id, read_only: true)
5490
5862
  begin
5491
5863
  uid_list = @mail_store.each_msg_uid(@inbox_id).to_a
5492
5864
  last_uid = uid_list.min
@@ -5496,13 +5868,80 @@ module RIMS::Test
5496
5868
  end
5497
5869
  }
5498
5870
 
5871
+ n -= 1
5499
5872
  another_decoder.close('tag', &another_writer)
5500
5873
  assert_imap_command('NOOP') {|assert|
5501
5874
  assert.equal("* 1 EXPUNGE")
5875
+ assert.equal("* 0 RECENT")
5502
5876
  assert.equal("#{tag} OK NOOP completed")
5503
5877
  }
5504
5878
 
5505
- another_decoder.cleanup
5879
+ open_mail_store{
5880
+ f = @mail_store.open_folder(@inbox_id, read_only: true)
5881
+ begin
5882
+ uid_list = @mail_store.each_msg_uid(@inbox_id).to_a
5883
+ last_uid = uid_list.min
5884
+ @mail_store.set_msg_flag(@inbox_id, last_uid, 'deleted', true)
5885
+ ensure
5886
+ f.close
5887
+ end
5888
+ }
5889
+
5890
+ another_decoder.create('tag', 'foo', &another_writer)
5891
+ another_decoder.examine('tag', 'INBOX', &another_writer)
5892
+ another_decoder.examine('tag', 'foo', &another_writer) # closed INBOX implicitly
5893
+ another_decoder.close('tag', 'foo', &another_writer)
5894
+ assert_imap_command('NOOP') {|assert|
5895
+ # no untagged responses on implicit INBOX close because
5896
+ # INBOX is opened as read-only.
5897
+ assert.equal("#{tag} OK NOOP completed")
5898
+ }
5899
+
5900
+ n -= 1
5901
+ another_decoder.select('tag', 'INBOX', &another_writer)
5902
+ another_decoder.select('tag', 'foo', &another_writer) # closed INBOX implicitly
5903
+ another_decoder.close('tag', 'foo', &another_writer)
5904
+ assert_imap_command('NOOP') {|assert|
5905
+ assert.equal("* 1 EXPUNGE")
5906
+ assert.equal("#{tag} OK NOOP completed")
5907
+ }
5908
+
5909
+ n += 1
5910
+ another_decoder.append('tag', 'INBOX', 'test', &another_writer)
5911
+ assert_imap_command('CLOSE') {|assert|
5912
+ # IMAP CLOSE command releases a mailbox that has a status to
5913
+ # be notified, and it will not send untagged responses
5914
+ # notified from other connections.
5915
+ assert.equal("#{tag} OK CLOSE completed")
5916
+ }
5917
+
5918
+ assert_imap_command('EXAMINE INBOX') {|assert|
5919
+ assert.equal("* #{n} EXISTS")
5920
+ assert.equal('* 0 RECENT')
5921
+ assert.equal("* OK [UNSEEN #{n}]")
5922
+ assert.equal('* OK [UIDVALIDITY 1]')
5923
+ assert.equal('* FLAGS (\Answered \Flagged \Deleted \Seen \Draft)')
5924
+ assert.equal("#{tag} OK [READ-ONLY] EXAMINE completed")
5925
+ }
5926
+
5927
+ open_mail_store{
5928
+ f = @mail_store.open_folder(@inbox_id, read_only: true)
5929
+ begin
5930
+ uid_list = @mail_store.each_msg_uid(@inbox_id).to_a
5931
+ last_uid = uid_list.min
5932
+ @mail_store.set_msg_flag(@inbox_id, last_uid, 'deleted', true)
5933
+ ensure
5934
+ f.close
5935
+ end
5936
+ }
5937
+
5938
+ n -= 1
5939
+ another_decoder.select('tag', 'INBOX', &another_writer)
5940
+ another_decoder.cleanup # closed INBOX implicitly
5941
+ assert_imap_command('NOOP') {|assert|
5942
+ assert.equal("* 1 EXPUNGE")
5943
+ assert.equal("#{tag} OK NOOP completed")
5944
+ }
5506
5945
  }
5507
5946
  end
5508
5947
 
@@ -5544,29 +5983,29 @@ module RIMS::Test
5544
5983
 
5545
5984
  another_decoder.append('tag', 'INBOX', [ :group, '\Deleted' ], 'test', &another_writer)
5546
5985
  assert_imap_command('IDLE', client_input_text: "DONE\r\n") {|assert|
5547
- assert.equal_lines("+ continue\r\n" +
5548
- "* 1 EXISTS\r\n" +
5549
- "* 1 RECENT\r\n")
5986
+ assert.match(/^\+ /)
5987
+ assert.equal('* 1 EXISTS')
5988
+ assert.equal('* 1 RECENT')
5550
5989
  assert.equal("#{tag} OK IDLE terminated")
5551
5990
  }
5552
5991
 
5553
5992
  another_decoder.copy('tag', '1', 'INBOX', &another_writer)
5554
5993
  assert_imap_command('IDLE', client_input_text: "DONE\r\n") {|assert|
5555
- assert.equal_lines("+ continue\r\n" +
5556
- "* 2 EXISTS\r\n" +
5557
- "* 2 RECENT\r\n")
5994
+ assert.match(/^\+ /)
5995
+ assert.equal('* 2 EXISTS')
5996
+ assert.equal('* 2 RECENT')
5558
5997
  assert.equal("#{tag} OK IDLE terminated")
5559
5998
  }
5560
5999
 
5561
6000
  another_decoder.expunge('tag', &another_writer)
5562
6001
  assert_imap_command('IDLE', client_input_text: "DONE\r\n") {|assert|
5563
- assert.equal_lines("+ continue\r\n" +
5564
- "* 1 EXPUNGE\r\n")
6002
+ assert.match(/^\+ /)
6003
+ assert.equal('* 1 EXPUNGE')
5565
6004
  assert.equal("#{tag} OK IDLE terminated")
5566
6005
  }
5567
6006
 
5568
6007
  open_mail_store{
5569
- f = @mail_store.examine_mbox(@inbox_id)
6008
+ f = @mail_store.open_folder(@inbox_id, read_only: true)
5570
6009
  begin
5571
6010
  uid_list = @mail_store.each_msg_uid(@inbox_id).to_a
5572
6011
  last_uid = uid_list.min
@@ -5578,8 +6017,9 @@ module RIMS::Test
5578
6017
 
5579
6018
  another_decoder.close('tag', &another_writer)
5580
6019
  assert_imap_command('IDLE', client_input_text: "DONE\r\n") {|assert|
5581
- assert.equal_lines("+ continue\r\n" +
5582
- "* 1 EXPUNGE\r\n")
6020
+ assert.match(/^\+ /)
6021
+ assert.equal('* 1 EXPUNGE')
6022
+ assert.equal('* 0 RECENT')
5583
6023
  assert.equal("#{tag} OK IDLE terminated")
5584
6024
  }
5585
6025