Files
2026-07-13 12:32:21 +08:00

293 lines
8.1 KiB
Lua

local helpers = require "spec.helpers"
local meta = require "kong.meta"
local http_mock = require "spec.helpers.http_mock"
local server_tokens = meta._SERVER_TOKENS
for _, strategy in helpers.each_strategy() do
describe("Plugin: Azure Functions (access) [#" .. strategy .. "]", function()
local mock
local proxy_client
local mock_http_server_port
setup(function()
mock_http_server_port = helpers.get_available_port()
mock = http_mock.new("127.0.0.1:" .. mock_http_server_port, {
["/"] = {
access = [[
local json = require "cjson"
local method = ngx.req.get_method()
local uri = ngx.var.request_uri
local headers = ngx.req.get_headers(nil, true)
local query_args = ngx.req.get_uri_args()
ngx.req.read_body()
local body
-- collect body
body = ngx.req.get_body_data()
if not body then
local file = ngx.req.get_body_file()
if file then
local f = io.open(file, "r")
if f then
body = f:read("*a")
f:close()
end
end
end
ngx.say(json.encode({
query_args = query_args,
uri = uri,
method = method,
headers = headers,
body = body,
status = 200,
}))
]]
},
})
local _, db = helpers.get_db_utils(strategy, {
"routes",
"services",
"plugins",
})
local route2 = db.routes:insert {
hosts = { "azure2.test" },
protocols = { "http", "https" },
}
-- Mocking lua-resty-http's request_uri function
db.plugins:insert {
name = "pre-function",
route = { id = route2.id },
config = {
access = {
[[
local http = require "resty.http"
local json = require "cjson"
local _request_uri = http.request_uri
http.request_uri = function (self, uri, params)
local scheme, host, port, _, _ = unpack(http:parse_uri(uri))
local mock_server_port = ]] .. mock_http_server_port .. [[
-- Replace the port with the mock server port
local new_uri = string.format("%s://%s:%d", scheme, host, mock_server_port)
return _request_uri(self, new_uri, params)
end
]]
}
}
}
db.plugins:insert {
name = "azure-functions",
route = { id = route2.id },
config = {
https = false,
appname = "azure",
hostdomain = "example.test",
routeprefix = "request",
functionname = "test-func-name",
apikey = "anything_but_an_API_key",
clientid = "and_no_clientid",
},
}
local fixtures = {
dns_mock = helpers.dns_mock.new()
}
local route3 = db.routes:insert {
hosts = { "azure3.test" },
protocols = { "http", "https" },
service = db.services:insert(
{
name = "azure3",
host = "azure.example.test", -- just mock service, it will not be requested
port = 80,
path = "/request",
}
),
}
-- this plugin definition results in an upstream url to
-- http://mockbin.org/request
-- which will echo the request for inspection
db.plugins:insert {
name = "azure-functions",
route = { id = route3.id },
config = {
https = false,
appname = "azure",
hostdomain = "example.test",
routeprefix = "request",
functionname = "test-func-name",
apikey = "anything_but_an_API_key",
clientid = "and_no_clientid",
},
}
fixtures.dns_mock:A({
name = "azure.example.test",
address = "127.0.0.1",
})
assert(helpers.start_kong({
database = strategy,
untrusted_lua = "on",
plugins = "azure-functions,pre-function",
}, nil, nil, fixtures))
assert(mock:start())
end) -- setup
before_each(function()
proxy_client = helpers.proxy_client()
end)
after_each(function ()
proxy_client:close()
end)
teardown(function()
helpers.stop_kong()
assert(mock:stop())
end)
it("passes request query parameters", function()
local res = assert(proxy_client:send {
method = "GET",
path = "/",
query = { hello = "world" },
headers = {
["Host"] = "azure2.test"
}
})
assert.response(res).has.status(200)
local json = assert.response(res).has.jsonbody()
assert.same({ hello ="world" }, json.query_args)
end)
it("passes request body", function()
local body = "I'll be back"
local res = assert(proxy_client:send {
method = "GET",
path = "/",
body = body,
query = { hello = "world" },
headers = {
["Host"] = "azure2.test"
}
})
assert.response(res).has.status(200)
local json = assert.response(res).has.jsonbody()
assert.same(body, json.body)
end)
it("passes the path parameters", function()
local res = assert(proxy_client:send {
method = "GET",
path = "/and/then/some",
headers = {
["Host"] = "azure2.test"
}
})
assert.response(res).has.status(200)
local json = assert.response(res).has.jsonbody()
assert.matches("/request/test%-func%-name", json.uri)
end)
it("passes the method", function()
local res = assert(proxy_client:send {
method = "POST",
path = "/",
headers = {
["Host"] = "azure2.test"
}
})
assert.response(res).has.status(200)
local json = assert.response(res).has.jsonbody()
assert.same("POST", json.method)
end)
it("passes the headers", function()
local res = assert(proxy_client:send {
method = "GET",
path = "/and/then/some",
headers = {
["Host"] = "azure2.test",
["Just-A-Header"] = "just a value",
}
})
assert.response(res).has.status(200)
local json = assert.response(res).has.jsonbody()
assert.same("just a value", json.headers["just-a-header"])
end)
it("injects the apikey and clientid", function()
local res = assert(proxy_client:send {
method = "POST",
path = "/",
headers = {
["Host"] = "azure2.test"
}
})
assert.response(res).has.status(200)
local json = assert.response(res).has.jsonbody()
--assert.same({}, json.headers)
assert.same("anything_but_an_API_key", json.headers["x-functions-key"])
assert.same("and_no_clientid", json.headers["x-functions-clientid"])
end)
it("returns server tokens with Via header", function()
local res = assert(proxy_client:send {
method = "GET",
path = "/",
query = { hello = "world" },
headers = {
["Host"] = "azure2.test"
}
})
assert.equal("2 " .. server_tokens, res.headers["Via"])
end)
it("returns Content-Length header", function()
local res = assert(proxy_client:send {
method = "GET",
path = "/",
query = { hello = "world" },
headers = {
["Host"] = "azure2.test"
}
})
assert(tonumber(res.headers["Content-Length"]) > 100)
end)
it("service upstream uri and request uri can not influence azure function", function()
local res = assert(proxy_client:send {
method = "GET",
path = "/",
query = { hello = "world" },
headers = {
["Host"] = "azure3.test"
}
})
assert(tonumber(res.headers["Content-Length"]) > 100)
end)
end) -- describe
end