test_helper.rb 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. require 'minitest/autorun'
  2. require 'rack/mock'
  3. require 'byebug'
  4. require 'dav4rack'
  5. require 'nokogiri'
  6. require 'addressable/uri'
  7. class DAV4RackTest < MiniTest::Test
  8. def env_for(method, path, env = {})
  9. Rack::MockRequest::DEFAULT_ENV.merge(
  10. 'HTTP_HOST' => 'localhost',
  11. Rack::RACK_URL_SCHEME => 'http',
  12. 'REMOTE_USER' => 'user',
  13. 'PATH_INFO' => Addressable::URI.encode_component(path),
  14. 'REQUEST_METHOD' => method.to_s.upcase,
  15. ).merge env
  16. end
  17. end
  18. class DAV4RackIntegrationTest < DAV4RackTest
  19. DOC_ROOT = File.expand_path(File.dirname(__FILE__) + '/htdocs')
  20. METHODS = %w(GET PUT POST DELETE PROPFIND PROPPATCH MKCOL COPY MOVE OPTIONS HEAD LOCK UNLOCK)
  21. def setup
  22. FileUtils.mkdir_p(DOC_ROOT)
  23. end
  24. def teardown
  25. FileUtils.rm_rf(DOC_ROOT)
  26. end
  27. private
  28. METHODS.each do |method|
  29. define_method(method.downcase) do |*args|
  30. request(method, *args)
  31. end
  32. end
  33. def request(method, path = '/', input: nil, env: {}, options: {})
  34. env = env_for method, path, env
  35. if input
  36. input = StringIO.new input if input.is_a? String
  37. env[Rack::RACK_INPUT] = input
  38. env['CONTENT_LENGTH'] = input.size.to_s
  39. end
  40. if defined? @handler
  41. r = Rack::MockRequest.new(@handler)
  42. path = Addressable::URI.encode_component path
  43. @response = r.request(method, path, env)
  44. else
  45. @options ||= {
  46. root: DOC_ROOT,
  47. resource_class: DAV4Rack::FileResource
  48. }
  49. @options.update options
  50. @request = DAV4Rack::Request.new env, @options
  51. @response = Rack::Response.new
  52. @controller = DAV4Rack::Controller.new @request, @response, @options
  53. @controller.process
  54. @response = Rack::MockResponse.new @response.status, @response.headers, @response.body
  55. end
  56. end
  57. def url_escape(s)
  58. Addressable::URI.encode s
  59. end
  60. def response_xml
  61. Nokogiri.XML(@response.body){|config| config.strict}
  62. end
  63. def propfind_xml(*props)
  64. render(:propfind) do |xml|
  65. xml.prop do
  66. props.each do |prop|
  67. xml.send(prop.to_sym)
  68. end
  69. end
  70. end
  71. end
  72. def render(root_type)
  73. raise ArgumentError.new 'Expecting block' unless block_given?
  74. doc = Nokogiri::XML::Builder.new do |xml_base|
  75. xml_base.send(root_type.to_s, 'xmlns:D' => 'DAV:') do
  76. xml_base.parent.namespace = xml_base.parent.namespace_definitions.first
  77. xml = xml_base['D']
  78. yield xml
  79. end
  80. end
  81. doc.to_xml
  82. end
  83. STATUS_SYMBOLS = Hash[
  84. DAV4Rack::HTTPStatus::StatusMessage.map do |code, name|
  85. [name.gsub(/[ \-]/,'_').downcase.to_sym, code]
  86. end
  87. ]
  88. def assert_response(status)
  89. if status.is_a? Symbol
  90. status = STATUS_SYMBOLS[status]
  91. end
  92. assert_equal status, @response.status
  93. end
  94. def multistatus_response(pattern)
  95. assert_response :multi_status
  96. refute response_xml.xpath('//d:multistatus/d:response', response_xml.root.namespaces).empty?
  97. response_xml.xpath("//d:multistatus/d:response#{pattern}", response_xml.root.namespaces)
  98. end
  99. def multi_status_created
  100. refute response_xml.xpath('//d:multistatus/d:response/d:status').empty?
  101. assert_match(/Created/, response_xml.xpath('//d:multistatus/d:response/d:status').text)
  102. end
  103. def multi_status_ok
  104. refute response_xml.xpath('//d:multistatus/d:response/d:status').empty?
  105. assert_match(/OK/, response_xml.xpath('//d:multistatus/d:response/d:status').text)
  106. end
  107. def multi_status_no_content
  108. refute response_xml.xpath('//d:multistatus/d:response/d:status').empty?
  109. assert_match(/No Content/, response_xml.xpath('//d:multistatus/d:response/d:status').text)
  110. end
  111. end