#!/usr/bin/env ruby
# Copyright (C) 2003-2005 Kouichirou Eto, All rights reserved.

require "test/unit"
$LOAD_PATH << "../../lib" unless $LOAD_PATH.include?("../../lib")
require "qwik/request"
require "qwik/response"
require "qwik/memory"
require "qwik/server"

module Test
  class WEBrickRequest < WEBrick::HTTPRequest
    attr_writer :request_uri, :path, :peeraddr
    attr_writer :request_method, :cookies, :header, :query
    attr_writer :user
  end

  class WEBrickResponse < WEBrick::HTTPResponse
    def set_config
      @config.update(WEBrick::Config::HTTP)
    end
  end
end

class TC_Server < Test::Unit::TestCase
  def make_session(webrick_request, webrick_response)
    @req = Qwik::Request.new(@config)
    @req.parse_webrick(webrick_request)
    @res = Qwik::Response.new(@config)
    @res.set_webrick(webrick_response)
    @action = Qwik::Action.new(@config, @memory, @req, @res)
  end

  def test_server
    @config = Qwik::Config.new(true)
    @config.test = true # do not show webrick log
    @memory = Qwik::ServerMemory.new(@config)

    @server = Qwik::Server.new(@config, @memory)
#    trap(:TERM) { @server.shutdown; }
#    trap(:INT)  { @server.shutdown; }

    @webrick_request = Test::WEBrickRequest.new(@server.config)
    uri = URI.parse("http://example.com/test/")
    @webrick_request.request_uri = uri
    @webrick_request.path = "/FrontPage.html"
    @webrick_request.peeraddr = [nil, nil, nil, "127.0.0.1"]

    @webrick_response = Test::WEBrickResponse.new(@server.config)
    @webrick_response.set_config
    make_session(@webrick_request, @webrick_response)

    @action.run
    @res.setback(@webrick_response)
    assert_match(%r!\Atext/html!, @webrick_response["content-type"])
    if @webrick_response.body.is_a? String
      assert_match(%r|^<|, @webrick_response.body)
    elsif @webrick_response.body.is_a? Array
      assert_match(%r|^<|, @webrick_response.body)
    else
      assert_instance_of(File, @webrick_response.body)
      @webrick_response.body.close
    end

    @webrick_request.path = "/.theme/all.css"
    make_session(@webrick_request, @webrick_response)

    @action.run
    @res.setback(@webrick_response)
    assert_equal("text/css", @webrick_response["content-type"])
    assert_instance_of(File, @webrick_response.body)
    assert_match(%r|^/*|, @webrick_response.body.read)

    # test_head_session
    @webrick_request.path = "/FrontPage.html"
    webrick_request = @webrick_request.dup
    webrick_request.request_method = "HEAD"
    make_session(webrick_request, @webrick_response)

    @action.run
    @res.setback(@webrick_response)
    assert_match(%r!\Atext/html!, @webrick_response["content-type"])
    if @webrick_response.body.is_a? String
      assert_match(%r|^<|, @webrick_response.body)
    else
      assert_instance_of(File, @webrick_response.body)
      @webrick_response.body.close
    end

    webrick_request.path = "/.theme/all.css"
    make_session(webrick_request, @webrick_response)
    @action.run
    @res.setback(@webrick_response)
    assert_equal("text/css", @webrick_response["content-type"])
    assert_instance_of(File, @webrick_response.body)
    assert_match(%r|^/*|, @webrick_response.body.read)
  end
end

class TC_WEBrickRequest < Test::Unit::TestCase
  def assert_request(expected, req)
    ar = [req.domain, req.sitename, req.base, req.ext]
    assert_equal(expected, ar)
  end

  def test_parse_webrick
    @config = Qwik::Config.new(true)
    @config.test = true # do not show webrick log
    @memory = Qwik::ServerMemory.new(@config)

    @server = Qwik::Server.new(@config, @memory)
#    trap(:TERM) { @server.shutdown; }
#    trap(:INT)  { @server.shutdown; }

    @webrick_request = Test::WEBrickRequest.new(@server.config)

    @req = Qwik::Request.new(@config)

    @webrick_request.request_uri = URI.parse("http://example.com/")
    @webrick_request.path = "/"
    @req.parse_webrick(@webrick_request)
    assert_request(["example.com", "www", "FrontPage", "html"], @req)

    @webrick_request.request_uri = URI.parse("http://example.com/test/0.html")
    @webrick_request.path = "/test/0.html"
    @req.parse_webrick(@webrick_request)
    assert_request(["example.com", "test", "0", "html"], @req)

    # test_parse_webrick_env
    @webrick_request = Test::WEBrickRequest.new(@server.config)
    @webrick_request.path = "/"

    @webrick_request.peeraddr = [nil, nil, nil, "192.168.0.1"]
    @req.parse_webrick(@webrick_request)

    @webrick_request.request_method = "POST"
    @req.parse_webrick(@webrick_request)
    assert_equal("POST", @req.request_method)

    @webrick_request.request_method = "HEAD"
    @req.parse_webrick(@webrick_request)
    assert_equal("HEAD", @req.request_method)

    @webrick_request.request_method = "GET"
    @req.parse_webrick(@webrick_request)
    assert_equal("GET", @req.request_method)

    @webrick_request.header = {"x-test" => ["t"]}
    @req.parse_webrick(@webrick_request)
    assert_equal("t", @req["X-Test"])

    @webrick_request.cookies = []
    @webrick_request.cookies << WEBrick::Cookie.new("s", "t")
    @webrick_request.cookies << WEBrick::Cookie.new("k", "v")
    @req.parse_webrick(@webrick_request)
    assert_equal("t", @req.cookies["s"])
    assert_equal("v", @req.cookies["k"])

    @webrick_request.query = {"k" => "v"}
    @req.parse_webrick(@webrick_request)
    assert_equal("v", @req.query["k"])

    @req.parse_webrick(@webrick_request)

    @webrick_request.query = {"c" => "edit"}
    @req.parse_webrick(@webrick_request)
  end
end
