diff options
author | Hiroshi SHIBATA <hsbt@ruby-lang.org> | 2021-05-26 15:48:36 +0900 |
---|---|---|
committer | Hiroshi SHIBATA <hsbt@ruby-lang.org> | 2021-05-27 14:42:11 +0900 |
commit | d5bc6b23370908f19d1a4a19ead56e61444f0974 (patch) | |
tree | 765f16079da2b841691c85244733520a8c699561 /test | |
parent | e49c998d1e41737016c8afb7e1b22797018caebb (diff) |
Promote net-imap to the bundled gems
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/4530
Diffstat (limited to 'test')
-rw-r--r-- | test/net/imap/test_imap.rb | 856 | ||||
-rw-r--r-- | test/net/imap/test_imap_authenticators.rb | 23 | ||||
-rw-r--r-- | test/net/imap/test_imap_data_encoding.rb | 46 | ||||
-rw-r--r-- | test/net/imap/test_imap_response_parser.rb | 389 |
4 files changed, 0 insertions, 1314 deletions
diff --git a/test/net/imap/test_imap.rb b/test/net/imap/test_imap.rb deleted file mode 100644 index 46008b0531..0000000000 --- a/test/net/imap/test_imap.rb +++ /dev/null @@ -1,856 +0,0 @@ -# frozen_string_literal: true - -require "net/imap" -require "test/unit" - -class IMAPTest < Test::Unit::TestCase - CA_FILE = File.expand_path("../fixtures/cacert.pem", __dir__) - SERVER_KEY = File.expand_path("../fixtures/server.key", __dir__) - SERVER_CERT = File.expand_path("../fixtures/server.crt", __dir__) - - def setup - @do_not_reverse_lookup = Socket.do_not_reverse_lookup - Socket.do_not_reverse_lookup = true - @threads = [] - end - - def teardown - if !@threads.empty? - assert_join_threads(@threads) - end - ensure - Socket.do_not_reverse_lookup = @do_not_reverse_lookup - end - - if defined?(OpenSSL::SSL::SSLError) - def test_imaps_unknown_ca - assert_raise(OpenSSL::SSL::SSLError) do - imaps_test do |port| - begin - Net::IMAP.new("localhost", - :port => port, - :ssl => true) - rescue SystemCallError - skip $! - end - end - end - end - - def test_imaps_with_ca_file - assert_nothing_raised do - imaps_test do |port| - begin - Net::IMAP.new("localhost", - :port => port, - :ssl => { :ca_file => CA_FILE }) - rescue SystemCallError - skip $! - end - end - end - end - - def test_imaps_verify_none - assert_nothing_raised do - imaps_test do |port| - Net::IMAP.new(server_addr, - :port => port, - :ssl => { :verify_mode => OpenSSL::SSL::VERIFY_NONE }) - end - end - end - - def test_imaps_post_connection_check - assert_raise(OpenSSL::SSL::SSLError) do - imaps_test do |port| - # server_addr is different from the hostname in the certificate, - # so the following code should raise a SSLError. - Net::IMAP.new(server_addr, - :port => port, - :ssl => { :ca_file => CA_FILE }) - end - end - end - end - - if defined?(OpenSSL::SSL) - def test_starttls - imap = nil - starttls_test do |port| - imap = Net::IMAP.new("localhost", :port => port) - imap.starttls(:ca_file => CA_FILE) - imap - end - rescue SystemCallError - skip $! - ensure - if imap && !imap.disconnected? - imap.disconnect - end - end - end - - def start_server - th = Thread.new do - yield - end - @threads << th - sleep 0.1 until th.stop? - end - - def test_unexpected_eof - server = create_tcp_server - port = server.addr[1] - start_server do - sock = server.accept - begin - sock.print("* OK test server\r\n") - sock.gets -# sock.print("* BYE terminating connection\r\n") -# sock.print("RUBY0001 OK LOGOUT completed\r\n") - ensure - sock.close - server.close - end - end - begin - imap = Net::IMAP.new(server_addr, :port => port) - assert_raise(EOFError) do - imap.logout - end - ensure - imap.disconnect if imap - end - end - - def test_idle - server = create_tcp_server - port = server.addr[1] - requests = [] - start_server do - sock = server.accept - begin - sock.print("* OK test server\r\n") - requests.push(sock.gets) - sock.print("+ idling\r\n") - sock.print("* 3 EXISTS\r\n") - sock.print("* 2 EXPUNGE\r\n") - requests.push(sock.gets) - sock.print("RUBY0001 OK IDLE terminated\r\n") - sock.gets - sock.print("* BYE terminating connection\r\n") - sock.print("RUBY0002 OK LOGOUT completed\r\n") - ensure - sock.close - server.close - end - end - - begin - imap = Net::IMAP.new(server_addr, :port => port) - responses = [] - imap.idle do |res| - responses.push(res) - if res.name == "EXPUNGE" - imap.idle_done - end - end - assert_equal(3, responses.length) - assert_instance_of(Net::IMAP::ContinuationRequest, responses[0]) - assert_equal("EXISTS", responses[1].name) - assert_equal(3, responses[1].data) - assert_equal("EXPUNGE", responses[2].name) - assert_equal(2, responses[2].data) - assert_equal(2, requests.length) - assert_equal("RUBY0001 IDLE\r\n", requests[0]) - assert_equal("DONE\r\n", requests[1]) - imap.logout - ensure - imap.disconnect if imap - end - end - - def test_exception_during_idle - server = create_tcp_server - port = server.addr[1] - requests = [] - start_server do - sock = server.accept - begin - sock.print("* OK test server\r\n") - requests.push(sock.gets) - sock.print("+ idling\r\n") - sock.print("* 3 EXISTS\r\n") - sock.print("* 2 EXPUNGE\r\n") - requests.push(sock.gets) - sock.print("RUBY0001 OK IDLE terminated\r\n") - sock.gets - sock.print("* BYE terminating connection\r\n") - sock.print("RUBY0002 OK LOGOUT completed\r\n") - ensure - sock.close - server.close - end - end - begin - imap = Net::IMAP.new(server_addr, :port => port) - begin - th = Thread.current - m = Monitor.new - in_idle = false - exception_raised = false - c = m.new_cond - raiser = Thread.start do - m.synchronize do - until in_idle - c.wait(0.1) - end - end - th.raise(Interrupt) - m.synchronize do - exception_raised = true - c.signal - end - end - @threads << raiser - imap.idle do |res| - m.synchronize do - in_idle = true - c.signal - until exception_raised - c.wait(0.1) - end - end - end - rescue Interrupt - end - assert_equal(2, requests.length) - assert_equal("RUBY0001 IDLE\r\n", requests[0]) - assert_equal("DONE\r\n", requests[1]) - imap.logout - ensure - imap.disconnect if imap - raiser.kill unless in_idle - end - end - - def test_idle_done_not_during_idle - server = create_tcp_server - port = server.addr[1] - start_server do - sock = server.accept - begin - sock.print("* OK test server\r\n") - sleep 0.1 - ensure - sock.close - server.close - end - end - begin - imap = Net::IMAP.new(server_addr, :port => port) - assert_raise(Net::IMAP::Error) do - imap.idle_done - end - ensure - imap.disconnect if imap - end - end - - def test_idle_timeout - server = create_tcp_server - port = server.addr[1] - requests = [] - start_server do - sock = server.accept - begin - sock.print("* OK test server\r\n") - requests.push(sock.gets) - sock.print("+ idling\r\n") - sock.print("* 3 EXISTS\r\n") - sock.print("* 2 EXPUNGE\r\n") - requests.push(sock.gets) - sock.print("RUBY0001 OK IDLE terminated\r\n") - sock.gets - sock.print("* BYE terminating connection\r\n") - sock.print("RUBY0002 OK LOGOUT completed\r\n") - ensure - sock.close - server.close - end - end - - begin - imap = Net::IMAP.new(server_addr, :port => port) - responses = [] - Thread.pass - imap.idle(0.2) do |res| - responses.push(res) - end - # There is no guarantee that this thread has received all the responses, - # so check the response length. - if responses.length > 0 - assert_instance_of(Net::IMAP::ContinuationRequest, responses[0]) - if responses.length > 1 - assert_equal("EXISTS", responses[1].name) - assert_equal(3, responses[1].data) - if responses.length > 2 - assert_equal("EXPUNGE", responses[2].name) - assert_equal(2, responses[2].data) - end - end - end - # Also, there is no guarantee that the server thread has stored - # all the requests into the array, so check the length. - if requests.length > 0 - assert_equal("RUBY0001 IDLE\r\n", requests[0]) - if requests.length > 1 - assert_equal("DONE\r\n", requests[1]) - end - end - imap.logout - ensure - imap.disconnect if imap - end - end - - def test_unexpected_bye - server = create_tcp_server - port = server.addr[1] - start_server do - sock = server.accept - begin - sock.print("* OK Gimap ready for requests from 75.101.246.151 33if2752585qyk.26\r\n") - sock.gets - sock.print("* BYE System Error 33if2752585qyk.26\r\n") - ensure - sock.close - server.close - end - end - begin - imap = Net::IMAP.new(server_addr, :port => port) - assert_raise(Net::IMAP::ByeResponseError) do - imap.login("user", "password") - end - end - end - - def test_exception_during_shutdown - server = create_tcp_server - port = server.addr[1] - start_server do - sock = server.accept - begin - sock.print("* OK test server\r\n") - sock.gets - sock.print("* BYE terminating connection\r\n") - sock.print("RUBY0001 OK LOGOUT completed\r\n") - ensure - sock.close - server.close - end - end - begin - imap = Net::IMAP.new(server_addr, :port => port) - imap.instance_eval do - def @sock.shutdown(*args) - super - ensure - raise "error" - end - end - imap.logout - ensure - assert_raise(RuntimeError) do - imap.disconnect - end - end - end - - def test_connection_closed_during_idle - server = create_tcp_server - port = server.addr[1] - requests = [] - sock = nil - threads = [] - started = false - threads << Thread.start do - started = true - begin - sock = server.accept - sock.print("* OK test server\r\n") - requests.push(sock.gets) - sock.print("+ idling\r\n") - rescue IOError # sock is closed by another thread - ensure - server.close - end - end - sleep 0.1 until started - threads << Thread.start do - imap = Net::IMAP.new(server_addr, :port => port) - begin - m = Monitor.new - in_idle = false - closed = false - c = m.new_cond - threads << Thread.start do - m.synchronize do - until in_idle - c.wait(0.1) - end - end - sock.close - m.synchronize do - closed = true - c.signal - end - end - assert_raise(EOFError) do - imap.idle do |res| - m.synchronize do - in_idle = true - c.signal - until closed - c.wait(0.1) - end - end - end - end - assert_equal(1, requests.length) - assert_equal("RUBY0001 IDLE\r\n", requests[0]) - ensure - imap.disconnect if imap - end - end - assert_join_threads(threads) - ensure - if sock && !sock.closed? - sock.close - end - end - - def test_connection_closed_without_greeting - server = create_tcp_server - port = server.addr[1] - h = { - server: server, - port: port, - server_created: { - server: server.inspect, - t: Process.clock_gettime(Process::CLOCK_MONOTONIC), - } - } - net_imap = Class.new(Net::IMAP) do - @@h = h - def tcp_socket(host, port) - @@h[:in_tcp_socket] = { - host: host, - port: port, - server: @@h[:server].inspect, - t: Process.clock_gettime(Process::CLOCK_MONOTONIC), - } - #super - s = Socket.tcp(host, port, :connect_timeout => @open_timeout) - @@h[:in_tcp_socket_2] = { - s: s.inspect, - local_address: s.local_address, - remote_address: s.remote_address, - t: Process.clock_gettime(Process::CLOCK_MONOTONIC), - } - s.setsockopt(:SOL_SOCKET, :SO_KEEPALIVE, true) - s - end - end - start_server do - begin - h[:in_start_server_before_accept] = { - t: Process.clock_gettime(Process::CLOCK_MONOTONIC), - } - sock = server.accept - h[:in_start_server] = { - sock_addr: sock.addr, - sock_peeraddr: sock.peeraddr, - t: Process.clock_gettime(Process::CLOCK_MONOTONIC), - sockets: ObjectSpace.each_object(BasicSocket).map{|s| [s.inspect, connect_address: (s.connect_address rescue nil).inspect, local_address: (s.local_address rescue nil).inspect, remote_address: (s.remote_address rescue nil).inspect] }, - } - sock.close - h[:in_start_server_sock_closed] = { - t: Process.clock_gettime(Process::CLOCK_MONOTONIC), - } - ensure - server.close - end - end - assert_raise(Net::IMAP::Error) do - #Net::IMAP.new(server_addr, :port => port) - if true - net_imap.new(server_addr, :port => port) - else - # for testing debug print - begin - net_imap.new(server_addr, :port => port) - rescue Net::IMAP::Error - raise Errno::EINVAL - end - end - rescue SystemCallError => e # for debug on OpenCSW - h[:in_rescue] = { - e: e, - server_addr: server_addr, - t: Process.clock_gettime(Process::CLOCK_MONOTONIC), - } - require 'pp' - raise(PP.pp(h, +'')) - end - end - - def test_default_port - assert_equal(143, Net::IMAP.default_port) - assert_equal(143, Net::IMAP.default_imap_port) - assert_equal(993, Net::IMAP.default_tls_port) - assert_equal(993, Net::IMAP.default_ssl_port) - assert_equal(993, Net::IMAP.default_imaps_port) - end - - def test_send_invalid_number - server = create_tcp_server - port = server.addr[1] - start_server do - sock = server.accept - begin - sock.print("* OK test server\r\n") - sock.gets - sock.print("RUBY0001 OK TEST completed\r\n") - sock.gets - sock.print("RUBY0002 OK TEST completed\r\n") - sock.gets - sock.print("RUBY0003 OK TEST completed\r\n") - sock.gets - sock.print("RUBY0004 OK TEST completed\r\n") - sock.gets - sock.print("* BYE terminating connection\r\n") - sock.print("RUBY0005 OK LOGOUT completed\r\n") - ensure - sock.close - server.close - end - end - begin - imap = Net::IMAP.new(server_addr, :port => port) - assert_raise(Net::IMAP::DataFormatError) do - imap.__send__(:send_command, "TEST", -1) - end - imap.__send__(:send_command, "TEST", 0) - imap.__send__(:send_command, "TEST", 4294967295) - assert_raise(Net::IMAP::DataFormatError) do - imap.__send__(:send_command, "TEST", 4294967296) - end - assert_raise(Net::IMAP::DataFormatError) do - imap.__send__(:send_command, "TEST", Net::IMAP::MessageSet.new(-1)) - end - assert_raise(Net::IMAP::DataFormatError) do - imap.__send__(:send_command, "TEST", Net::IMAP::MessageSet.new(0)) - end - imap.__send__(:send_command, "TEST", Net::IMAP::MessageSet.new(1)) - imap.__send__(:send_command, "TEST", Net::IMAP::MessageSet.new(4294967295)) - assert_raise(Net::IMAP::DataFormatError) do - imap.__send__(:send_command, "TEST", Net::IMAP::MessageSet.new(4294967296)) - end - imap.logout - ensure - imap.disconnect - end - end - - def test_send_literal - server = create_tcp_server - port = server.addr[1] - requests = [] - literal = nil - start_server do - sock = server.accept - begin - sock.print("* OK test server\r\n") - line = sock.gets - requests.push(line) - size = line.slice(/{(\d+)}\r\n/, 1).to_i - sock.print("+ Ready for literal data\r\n") - literal = sock.read(size) - requests.push(sock.gets) - sock.print("RUBY0001 OK TEST completed\r\n") - sock.gets - sock.print("* BYE terminating connection\r\n") - sock.print("RUBY0002 OK LOGOUT completed\r\n") - ensure - sock.close - server.close - end - end - begin - imap = Net::IMAP.new(server_addr, :port => port) - imap.__send__(:send_command, "TEST", ["\xDE\xAD\xBE\xEF".b]) - assert_equal(2, requests.length) - assert_equal("RUBY0001 TEST ({4}\r\n", requests[0]) - assert_equal("\xDE\xAD\xBE\xEF".b, literal) - assert_equal(")\r\n", requests[1]) - imap.logout - ensure - imap.disconnect - end - end - - def test_disconnect - server = create_tcp_server - port = server.addr[1] - start_server do - sock = server.accept - begin - sock.print("* OK test server\r\n") - sock.gets - sock.print("* BYE terminating connection\r\n") - sock.print("RUBY0001 OK LOGOUT completed\r\n") - ensure - sock.close - server.close - end - end - begin - imap = Net::IMAP.new(server_addr, :port => port) - imap.logout - imap.disconnect - assert_equal(true, imap.disconnected?) - imap.disconnect - assert_equal(true, imap.disconnected?) - ensure - imap.disconnect if imap && !imap.disconnected? - end - end - - def test_append - server = create_tcp_server - port = server.addr[1] - mail = <<EOF.gsub(/\n/, "\r\n") -From: shugo@example.com -To: matz@example.com -Subject: hello - -hello world -EOF - requests = [] - received_mail = nil - start_server do - sock = server.accept - begin - sock.print("* OK test server\r\n") - line = sock.gets - requests.push(line) - size = line.slice(/{(\d+)}\r\n/, 1).to_i - sock.print("+ Ready for literal data\r\n") - received_mail = sock.read(size) - sock.gets - sock.print("RUBY0001 OK APPEND completed\r\n") - requests.push(sock.gets) - sock.print("* BYE terminating connection\r\n") - sock.print("RUBY0002 OK LOGOUT completed\r\n") - ensure - sock.close - server.close - end - end - - begin - imap = Net::IMAP.new(server_addr, :port => port) - imap.append("INBOX", mail) - assert_equal(1, requests.length) - assert_equal("RUBY0001 APPEND INBOX {#{mail.size}}\r\n", requests[0]) - assert_equal(mail, received_mail) - imap.logout - assert_equal(2, requests.length) - assert_equal("RUBY0002 LOGOUT\r\n", requests[1]) - ensure - imap.disconnect if imap - end - end - - def test_append_fail - server = create_tcp_server - port = server.addr[1] - mail = <<EOF.gsub(/\n/, "\r\n") -From: shugo@example.com -To: matz@example.com -Subject: hello - -hello world -EOF - requests = [] - start_server do - sock = server.accept - begin - sock.print("* OK test server\r\n") - requests.push(sock.gets) - sock.print("RUBY0001 NO Mailbox doesn't exist\r\n") - requests.push(sock.gets) - sock.print("* BYE terminating connection\r\n") - sock.print("RUBY0002 OK LOGOUT completed\r\n") - ensure - sock.close - server.close - end - end - - begin - imap = Net::IMAP.new(server_addr, :port => port) - assert_raise(Net::IMAP::NoResponseError) do - imap.append("INBOX", mail) - end - assert_equal(1, requests.length) - assert_equal("RUBY0001 APPEND INBOX {#{mail.size}}\r\n", requests[0]) - imap.logout - assert_equal(2, requests.length) - assert_equal("RUBY0002 LOGOUT\r\n", requests[1]) - ensure - imap.disconnect if imap - end - end - - def test_id - server = create_tcp_server - port = server.addr[1] - requests = Queue.new - server_id = {"name" => "test server", "version" => "v0.1.0"} - server_id_str = '("name" "test server" "version" "v0.1.0")' - @threads << Thread.start do - sock = server.accept - begin - sock.print("* OK test server\r\n") - requests.push(sock.gets) - # RFC 2971 very clearly states (in section 3.2): - # "a server MUST send a tagged ID response to an ID command." - # And yet... some servers report ID capability but won't the response. - sock.print("RUBY0001 OK ID completed\r\n") - requests.push(sock.gets) - sock.print("* ID #{server_id_str}\r\n") - sock.print("RUBY0002 OK ID completed\r\n") - requests.push(sock.gets) - sock.print("* ID #{server_id_str}\r\n") - sock.print("RUBY0003 OK ID completed\r\n") - requests.push(sock.gets) - sock.print("* BYE terminating connection\r\n") - sock.print("RUBY0004 OK LOGOUT completed\r\n") - ensure - sock.close - server.close - end - end - - begin - imap = Net::IMAP.new(server_addr, :port => port) - resp = imap.id - assert_equal(nil, resp) - assert_equal("RUBY0001 ID NIL\r\n", requests.pop) - resp = imap.id({}) - assert_equal(server_id, resp) - assert_equal("RUBY0002 ID ()\r\n", requests.pop) - resp = imap.id("name" => "test client", "version" => "latest") - assert_equal(server_id, resp) - assert_equal("RUBY0003 ID (\"name\" \"test client\" \"version\" \"latest\")\r\n", - requests.pop) - imap.logout - assert_equal("RUBY0004 LOGOUT\r\n", requests.pop) - ensure - imap.disconnect if imap - end - end - - private - - def imaps_test - server = create_tcp_server - port = server.addr[1] - ctx = OpenSSL::SSL::SSLContext.new - ctx.ca_file = CA_FILE - ctx.key = File.open(SERVER_KEY) { |f| - OpenSSL::PKey::RSA.new(f) - } - ctx.cert = File.open(SERVER_CERT) { |f| - OpenSSL::X509::Certificate.new(f) - } - ssl_server = OpenSSL::SSL::SSLServer.new(server, ctx) - started = false - ths = Thread.start do - Thread.current.report_on_exception = false # always join-ed - begin - started = true - sock = ssl_server.accept - begin - sock.print("* OK test server\r\n") - sock.gets - sock.print("* BYE terminating connection\r\n") - sock.print("RUBY0001 OK LOGOUT completed\r\n") - ensure - sock.close - end - rescue Errno::EPIPE, Errno::ECONNRESET, Errno::ECONNABORTED - end - end - sleep 0.1 until started - begin - begin - imap = yield(port) - imap.logout - ensure - imap.disconnect if imap - end - ensure - ssl_server.close - ths.join - end - end - - def starttls_test - server = create_tcp_server - port = server.addr[1] - start_server do - sock = server.accept - begin - sock.print("* OK test server\r\n") - sock.gets - sock.print("RUBY0001 OK completed\r\n") - ctx = OpenSSL::SSL::SSLContext.new - ctx.ca_file = CA_FILE - ctx.key = File.open(SERVER_KEY) { |f| - OpenSSL::PKey::RSA.new(f) - } - ctx.cert = File.open(SERVER_CERT) { |f| - OpenSSL::X509::Certificate.new(f) - } - sock = OpenSSL::SSL::SSLSocket.new(sock, ctx) - sock.sync_close = true - sock.accept - sock.gets - sock.print("* BYE terminating connection\r\n") - sock.print("RUBY0002 OK LOGOUT completed\r\n") - ensure - sock.close - server.close - end - end - begin - imap = yield(port) - imap.logout if !imap.disconnected? - ensure - imap.disconnect if imap && !imap.disconnected? - end - end - - def create_tcp_server - return TCPServer.new(server_addr, 0) - end - - def server_addr - Addrinfo.tcp("localhost", 0).ip_address - end -end diff --git a/test/net/imap/test_imap_authenticators.rb b/test/net/imap/test_imap_authenticators.rb deleted file mode 100644 index 0c7a0a325d..0000000000 --- a/test/net/imap/test_imap_authenticators.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -require "net/imap" -require "test/unit" - -class IMAPAuthenticatorsTest < Test::Unit::TestCase - - PLAIN = Net::IMAP::PlainAuthenticator - - def test_plain - assert_equal("\0authc\0passwd", - PLAIN.new("authc", "passwd").process(nil)) - assert_equal("authz\0user\0pass", - PLAIN.new("user", "pass", authzid: "authz").process(nil)) - end - - def test_plain_no_null_chars - assert_raise(ArgumentError) { PLAIN.new("bad\0user", "pass") } - assert_raise(ArgumentError) { PLAIN.new("user", "bad\0pass") } - assert_raise(ArgumentError) { PLAIN.new("u", "p", authzid: "bad\0authz") } - end - -end diff --git a/test/net/imap/test_imap_data_encoding.rb b/test/net/imap/test_imap_data_encoding.rb deleted file mode 100644 index 2ca1c1822b..0000000000 --- a/test/net/imap/test_imap_data_encoding.rb +++ /dev/null @@ -1,46 +0,0 @@ -# frozen_string_literal: true - -require "net/imap" -require "test/unit" - -class IMAPDataEncodingTest < Test::Unit::TestCase - - def test_encode_utf7 - assert_equal("foo", Net::IMAP.encode_utf7("foo")) - assert_equal("&-", Net::IMAP.encode_utf7("&")) - - utf8 = "\357\274\241\357\274\242\357\274\243".dup.force_encoding("UTF-8") - s = Net::IMAP.encode_utf7(utf8) - assert_equal("&,yH,Iv8j-", s) - s = Net::IMAP.encode_utf7("foo&#{utf8}-bar".encode("EUC-JP")) - assert_equal("foo&-&,yH,Iv8j--bar", s) - - utf8 = "\343\201\202&".dup.force_encoding("UTF-8") - s = Net::IMAP.encode_utf7(utf8) - assert_equal("&MEI-&-", s) - s = Net::IMAP.encode_utf7(utf8.encode("EUC-JP")) - assert_equal("&MEI-&-", s) - end - - def test_decode_utf7 - assert_equal("&", Net::IMAP.decode_utf7("&-")) - assert_equal("&-", Net::IMAP.decode_utf7("&--")) - - s = Net::IMAP.decode_utf7("&,yH,Iv8j-") - utf8 = "\357\274\241\357\274\242\357\274\243".dup.force_encoding("UTF-8") - assert_equal(utf8, s) - end - - def test_format_date - time = Time.mktime(2009, 7, 24) - s = Net::IMAP.format_date(time) - assert_equal("24-Jul-2009", s) - end - - def test_format_datetime - time = Time.mktime(2009, 7, 24, 1, 23, 45) - s = Net::IMAP.format_datetime(time) - assert_match(/\A24-Jul-2009 01:23 [+\-]\d{4}\z/, s) - end - -end diff --git a/test/net/imap/test_imap_response_parser.rb b/test/net/imap/test_imap_response_parser.rb deleted file mode 100644 index 5b519edeff..0000000000 --- a/test/net/imap/test_imap_response_parser.rb +++ /dev/null @@ -1,389 +0,0 @@ -# frozen_string_literal: true - -require "net/imap" -require "test/unit" - -class IMAPResponseParserTest < Test::Unit::TestCase - def setup - @do_not_reverse_lookup = Socket.do_not_reverse_lookup - Socket.do_not_reverse_lookup = true - if Net::IMAP.respond_to?(:max_flag_count) - @max_flag_count = Net::IMAP.max_flag_count - Net::IMAP.max_flag_count = 3 - end - end - - def teardown - Socket.do_not_reverse_lookup = @do_not_reverse_lookup - if Net::IMAP.respond_to?(:max_flag_count) - Net::IMAP.max_flag_count = @max_flag_count - end - end - - def test_flag_list_too_many_flags - parser = Net::IMAP::ResponseParser.new - assert_nothing_raised do - 3.times do |i| - parser.parse(<<EOF.gsub(/\n/, "\r\n")) -* LIST (\\Foo#{i}) "." "INBOX" -EOF - end - end - assert_raise(Net::IMAP::FlagCountError) do - parser.parse(<<EOF.gsub(/\n/, "\r\n")) -* LIST (\\Foo3) "." "INBOX" -EOF - end - end - - def test_flag_list_many_same_flags - parser = Net::IMAP::ResponseParser.new - assert_nothing_raised do - 100.times do - parser.parse(<<EOF.gsub(/\n/, "\r\n")) -* LIST (\\Foo) "." "INBOX" -EOF - end - end - end - - def test_flag_xlist_inbox - parser = Net::IMAP::ResponseParser.new - response = parser.parse(<<EOF.gsub(/\n/, "\r\n")) -* XLIST (\\Inbox) "." "INBOX" -EOF - assert_equal [:Inbox], response.data.attr - end - - def test_resp_text_code - parser = Net::IMAP::ResponseParser.new - response = parser.parse(<<EOF.gsub(/\n/, "\r\n")) -* OK [CLOSED] Previous mailbox closed. -EOF - assert_equal "CLOSED", response.data.code.name - end - - def test_search_response - parser = Net::IMAP::ResponseParser.new - response = parser.parse(<<EOF.gsub(/\n/, "\r\n")) -* SEARCH -EOF - assert_equal [], response.data - response = parser.parse(<<EOF.gsub(/\n/, "\r\n")) -* SEARCH 1 -EOF - assert_equal [1], response.data - response = parser.parse(<<EOF.gsub(/\n/, "\r\n")) -* SEARCH 1 2 3 -EOF - assert_equal [1, 2, 3], response.data - end - - def test_search_response_of_yahoo - parser = Net::IMAP::ResponseParser.new - response = parser.parse(<<EOF.gsub(/\n/, "\r\n")) -* SEARCH 1\s -EOF - assert_equal [1], response.data - response = parser.parse(<<EOF.gsub(/\n/, "\r\n")) -* SEARCH 1 2 3\s -EOF - assert_equal [1, 2, 3], response.data - end - - def test_msg_att_extra_space - parser = Net::IMAP::ResponseParser.new - response = parser.parse(<<EOF.gsub(/\n/, "\r\n")) -* 1 FETCH (UID 92285) -EOF - assert_equal 92285, response.data.attr["UID"] - - response = parser.parse(<<EOF.gsub(/\n/, "\r\n")) -* 1 FETCH (UID 92285 ) -EOF - assert_equal 92285, response.data.attr["UID"] - end - - def test_msg_att_parse_error - parser = Net::IMAP::ResponseParser.new - e = assert_raise(Net::IMAP::ResponseParseError) { - parser.parse(<<EOF.gsub(/\n/, "\r\n")) -* 123 FETCH (UNKNOWN 92285) -EOF - } - assert_match(/ for \{123\}/, e.message) - end - - def test_msg_att_rfc822_text - parser = Net::IMAP::ResponseParser.new - response = parser.parse(<<EOF.gsub(/\n/, "\r\n")) -* 123 FETCH (RFC822 {5} -foo -) -EOF - assert_equal("foo\r\n", response.data.attr["RFC822"]) - response = parser.parse(<<EOF.gsub(/\n/, "\r\n")) -* 123 FETCH (RFC822[] {5} -foo -) -EOF - assert_equal("foo\r\n", response.data.attr["RFC822"]) - end - - # [Bug #6397] [ruby-core:44849] - def test_body_type_attachment - parser = Net::IMAP::ResponseParser.new - response = parser.parse(<<EOF.gsub(/\n/, "\r\n")) -* 980 FETCH (UID 2862 BODYSTRUCTURE ((("TEXT" "PLAIN" ("CHARSET" "iso-8859-1") NIL NIL "7BIT" 416 21 NIL NIL NIL)("TEXT" "HTML" ("CHARSET" "iso-8859-1") NIL NIL "7BIT" 1493 32 NIL NIL NIL) "ALTERNATIVE" ("BOUNDARY" "Boundary_(ID_IaecgfnXwG5bn3x8lIeGIQ)") NIL NIL)("MESSAGE" "RFC822" ("NAME" "Fw_ ____ _____ ____.eml") NIL NIL "7BIT" 1980088 NIL ("ATTACHMENT" ("FILENAME" "Fw_ ____ _____ ____.eml")) NIL) "MIXED" ("BOUNDARY" "Boundary_(ID_eDdLc/j0mBIzIlR191pHjA)") NIL NIL)) -EOF - assert_equal("Fw_ ____ _____ ____.eml", - response.data.attr["BODYSTRUCTURE"].parts[1].body.param["FILENAME"]) - end - - def assert_parseable(s) - parser = Net::IMAP::ResponseParser.new - parser.parse(s.gsub(/\n/, "\r\n")) - end - - # [Bug #7146] - def test_msg_delivery_status - # This was part of a larger response that caused crashes, but this was the - # minimal test case to demonstrate it - assert_parseable <<EOF -* 4902 FETCH (BODY (("MESSAGE" "DELIVERY-STATUS" NIL NIL NIL "7BIT" 324) "REPORT")) -EOF - end - - # [Bug #7147] - def test_msg_with_message_rfc822_attachment - assert_parseable <<EOF -* 5441 FETCH (BODY ((("TEXT" "PLAIN" ("CHARSET" "iso-8859-1") NIL NIL "QUOTED-PRINTABLE" 69 1)("TEXT" "HTML" ("CHARSET" "iso-8859-1") NIL NIL "QUOTED-PRINTABLE" 455 12) "ALTERNATIVE")("MESSAGE" "RFC822" ("NAME" "ATT00026.eml") NIL NIL "7BIT" 4079755) "MIXED")) -EOF - end - - # [Bug #7153] - def test_msg_body_mixed - assert_parseable <<EOF -* 1038 FETCH (BODY ("MIXED")) -EOF - end - - # [Bug #8167] - def test_msg_delivery_status_with_extra_data - parser = Net::IMAP::ResponseParser.new - response = parser.parse(<<EOF.gsub(/\n/, "\r\n")) -* 29021 FETCH (RFC822.SIZE 3162 UID 113622 RFC822.HEADER {1155} -Return-path: <> -Envelope-to: info@xxxxxxxx.si -Delivery-date: Tue, 26 Mar 2013 12:42:58 +0100 -Received: from mail by xxxx.xxxxxxxxxxx.net with spam-scanned (Exim 4.76) - id 1UKSHI-000Cwl-AR - for info@xxxxxxxx.si; Tue, 26 Mar 2013 12:42:58 +0100 -X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on xxxx.xxxxxxxxxxx.net -X-Spam-Level: ** -X-Spam-Status: No, score=2.1 required=7.0 tests=DKIM_ADSP_NXDOMAIN,RDNS_NONE - autolearn=no version=3.3.1 -Received: from [xx.xxx.xxx.xx] (port=56890 helo=xxxxxx.localdomain) - by xxxx.xxxxxxxxxxx.net with esmtp (Exim 4.76) - id 1UKSHI-000Cwi-9j - for info@xxxxxxxx.si; Tue, 26 Mar 2013 12:42:56 +0100 -Received: by xxxxxx.localdomain (Postfix) - id 72725BEA64A; Tue, 26 Mar 2013 12:42:55 +0100 (CET) -Date: Tue, 26 Mar 2013 12:42:55 +0100 (CET) -From: MAILER-DAEMON@xxxxxx.localdomain (Mail Delivery System) -Subject: Undelivered Mail Returned to Sender -To: info@xxxxxxxx.si -Auto-Submitted: auto-replied -MIME-Version: 1.0 -Content-Type: multipart/report; report-type=delivery-status; - boundary="27797BEA649.1364298175/xxxxxx.localdomain" -Message-Id: <20130326114255.72725BEA64A@xxxxxx.localdomain> - - BODYSTRUCTURE (("text" "plain" ("charset" "us-ascii") NIL "Notification" "7bit" 510 14 NIL NIL NIL NIL)("message" "delivery-status" NIL NIL "Delivery report" "7bit" 410 NIL NIL NIL NIL)("text" "rfc822-headers" ("charset" "us-ascii") NIL "Undelivered Message Headers" "7bit" 612 15 NIL NIL NIL NIL) "report" ("report-type" "delivery-status" "boundary" "27797BEA649.1364298175/xxxxxx.localdomain") NIL NIL NIL)) -EOF - delivery_status = response.data.attr["BODYSTRUCTURE"].parts[1] - assert_equal("MESSAGE", delivery_status.media_type) - assert_equal("DELIVERY-STATUS", delivery_status.subtype) - assert_equal(nil, delivery_status.param) - assert_equal(nil, delivery_status.content_id) - assert_equal("Delivery report", delivery_status.description) - assert_equal("7BIT", delivery_status.encoding) - assert_equal(410, delivery_status.size) - end - - # [Bug #8281] - def test_acl - parser = Net::IMAP::ResponseParser.new - response = parser.parse(<<EOF.gsub(/\n/, "\r\n")) -* ACL "INBOX/share" "imshare2copy1366146467@xxxxxxxxxxxxxxxxxx.com" lrswickxteda -EOF - assert_equal("ACL", response.name) - assert_equal(1, response.data.length) - assert_equal("INBOX/share", response.data[0].mailbox) - assert_equal("imshare2copy1366146467@xxxxxxxxxxxxxxxxxx.com", - response.data[0].user) - assert_equal("lrswickxteda", response.data[0].rights) - end - - # [Bug #8415] - def test_capability - parser = Net::IMAP::ResponseParser.new - response = parser.parse("* CAPABILITY st11p00mm-iscream009 1Q49 XAPPLEPUSHSERVICE IMAP4 IMAP4rev1 SASL-IR AUTH=ATOKEN AUTH=PLAIN\r\n") - assert_equal("CAPABILITY", response.name) - assert_equal("AUTH=PLAIN", response.data.last) - response = parser.parse("* CAPABILITY st11p00mm-iscream009 1Q49 XAPPLEPUSHSERVICE IMAP4 IMAP4rev1 SASL-IR AUTH=ATOKEN AUTH=PLAIN \r\n") - assert_equal("CAPABILITY", response.name) - assert_equal("AUTH=PLAIN", response.data.last) - response = parser.parse("* OK [CAPABILITY IMAP4rev1 SASL-IR 1234 NIL THIS+THAT + AUTH=PLAIN ID] IMAP4rev1 Hello\r\n") - assert_equal("OK", response.name) - assert_equal("IMAP4rev1 Hello", response.data.text) - code = response.data.code - assert_equal("CAPABILITY", code.name) - assert_equal( - ["IMAP4REV1", "SASL-IR", "1234", "NIL", "THIS+THAT", "+", "AUTH=PLAIN", "ID"], - code.data - ) - end - - def test_id - parser = Net::IMAP::ResponseParser.new - response = parser.parse("* ID NIL\r\n") - assert_equal("ID", response.name) - assert_equal(nil, response.data) - response = parser.parse("* ID (\"name\" \"GImap\" \"vendor\" \"Google, Inc.\" \"support-url\" NIL)\r\n") - assert_equal("ID", response.name) - assert_equal("GImap", response.data["name"]) - assert_equal("Google, Inc.", response.data["vendor"]) - assert_equal(nil, response.data.fetch("support-url")) - end - - def test_mixed_boundary - parser = Net::IMAP::ResponseParser.new - response = parser.parse("* 2688 FETCH (UID 179161 BODYSTRUCTURE (" \ - "(\"TEXT\" \"PLAIN\" (\"CHARSET\" \"iso-8859-1\") NIL NIL \"QUOTED-PRINTABLE\" 200 4 NIL NIL NIL)" \ - "(\"MESSAGE\" \"DELIVERY-STATUS\" NIL NIL NIL \"7BIT\" 318 NIL NIL NIL)" \ - "(\"MESSAGE\" \"RFC822\" NIL NIL NIL \"7BIT\" 2177" \ - " (\"Tue, 11 May 2010 18:28:16 -0400\" \"Re: Welcome letter\" (" \ - "(\"David\" NIL \"info\" \"xxxxxxxx.si\")) " \ - "((\"David\" NIL \"info\" \"xxxxxxxx.si\")) " \ - "((\"David\" NIL \"info\" \"xxxxxxxx.si\")) " \ - "((\"Doretha\" NIL \"doretha.info\" \"xxxxxxxx.si\")) " \ - "NIL NIL " \ - "\"<AC1D15E06EA82F47BDE18E851CC32F330717704E@localdomain>\" " \ - "\"<AANLkTikKMev1I73L2E7XLjRs67IHrEkb23f7ZPmD4S_9@localdomain>\")" \ - " (\"MIXED\" (\"BOUNDARY\" \"000e0cd29212e3e06a0486590ae2\") NIL NIL)" \ - " 37 NIL NIL NIL)" \ - " \"REPORT\" (\"BOUNDARY\" \"16DuG.4XbaNOvCi.9ggvq.8Ipnyp3\" \"REPORT-TYPE\" \"delivery-status\") NIL NIL))\r\n") - empty_part = response.data.attr['BODYSTRUCTURE'].parts[2] - assert_equal(empty_part.lines, 37) - assert_equal(empty_part.body.media_type, 'MULTIPART') - assert_equal(empty_part.body.subtype, 'MIXED') - assert_equal(empty_part.body.param['BOUNDARY'], '000e0cd29212e3e06a0486590ae2') - end - - # [Bug #10112] - def test_search_modseq - parser = Net::IMAP::ResponseParser.new - response = parser.parse("* SEARCH 87216 87221 (MODSEQ 7667567)\r\n") - assert_equal("SEARCH", response.name) - assert_equal([87216, 87221], response.data) - end - - # [Bug #11128] - def test_body_ext_mpart_without_lang - parser = Net::IMAP::ResponseParser.new - response = parser.parse("* 4 FETCH (BODY (((\"text\" \"plain\" (\"charset\" \"utf-8\") NIL NIL \"7bit\" 257 9 NIL NIL NIL NIL)(\"text\" \"html\" (\"charset\" \"utf-8\") NIL NIL \"quoted-printable\" 655 9 NIL NIL NIL NIL) \"alternative\" (\"boundary\" \"001a1137a5047848dd05157ddaa1\") NIL)(\"application\" \"pdf\" (\"name\" \"test.xml\" \"x-apple-part-url\" \"9D00D9A2-98AB-4EFB-85BA-FB255F8BF3D7\") NIL NIL \"base64\" 4383638 NIL (\"attachment\" (\"filename\" \"test.xml\")) NIL NIL) \"mixed\" (\"boundary\" \"001a1137a5047848e405157ddaa3\") NIL))\r\n") - assert_equal("FETCH", response.name) - body = response.data.attr["BODY"] - assert_equal(nil, body.parts[0].disposition) - assert_equal(nil, body.parts[0].language) - assert_equal("ATTACHMENT", body.parts[1].disposition.dsp_type) - assert_equal("test.xml", body.parts[1].disposition.param["FILENAME"]) - assert_equal(nil, body.parts[1].language) - end - - # [Bug #13649] - def test_status - parser = Net::IMAP::ResponseParser.new - response = parser.parse("* STATUS INBOX (UIDNEXT 1 UIDVALIDITY 1234)\r\n") - assert_equal("STATUS", response.name) - assert_equal("INBOX", response.data.mailbox) - assert_equal(1234, response.data.attr["UIDVALIDITY"]) - response = parser.parse("* STATUS INBOX (UIDNEXT 1 UIDVALIDITY 1234) \r\n") - assert_equal("STATUS", response.name) - assert_equal("INBOX", response.data.mailbox) - assert_equal(1234, response.data.attr["UIDVALIDITY"]) - end - - # [Bug #10119] - def test_msg_att_modseq_data - parser = Net::IMAP::ResponseParser.new - response = parser.parse("* 1 FETCH (FLAGS (\Seen) MODSEQ (12345) UID 5)\r\n") - assert_equal(12345, response.data.attr["MODSEQ"]) - end - - def test_msg_rfc3501_response_text_with_T_LBRA - parser = Net::IMAP::ResponseParser.new - response = parser.parse("RUBY0004 OK [READ-WRITE] [Gmail]/Sent Mail selected. (Success)\r\n") - assert_equal("RUBY0004", response.tag) - assert_equal("READ-WRITE", response.data.code.name) - assert_equal("[Gmail]/Sent Mail selected. (Success)", response.data.text) - end - - def test_msg_rfc3501_response_text_with_BADCHARSET_astrings - parser = Net::IMAP::ResponseParser.new - response = parser.parse("t BAD [BADCHARSET (US-ASCII \"[astring with brackets]\")] unsupported charset foo.\r\n") - assert_equal("t", response.tag) - assert_equal("unsupported charset foo.", response.data.text) - assert_equal("BADCHARSET", response.data.code.name) - end - - def test_continuation_request_without_response_text - parser = Net::IMAP::ResponseParser.new - response = parser.parse("+\r\n") - assert_instance_of(Net::IMAP::ContinuationRequest, response) - assert_equal(nil, response.data.code) - assert_equal("", response.data.text) - end - - def test_ignored_response - parser = Net::IMAP::ResponseParser.new - response = nil - assert_nothing_raised do - response = parser.parse("* NOOP\r\n") - end - assert_instance_of(Net::IMAP::IgnoredResponse, response) - end - - def test_namespace - parser = Net::IMAP::ResponseParser.new - # RFC2342 Example 5.1 - response = parser.parse(%Q{* NAMESPACE (("" "/")) NIL NIL\r\n}) - assert_equal("NAMESPACE", response.name) - assert_equal([Net::IMAP::Namespace.new("", "/", {})], response.data.personal) - assert_equal([], response.data.other) - assert_equal([], response.data.shared) - # RFC2342 Example 5.4 - response = parser.parse(%Q{* NAMESPACE (("" "/")) (("~" "/")) (("#shared/" "/")} + - %Q{ ("#public/" "/") ("#ftp/" "/") ("#news." "."))\r\n}) - assert_equal("NAMESPACE", response.name) - assert_equal([Net::IMAP::Namespace.new("", "/", {})], response.data.personal) - assert_equal([Net::IMAP::Namespace.new("~", "/", {})], response.data.other) - assert_equal( - [ - Net::IMAP::Namespace.new("#shared/", "/", {}), - Net::IMAP::Namespace.new("#public/", "/", {}), - Net::IMAP::Namespace.new("#ftp/", "/", {}), - Net::IMAP::Namespace.new("#news.", ".", {}), - ], - response.data.shared - ) - # RFC2342 Example 5.6 - response = parser.parse(%Q{* NAMESPACE (("" "/") ("#mh/" "/" "X-PARAM" ("FLAG1" "FLAG2"))) NIL NIL\r\n}) - assert_equal("NAMESPACE", response.name) - namespace = response.data.personal.last - assert_equal("#mh/", namespace.prefix) - assert_equal("/", namespace.delim) - assert_equal({"X-PARAM" => ["FLAG1", "FLAG2"]}, namespace.extensions) - end -end |