Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the UNSELECT command #72

Merged
merged 2 commits into from
Nov 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions lib/net/imap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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 <tt>\\Deleted</tt> 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
Expand Down
67 changes: 67 additions & 0 deletions test/net/imap/test_imap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -869,6 +869,73 @@ 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

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
Expand Down