kong/spec/02-integration/01-helpers/01-helpers_spec.lua (456 lines of code) (raw):
local helpers = require "spec.helpers"
local cjson = require "cjson"
for _, strategy in helpers.each_strategy() do
describe("helpers [#" .. strategy .. "]: assertions and modifiers", function()
local proxy_client
lazy_setup(function()
local bp = helpers.get_db_utils(strategy, {
"routes",
"services",
})
local service = bp.services:insert {
host = helpers.mock_upstream_host,
port = helpers.mock_upstream_port,
protocol = helpers.mock_upstream_protocol,
}
bp.routes:insert {
hosts = { "mock_upstream" },
protocols = { "http" },
service = service
}
assert(helpers.start_kong({
database = strategy,
nginx_conf = "spec/fixtures/custom_nginx.template",
}))
end)
lazy_teardown(function()
helpers.stop_kong()
end)
before_each(function()
proxy_client = helpers.proxy_client(5000)
end)
after_each(function()
if proxy_client then
proxy_client:close()
end
end)
describe("http_client", function()
it("encodes nested tables and arrays in Kong-compatible way when using form-urlencoded content-type", function()
local tests = {
{ input = { names = { "alice", "bob", "casius" } },
expected = { ["names[1]"] = "alice",
["names[2]"] = "bob",
["names[3]"] = "casius" } },
{ input = { headers = { location = { "here", "there", "everywhere" } } },
expected = { ["headers.location[1]"] = "here",
["headers.location[2]"] = "there",
["headers.location[3]"] = "everywhere" } },
{ input = { ["hello world"] = "foo, bar" } ,
expected = { ["hello world"] = "foo, bar" } },
{ input = { hash = { answer = 42 } },
expected = { ["hash.answer"] = "42" } },
{ input = { hash_array = { arr = { "one", "two" } } },
expected = { ["hash_array.arr[1]"] = "one",
["hash_array.arr[2]"] = "two" } },
{ input = { array_hash = { { name = "peter" } } },
expected = { ["array_hash[1].name"] = "peter" } },
{ input = { array_array = { { "x", "y" } } },
expected = { ["array_array[1][1]"] = "x",
["array_array[1][2]"] = "y" } },
{ input = { hybrid = { 1, 2, n = 3 } },
expected = { ["hybrid[1]"] = "1",
["hybrid[2]"] = "2",
["hybrid.n"] = "3" } },
}
for i = 1, #tests do
local r = proxy_client:get("/", {
headers = {
["Content-type"] = "application/x-www-form-urlencoded",
host = "mock_upstream",
},
body = tests[i].input
})
local json = assert.response(r).has.jsonbody()
assert.same(tests[i].expected, json.post_data.params)
end
end)
end)
describe("get_version()", function()
it("gets the version of Kong running", function()
local meta = require 'kong.meta'
local version = require 'version'
assert.equal(version(meta._VERSION), helpers.get_version())
end)
end)
describe("wait_until()", function()
it("does not errors out if thing happens", function()
assert.has_no_error(function()
local i = 0
helpers.wait_until(function()
i = i + 1
return i > 1
end, 3)
end)
end)
it("errors out after delay", function()
assert.error_matches(function()
helpers.wait_until(function()
return false, "thing still not done"
end, 1)
end, "timeout: thing still not done")
end)
it("reports errors in test function", function()
assert.error_matches(function()
helpers.wait_until(function()
assert.equal("foo", "bar")
end, 1)
end, "Expected objects to be equal.", nil, true)
end)
end)
describe("response modifier", function()
it("fails with bad input", function()
assert.error(function() assert.response().True(true) end)
assert.error(function() assert.response(true).True(true) end)
assert.error(function() assert.response("bad...").True(true) end)
end)
it("succeeds with a mock_upstream response", function()
local r = assert(proxy_client:send {
method = "GET",
path = "/request",
headers = {
host = "mock_upstream",
},
})
assert.response(r).True(true)
end)
it("succeeds with a mock upstream response", function()
local r = assert(proxy_client:send {
method = "GET",
path = "/anything",
headers = {
host = "mock_upstream",
},
})
assert.response(r).True(true)
end)
end)
describe("request modifier", function()
it("fails with bad input", function()
assert.error(function() assert.request().True(true) end)
assert.error(function() assert.request(true).True(true) end)
assert.error(function() assert.request("bad... ").True(true) end)
end)
it("succeeds with a mock_upstream response", function()
local r = assert(proxy_client:send {
method = "GET",
path = "/request",
headers = {
host = "mock_upstream",
},
})
assert.request(r).True(true)
end)
it("succeeds with a mock_upstream response", function()
-- GET request
local r = assert(proxy_client:send {
method = "GET",
path = "/get",
headers = {
host = "mock_upstream",
},
})
assert.request(r).True(true)
-- POST request
local r = assert(proxy_client:send {
method = "POST",
path = "/post",
body = {
v1 = "v2",
},
headers = {
host = "mock_upstream",
["Content-Type"] = "www-form-urlencoded",
},
})
assert.request(r).True(true)
end)
it("fails with a non mock_upstream response", function()
local r = assert(proxy_client:send {
method = "GET",
path = "/headers", -- this path is not supported, but should yield valid json for the test
headers = {
host = "127.0.0.1:15555",
},
})
assert.error(function() assert.request(r).True(true) end)
end)
end)
describe("contains assertion", function()
it("verifies content properly", function()
local arr = { "one", "three" }
assert.equals(1, assert.contains("one", arr))
assert.not_contains("two", arr)
assert.equals(2, assert.contains("ee$", arr, true))
end)
end)
describe("status assertion", function()
it("succeeds with a response", function()
local r = assert(proxy_client:send {
method = "GET",
path = "/get",
headers = {
host = "mock_upstream",
},
})
assert.status(200, r)
local body = assert.response(r).has.status(200)
assert(cjson.decode(body))
local r = assert(proxy_client:send {
method = "GET",
path = "/status/404",
headers = {
host = "mock_upstream",
},
})
assert.response(r).has.status(404)
end)
it("fails with bad input", function()
assert.error(function() assert.status(200, nil) end)
assert.error(function() assert.status(200, {}) end)
end)
end)
describe("jsonbody assertion", function()
it("fails with explicit or no parameters", function()
assert.error(function() assert.jsonbody({}) end)
assert.error(function() assert.jsonbody() end)
end)
it("succeeds on a response object on /request", function()
local r = assert(proxy_client:send {
method = "GET",
path = "/request",
headers = {
host = "mock_upstream",
},
})
local json = assert.response(r).has.jsonbody()
assert(json.url:find(helpers.mock_upstream_host), "expected a mock_upstream response")
end)
it("succeeds on a mock_upstream request object on /request", function()
local r = assert(proxy_client:send {
method = "GET",
path = "/request",
body = { hello = "world" },
headers = {
host = "mock_upstream",
["Content-Type"] = "application/json",
},
})
local json = assert.request(r).has.jsonbody()
assert.equals("world", json.params.hello)
end)
it("succeeds on a mock_upstream request object on /post", function()
local r = assert(proxy_client:send {
method = "POST",
path = "/post",
body = { hello = "world" },
headers = {
host = "mock_upstream",
["Content-Type"] = "application/json",
},
})
local json = assert.request(r).has.jsonbody()
assert.equals("world", json.params.hello)
end)
end)
describe("header assertion", function()
it("checks appropriate response headers", function()
local r = assert(proxy_client:send {
method = "GET",
path = "/request",
body = { hello = "world" },
headers = {
host = "mock_upstream",
["Content-Type"] = "application/json",
},
})
local v1 = assert.response(r).has.header("x-powered-by")
local v2 = assert.response(r).has.header("X-POWERED-BY")
assert.equals(v1, v2)
assert.error(function() assert.response(r).has.header("does not exists") end)
end)
it("checks appropriate mock_upstream request headers", function()
local r = assert(proxy_client:send {
method = "GET",
path = "/request",
headers = {
host = "mock_upstream",
["just-a-test-header"] = "just-a-test-value"
}
})
local v1 = assert.request(r).has.header("just-a-test-header")
local v2 = assert.request(r).has.header("just-a-test-HEADER")
assert.equals("just-a-test-value", v1)
assert.equals(v1, v2)
assert.error(function() assert.response(r).has.header("does not exists") end)
end)
it("checks appropriate mock_upstream request headers", function()
local r = assert(proxy_client:send {
method = "GET",
path = "/get",
headers = {
host = "mock_upstream",
["just-a-test-header"] = "just-a-test-value"
}
})
local v1 = assert.request(r).has.header("just-a-test-header")
local v2 = assert.request(r).has.header("just-a-test-HEADER")
assert.equals("just-a-test-value", v1)
assert.equals(v1, v2)
assert.error(function() assert.response(r).has.header("does not exists") end)
end)
end)
describe("queryParam assertion", function()
it("checks appropriate mock_upstream query parameters", function()
local r = assert(proxy_client:send {
method = "GET",
path = "/request",
query = {
hello = "world",
},
headers = {
host = "mock_upstream",
},
})
local v1 = assert.request(r).has.queryparam("hello")
local v2 = assert.request(r).has.queryparam("HELLO")
assert.equals("world", v1)
assert.equals(v1, v2)
assert.error(function() assert.response(r).has.queryparam("notHere") end)
end)
it("checks appropriate mock_upstream query parameters", function()
local r = assert(proxy_client:send {
method = "POST",
path = "/post",
query = {
hello = "world",
},
body = {
hello2 = "world2",
},
headers = {
host = "mock_upstream",
["Content-Type"] = "application/json",
},
})
local v1 = assert.request(r).has.queryparam("hello")
local v2 = assert.request(r).has.queryparam("HELLO")
assert.equals("world", v1)
assert.equals(v1, v2)
assert.error(function() assert.response(r).has.queryparam("notHere") end)
end)
end)
describe("formparam assertion", function()
it("checks appropriate mock_upstream url-encoded form parameters", function()
local r = assert(proxy_client:send {
method = "POST",
path = "/request",
body = {
hello = "world",
},
headers = {
host = "mock_upstream",
["Content-Type"] = "application/x-www-form-urlencoded",
},
})
local v1 = assert.request(r).has.formparam("hello")
local v2 = assert.request(r).has.formparam("HELLO")
assert.equals("world", v1)
assert.equals(v1, v2)
assert.error(function() assert.request(r).has.queryparam("notHere") end)
end)
it("fails with mock_upstream non-url-encoded form data", function()
local r = assert(proxy_client:send {
method = "POST",
path = "/request",
body = {
hello = "world",
},
headers = {
host = "mock_upstream",
["Content-Type"] = "application/json",
},
})
assert.error(function() assert.request(r).has.formparam("hello") end)
end)
it("checks appropriate mock_upstream url-encoded form parameters", function()
local r = assert(proxy_client:send {
method = "POST",
path = "/post",
body = {
hello = "world",
},
headers = {
host = "mock_upstream",
["Content-Type"] = "application/x-www-form-urlencoded",
},
})
local v1 = assert.request(r).has.formparam("hello")
local v2 = assert.request(r).has.formparam("HELLO")
assert.equals("world", v1)
assert.equals(v1, v2)
assert.error(function() assert.request(r).has.queryparam("notHere") end)
end)
it("fails with mock_upstream non-url-encoded form parameters", function()
local r = assert(proxy_client:send {
method = "POST",
path = "/post",
body = {
hello = "world"
},
headers = {
host = "mock_upstream",
["Content-Type"] = "application/json",
},
})
assert.error(function() assert.request(r).has.formparam("hello") end)
end)
end)
describe("certificates,", function()
local function get_cert(server_name)
local _, _, stdout = assert(helpers.execute(
string.format("echo 'GET /' | openssl s_client -connect 0.0.0.0:%d -servername %s",
helpers.get_proxy_port(true), server_name)
))
return stdout
end
it("cn assertion with 2 parameters, positive success", function()
local cert = get_cert("ssl1.com")
assert.has.cn("localhost", cert)
end)
it("cn assertion with 2 parameters, positive failure", function()
local cert = get_cert("ssl1.com")
assert.has.error(function()
assert.has.cn("some.other.host.org", cert)
end)
end)
it("cn assertion with 2 parameters, negative success", function()
local cert = get_cert("ssl1.com")
assert.Not.cn("some.other.host.org", cert)
end)
it("cn assertion with 2 parameters, negative failure", function()
local cert = get_cert("ssl1.com")
assert.has.error(function()
assert.Not.cn("localhost", cert)
end)
end)
it("cn assertion with modifier and 1 parameter", function()
local cert = get_cert("ssl1.com")
assert.certificate(cert).has.cn("localhost")
end)
it("cn assertion with modifier and 2 parameters fails", function()
local cert = get_cert("ssl1.com")
assert.has.error(function()
assert.certificate(cert).has.cn("localhost", cert)
end)
end)
end)
end)
end