require 'test_helper'

class ProxyRuleTest < ActiveSupport::TestCase

  test 'patterns' do
    proxy_rule = FactoryGirl.build_stubbed(:proxy_rule)

    ["/" , "/test/", "/foo/{bar}/baz/{foo}/quux",
     "/foo/{whatever}.json", "/foo/bar.json", "/foo.ext1/bar.ext2",
     "/v1/word/{word}.json?app_id={app_id}&app_key={app_key}", "/foo$",
     "/foo$?bar=baz", "/$" ,"/\$"].each do |pattern|
      proxy_rule.pattern = pattern
      assert proxy_rule.valid? , "#{pattern} should be valid"
    end

    ["", "foo", "/foo{lal}/", "/foo/{bar}k/baz/{p}/quux",
     "/foo?{a}=bar", "/micro$oft", "/$$" ].each do |pattern|
      proxy_rule.pattern = pattern

      refute proxy_rule.valid?, "#{pattern} should be invalid"
      assert proxy_rule.errors[:pattern], pattern.presence
    end
  end

  test 'duplicated vars' do
    proxy_rule = FactoryGirl.build_stubbed(:proxy_rule)
    proxy_rule.pattern = "/foo/{bar}/baz/{bar}/quux"
    proxy_rule.valid?
    assert proxy_rule.errors[:pattern].presence
  end

  test 'duplicated params with var and var' do
    proxy_rule = FactoryGirl.build_stubbed(:proxy_rule)
    proxy_rule.pattern = "/foo/bar/baz?a={foo}&a={bar}"
    proxy_rule.valid?
    assert proxy_rule.errors[:pattern].presence
  end

  test 'duplicated params with var and fixed' do
    proxy_rule = FactoryGirl.build_stubbed(:proxy_rule)
    proxy_rule.pattern = "/foo/bar/baz?a=foo&a={bar}"
    proxy_rule.valid?
    assert proxy_rule.errors[:pattern].presence
  end

  test 'duplicated params with fixed and fixed' do
    proxy_rule = FactoryGirl.build_stubbed(:proxy_rule)
    proxy_rule.pattern = "/foo/bar/baz?a=foo&a={bar}"
    proxy_rule.valid?
    assert proxy_rule.errors[:pattern].presence
  end

  test 'params in path' do
    proxy_rule = ProxyRule.new(:pattern => "/foo/{word}/{item}.json")
    assert_equal 'word' ,  proxy_rule.parameters.first
    assert_equal 'item' ,  proxy_rule.parameters.last
  end

  test 'params in the querystring' do
    proxy_rule = ProxyRule.new(:pattern => "/foo/word/{item}.json?action={action}")
    assert_equal ['action', '{action}'] , proxy_rule.querystring_parameters.first
  end

  test 'params in the querystring without {brackets} are not unordered' do
    proxy_rule = ProxyRule.new(:pattern => "/foo/word/{item}.json?foo=bar&action={action}")
    assert_equal 'bar', proxy_rule.querystring_parameters["foo"]
    assert_equal '{action}' , proxy_rule.querystring_parameters["action"]
    assert_equal 2 , proxy_rule.querystring_parameters.size
  end

  test 'pattern ending with ? works' do
    proxy_rule = ProxyRule.new(:pattern => "/foo/word/{item}.json?")
    assert_equal Hash.new , proxy_rule.querystring_parameters
  end

  # Regression test for https://github.com/3scale/system/issues/5898
  test 'pattern with more than 1 = per & should not raise error' do
    proxy_rule = ProxyRule.new(:pattern => "?foo=bar=lol")
    assert_equal({"foo" => "bar=lol"}, proxy_rule.querystring_parameters)
  end

  test '256 is the max length' do
    proxy_rule = FactoryGirl.build_stubbed(:proxy_rule)
    proxy_rule.pattern = '/'+ ("a" * 255)
    assert proxy_rule.valid?, proxy_rule.errors.to_a.to_sentence

    proxy_rule.pattern = '/'+ ("a" * 256)
    refute proxy_rule.valid?
  end

  test 'redirect_url' do
    # should accept a nil value
    proxy_rule = FactoryGirl.build_stubbed(:proxy_rule, redirect_url: nil)
    assert proxy_rule.valid?

    # should validate that is an URL
    proxy_rule = FactoryGirl.build_stubbed(:proxy_rule, redirect_url: 'foo')
    refute proxy_rule.valid?

    # should accept an url with http
    proxy_rule.redirect_url = 'http://example.com/foo/bar?foo=bar&bar=foo'
    assert proxy_rule.valid?

    # should accept an url with http
    proxy_rule.redirect_url = 'https://example.com/foo/bar?foo=bar&bar=foo'
    assert proxy_rule.valid?

    # should do not accept url without protocol
    proxy_rule.redirect_url = '//example.com/foo/bar?foo=bar&bar=foo'
    refute proxy_rule.valid?

    # should do not accept other protocols
    proxy_rule.redirect_url = 'ftp//example.com/foo/bar?foo=bar&bar=foo'
    refute proxy_rule.valid?

    # should not accept string of more than 10000 characters
    proxy_rule.redirect_url = "https://example.com/#{'1' * 9981}"
    refute proxy_rule.valid?

    # should accept string up to 10000 characters
    proxy_rule.redirect_url = "https://example.com/#{'1' * 9980}"
    assert proxy_rule.valid?

    proxy_rule.save!
  end
end
