kong/spec/01-unit/01-db/01-schema/07-plugins_spec.lua (270 lines of code) (raw):
require "spec.helpers" -- initializes 'kong' global for plugins
local Entity = require "kong.db.schema.entity"
local typedefs = require "kong.db.schema.typedefs"
local utils = require "kong.tools.utils"
local routes_definition = require "kong.db.schema.entities.routes"
local services_definition = require "kong.db.schema.entities.services"
local consumers_definition = require "kong.db.schema.entities.consumers"
local plugins_definition = require "kong.db.schema.entities.plugins"
local dao_plugins = require "kong.db.dao.plugins"
local certificates_definition = require "kong.db.schema.entities.certificates"
describe("plugins", function()
local Plugins
local db
lazy_setup(function()
assert(Entity.new(consumers_definition))
assert(Entity.new(certificates_definition))
assert(Entity.new(services_definition))
assert(Entity.new(routes_definition))
Plugins = assert(Entity.new(plugins_definition))
local my_plugins = {
"key-auth",
"rate-limiting",
"response-transformer",
"request-transformer",
}
local loaded_plugins = {}
for _, v in ipairs(my_plugins) do
loaded_plugins[v] = true
end
local kong_conf = {
anonymous_reports = false,
loaded_plugins = loaded_plugins,
}
db = {
plugins = {
schema = Plugins,
each = function()
local i = 0
return function()
i = i + 1
if my_plugins[i] then
return { name = my_plugins[i] }
end
end
end,
},
}
assert(dao_plugins.load_plugin_schemas({
db = db.plugins,
schema = Plugins,
}, kong_conf.loaded_plugins))
end)
it("has a cache_key", function()
assert.is_table(Plugins.cache_key)
end)
it("should not validate if the plugin doesn't exist (not installed)", function()
local plugin = {
name = "world domination"
}
plugin = Plugins:process_auto_fields(plugin)
local valid, err = Plugins:validate(plugin)
assert.falsy(valid)
assert.equal("plugin 'world domination' not enabled; add it to the 'plugins' configuration property", err.name)
end)
it("should validate a plugin configuration's `config` field", function()
-- Success
local plugin = {
name = "key-auth",
service = { id = utils.uuid() },
config = {
key_names = { "x-kong-key" }
}
}
plugin = Plugins:process_auto_fields(plugin)
local valid, err = Plugins:validate(plugin)
assert.same(nil, err)
assert.is_true(valid)
-- Failure
plugin = {
name = "rate-limiting",
service = { id = utils.uuid() },
config = {
second = "hello"
}
}
plugin = Plugins:process_auto_fields(plugin)
local errors
valid, errors = Plugins:validate(plugin)
assert.falsy(valid)
assert.same({
config = {
second = "expected a number"
}
}, errors)
end)
it("should produce a base config if none is specified and the config field does not have a top-level default", function()
-- Insert key-auth, whose config has some default values that should be set
local plugin = {
name = "key-auth",
service = { id = utils.uuid() },
}
plugin = Plugins:process_auto_fields(plugin)
local ok = Plugins:validate(plugin)
assert.is_true(ok)
assert.same({
key_names = { "apikey" },
hide_credentials = false,
anonymous = ngx.null,
key_in_header = true,
key_in_query = true,
key_in_body = false,
run_on_preflight = true,
}, plugin.config)
end)
it("should be valid if no value is specified for a subfield and if the config schema has default as empty array", function()
-- Insert response-transformer, whose default config has no default values, and should be empty
local plugin = {
name = "response-transformer",
service = { id = utils.uuid() },
}
plugin = Plugins:process_auto_fields(plugin)
local ok = Plugins:validate(plugin)
assert.is_true(ok)
assert.same({
remove = {
headers = {},
json = {}
},
rename = {
headers = {},
},
replace = {
headers = {},
json = {},
json_types = {}
},
add = {
headers = {},
json = {},
json_types = {}
},
append = {
headers = {},
json = {},
json_types = {}
}
}, plugin.config)
end)
describe("should refuse if criteria in plugin schema not met", function()
it("no_route", function()
local subschema = {
name = "with-no-route",
fields = {
{ route = typedefs.no_route },
{ config = {
type = "record",
fields = {
{ string = { type = "string", required = true } },
}
} }
}
}
assert(db.plugins.schema:new_subschema(subschema.name, subschema))
local ok, err = Plugins:validate(Plugins:process_auto_fields({
name = "with-no-route",
route = { id = utils.uuid() },
config = {
string = "foo",
}
}))
assert.falsy(ok)
assert.same({
route = "value must be null",
}, err)
ok = Plugins:validate(Plugins:process_auto_fields({
name = "with-no-route",
route = ngx.null,
config = {
string = "foo",
}
}))
assert.truthy(ok)
end)
it("no_service", function()
local subschema = {
name = "with-no-service",
fields = {
{ service = typedefs.no_service },
{ config = {
type = "record",
fields = {
{ string = { type = "string", required = true } },
}
} }
}
}
assert(db.plugins.schema:new_subschema(subschema.name, subschema))
local ok, err = Plugins:validate(Plugins:process_auto_fields({
name = "with-no-service",
service = { id = utils.uuid() },
config = {
string = "foo",
}
}))
assert.falsy(ok)
assert.same({
service = "value must be null",
}, err)
ok = Plugins:validate(Plugins:process_auto_fields({
name = "with-no-service",
service = ngx.null,
config = {
string = "foo",
}
}))
assert.truthy(ok)
end)
it("no_consumer", function()
local subschema = {
name = "with-no-consumer",
fields = {
{ consumer = typedefs.no_consumer },
{ config = {
type = "record",
fields = {
{ string = { type = "string", required = true } },
}
} }
}
}
assert(db.plugins.schema:new_subschema(subschema.name, subschema))
local ok, err = Plugins:validate(Plugins:process_auto_fields({
name = "with-no-consumer",
consumer = { id = utils.uuid() },
config = {
string = "foo",
}
}))
assert.falsy(ok)
assert.same({
consumer = "value must be null",
}, err)
ok = Plugins:validate(Plugins:process_auto_fields({
name = "with-no-consumer",
consumer = ngx.null,
config = {
string = "foo",
}
}))
assert.truthy(ok)
end)
it("accepts a plugin if configured for route", function()
assert(Plugins:validate(Plugins:process_auto_fields({
name = "key-auth",
route = { id = utils.uuid() },
})))
end)
it("accepts a plugin if configured for service", function()
assert(Plugins:validate(Plugins:process_auto_fields({
name = "key-auth",
service = { id = utils.uuid() },
})))
end)
it("accepts a plugin if configured for consumer", function()
assert(Plugins:validate(Plugins:process_auto_fields({
name = "rate-limiting",
consumer = { id = utils.uuid() },
config = {
second = 1,
}
})))
end)
end)
end)