From 7d07e7447b4c5c314aac542c0f71c6fc54ebc71d Mon Sep 17 00:00:00 2001 From: nick evans Date: Fri, 18 Nov 2022 13:48:30 -0500 Subject: [PATCH 1/2] =?UTF-8?q?=E2=9C=85=20Add=20a=20very=20simple=20test?= =?UTF-8?q?=20for=20IMAP#close?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/net/imap/test_imap.rb | 46 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/test/net/imap/test_imap.rb b/test/net/imap/test_imap.rb index 43d7e42f..720cb3c5 100644 --- a/test/net/imap/test_imap.rb +++ b/test/net/imap/test_imap.rb @@ -869,6 +869,52 @@ def test_uidplus_responses end end + def yields_in_test_server_thread( + greeting = "* OK [CAPABILITY IMAP4rev1 AUTH=PLAIN STARTTLS] test server\r\n" + ) + server = create_tcp_server + port = server.addr[1] + @threads << Thread.start do + sock = server.accept + gets = ->{ + buf = "".b + buf << sock.gets until /\A([^ ]+) ([^ ]+) ?(.*)\r\n\z/mn =~ buf + [$1, $2, $3] + } + begin + sock.print(greeting) + last_tag = yield sock, gets + sock.print("* BYE terminating connection\r\n") + sock.print("#{last_tag} OK LOGOUT completed\r\n") if last_tag + ensure + sock.close + server.close + end + end + port + end + + def test_close + requests = Queue.new + port = yields_in_test_server_thread do |sock, gets| + requests.push(gets[]) + sock.print("RUBY0001 OK CLOSE completed\r\n") + requests.push(gets[]) + "RUBY0002" + end + begin + imap = Net::IMAP.new(server_addr, :port => port) + resp = imap.close + assert_equal(["RUBY0001", "CLOSE", ""], requests.pop) + assert_equal([Net::IMAP::TaggedResponse, "RUBY0001", "OK"], + [resp.class, resp.tag, resp.name]) + imap.logout + assert_equal(["RUBY0002", "LOGOUT", ""], requests.pop) + ensure + imap.disconnect if imap + end + end + private def imaps_test From 34f35eea5768166b4752e231cbda5c65098d7219 Mon Sep 17 00:00:00 2001 From: nick evans Date: Fri, 18 Nov 2022 13:50:45 -0500 Subject: [PATCH 2/2] =?UTF-8?q?=E2=9C=A8=20Add=20support=20for=20UNSELECT?= =?UTF-8?q?=20extension=20(RFC3691)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is needed for IMAP4rev2 #12. Fixes #40. --- lib/net/imap.rb | 14 ++++++++++++++ test/net/imap/test_imap.rb | 21 +++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/lib/net/imap.rb b/lib/net/imap.rb index 801498b1..401edfec 100644 --- a/lib/net/imap.rb +++ b/lib/net/imap.rb @@ -796,6 +796,20 @@ def close send_command("CLOSE") end + # Sends an {UNSELECT command [IMAP4rev2 + # ยง6.4.2]}[https://www.rfc-editor.org/rfc/rfc9051#section-6.4.2] to free the + # session resources for a mailbox and return to the "_authenticated_" state. + # This is the same as #close, except that \\Deleted messages are + # not removed from the mailbox. + # + # ===== Capabilities + # + # The server's capabilities must include +UNSELECT+ + # [RFC3691[https://tools.ietf.org/html/rfc3691]]. + def unselect + send_command("UNSELECT") + end + # Sends a EXPUNGE command to permanently remove from the currently # selected mailbox all messages that have the \Deleted flag set. def expunge diff --git a/test/net/imap/test_imap.rb b/test/net/imap/test_imap.rb index 720cb3c5..308c83da 100644 --- a/test/net/imap/test_imap.rb +++ b/test/net/imap/test_imap.rb @@ -915,6 +915,27 @@ def test_close end end + def test_unselect + requests = Queue.new + port = yields_in_test_server_thread do |sock, gets| + requests.push(gets[]) + sock.print("RUBY0001 OK UNSELECT completed\r\n") + requests.push(gets[]) + "RUBY0002" + end + begin + imap = Net::IMAP.new(server_addr, :port => port) + resp = imap.unselect + assert_equal(["RUBY0001", "UNSELECT", ""], requests.pop) + assert_equal([Net::IMAP::TaggedResponse, "RUBY0001", "OK"], + [resp.class, resp.tag, resp.name]) + imap.logout + assert_equal(["RUBY0002", "LOGOUT", ""], requests.pop) + ensure + imap.disconnect if imap + end + end + private def imaps_test