Skip to content

Commit

Permalink
refactor: entities schemas structure and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
thibaultcha committed May 28, 2015
1 parent 256e0a5 commit dc8cbdd
Show file tree
Hide file tree
Showing 14 changed files with 131 additions and 129 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ install:
OPENSSL_LIBDIR=`find / -type f -name "libssl.so*" -print -quit | xargs dirname`; \
fi

dev:
dev: install
@for rock in $(DEV_ROCKS) ; do \
if ! command -v $$rock &> /dev/null ; then \
echo $$rock not found, installing via luarocks... ; \
Expand Down
5 changes: 4 additions & 1 deletion kong-0.3.0-1.rockspec
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,10 @@ build = {
["kong.resolver.resolver_util"] = "kong/resolver/resolver_util.lua",

["kong.dao.error"] = "kong/dao/error.lua",
["kong.dao.schemas"] = "kong/dao/schemas.lua",
["kong.dao.schemas_validation"] = "kong/dao/schemas_validation.lua",
["kong.dao.schemas.apis"] = "kong/dao/schemas/apis.lua",
["kong.dao.schemas.consumers"] = "kong/dao/schemas/consumers.lua",
["kong.dao.schemas.plugins_configurations"] = "kong/dao/schemas/plugins_configurations.lua",
["kong.dao.cassandra.factory"] = "kong/dao/cassandra/factory.lua",
["kong.dao.cassandra.base_dao"] = "kong/dao/cassandra/base_dao.lua",
["kong.dao.cassandra.apis"] = "kong/dao/cassandra/apis.lua",
Expand Down
30 changes: 3 additions & 27 deletions kong/dao/cassandra/apis.lua
Original file line number Diff line number Diff line change
@@ -1,36 +1,12 @@
local BaseDao = require "kong.dao.cassandra.base_dao"
local constants = require "kong.constants"
local apis_schema = require "kong.dao.schemas.apis"
local PluginsConfigurations = require "kong.dao.cassandra.plugins_configurations"
local url = require "socket.url"

local function validate_target_url(value)
local parsed_url = url.parse(value)
if parsed_url.scheme and parsed_url.host then
parsed_url.scheme = parsed_url.scheme:lower()
if parsed_url.scheme == "http" or parsed_url.scheme == "https" then
parsed_url.path = parsed_url.path or "/"
return true, nil, { target_url = url.build(parsed_url)}
else
return false, "Supported protocols are HTTP and HTTPS"
end
end

return false, "Invalid target URL"
end

local SCHEMA = {
id = { type = constants.DATABASE_TYPES.ID },
name = { type = "string", unique = true, queryable = true, default = function(api_t) return api_t.public_dns end },
public_dns = { type = "string", required = true, unique = true, queryable = true,
regex = "([a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*)" },
target_url = { type = "string", required = true, func = validate_target_url },
created_at = { type = constants.DATABASE_TYPES.TIMESTAMP }
}

local Apis = BaseDao:extend()

function Apis:new(properties)
self._schema = SCHEMA
self._entity = "API"
self._schema = apis_schema
self._queries = {
insert = {
args_keys = { "id", "name", "public_dns", "target_url", "created_at" },
Expand Down
2 changes: 1 addition & 1 deletion kong/dao/cassandra/base_dao.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
local constants = require "kong.constants"
local cassandra = require "cassandra"
local timestamp = require "kong.tools.timestamp"
local validate = require("kong.dao.schemas").validate
local validate = require("kong.dao.schemas_validation").validate
local DaoError = require "kong.dao.error"
local stringy = require "stringy"
local Object = require "classic"
Expand Down
21 changes: 3 additions & 18 deletions kong/dao/cassandra/consumers.lua
Original file line number Diff line number Diff line change
@@ -1,27 +1,12 @@
local BaseDao = require "kong.dao.cassandra.base_dao"
local stringy = require "stringy"
local constants = require "kong.constants"
local consumers_schema = require "kong.dao.schemas.consumers"
local PluginsConfigurations = require "kong.dao.cassandra.plugins_configurations"

local function check_custom_id_and_username(value, consumer_t)
if (consumer_t.custom_id == nil or stringy.strip(consumer_t.custom_id) == "")
and (consumer_t.username == nil or stringy.strip(consumer_t.username) == "") then
return false, "At least a 'custom_id' or a 'username' must be specified"
end
return true
end

local SCHEMA = {
id = { type = constants.DATABASE_TYPES.ID },
custom_id = { type = "string", unique = true, queryable = true, func = check_custom_id_and_username },
username = { type = "string", unique = true, queryable = true, func = check_custom_id_and_username },
created_at = { type = constants.DATABASE_TYPES.TIMESTAMP }
}

local Consumers = BaseDao:extend()

function Consumers:new(properties)
self._schema = SCHEMA
self._entity = "Consumer"
self._schema = consumers_schema
self._queries = {
insert = {
args_keys = { "id", "custom_id", "username", "created_at" },
Expand Down
27 changes: 3 additions & 24 deletions kong/dao/cassandra/plugins_configurations.lua
Original file line number Diff line number Diff line change
@@ -1,34 +1,13 @@
local plugins_configurations_schema = require "kong.dao.schemas.plugins_configurations"
local constants = require "kong.constants"
local BaseDao = require "kong.dao.cassandra.base_dao"
local cjson = require "cjson"
local utils = require "kong.tools.utils"

local function load_value_schema(plugin_t)
if plugin_t.name then
local loaded, plugin_schema = utils.load_module_if_exists("kong.plugins."..plugin_t.name..".schema")
if loaded then
return plugin_schema
else
return nil, "Plugin \""..(plugin_t.name and plugin_t.name or "").."\" not found"
end
end
end

local SCHEMA = {
id = { type = constants.DATABASE_TYPES.ID },
api_id = { type = constants.DATABASE_TYPES.ID, required = true, foreign = true, queryable = true },
consumer_id = { type = constants.DATABASE_TYPES.ID, foreign = true, queryable = true, default = constants.DATABASE_NULL_ID },
name = { type = "string", required = true, queryable = true, immutable = true },
value = { type = "table", schema = load_value_schema },
enabled = { type = "boolean", default = true },
created_at = { type = constants.DATABASE_TYPES.TIMESTAMP }
}

local PluginsConfigurations = BaseDao:extend()

function PluginsConfigurations:new(properties)
self._entity = "Plugin"
self._schema = SCHEMA
self._entity = "Plugin configuration"
self._schema = plugins_configurations_schema
self._queries = {
insert = {
args_keys = { "id", "api_id", "consumer_id", "name", "value", "enabled", "created_at" },
Expand Down
26 changes: 26 additions & 0 deletions kong/dao/schemas/apis.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
local url = require "socket.url"
local constants = require "kong.constants"

local function validate_target_url(value)
local parsed_url = url.parse(value)
if parsed_url.scheme and parsed_url.host then
parsed_url.scheme = parsed_url.scheme:lower()
if parsed_url.scheme == "http" or parsed_url.scheme == "https" then
parsed_url.path = parsed_url.path or "/"
return true, nil, { target_url = url.build(parsed_url)}
else
return false, "Supported protocols are HTTP and HTTPS"
end
end

return false, "Invalid target URL"
end

return {
id = { type = constants.DATABASE_TYPES.ID },
name = { type = "string", unique = true, queryable = true, default = function(api_t) return api_t.public_dns end },
public_dns = { type = "string", required = true, unique = true, queryable = true,
regex = "([a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*)" },
target_url = { type = "string", required = true, func = validate_target_url },
created_at = { type = constants.DATABASE_TYPES.TIMESTAMP }
}
17 changes: 17 additions & 0 deletions kong/dao/schemas/consumers.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
local stringy = require "stringy"
local constants = require "kong.constants"

local function check_custom_id_and_username(value, consumer_t)
if (consumer_t.custom_id == nil or stringy.strip(consumer_t.custom_id) == "")
and (consumer_t.username == nil or stringy.strip(consumer_t.username) == "") then
return false, "At least a 'custom_id' or a 'username' must be specified"
end
return true
end

return {
id = { type = constants.DATABASE_TYPES.ID },
custom_id = { type = "string", unique = true, queryable = true, func = check_custom_id_and_username },
username = { type = "string", unique = true, queryable = true, func = check_custom_id_and_username },
created_at = { type = constants.DATABASE_TYPES.TIMESTAMP }
}
23 changes: 23 additions & 0 deletions kong/dao/schemas/plugins_configurations.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
local utils = require "kong.tools.utils"
local constants = require "kong.constants"

local function load_value_schema(plugin_t)
if plugin_t.name then
local loaded, plugin_schema = utils.load_module_if_exists("kong.plugins."..plugin_t.name..".schema")
if loaded then
return plugin_schema
else
return nil, "Plugin \""..(plugin_t.name and plugin_t.name or "").."\" not found"
end
end
end

return {
id = { type = constants.DATABASE_TYPES.ID },
api_id = { type = constants.DATABASE_TYPES.ID, required = true, foreign = true, queryable = true },
consumer_id = { type = constants.DATABASE_TYPES.ID, foreign = true, queryable = true, default = constants.DATABASE_NULL_ID },
name = { type = "string", required = true, queryable = true, immutable = true },
value = { type = "table", schema = load_value_schema },
enabled = { type = "boolean", default = true },
created_at = { type = constants.DATABASE_TYPES.TIMESTAMP }
}
5 changes: 2 additions & 3 deletions kong/dao/schemas.lua → kong/dao/schemas_validation.lua
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ function _M.get_type(type_val)
return alias and alias or type_val
end


-- Validate a table against a given schema
-- @param {table} t Table to validate
-- @param {table} schema Schema against which to validate the table
Expand Down Expand Up @@ -131,8 +130,8 @@ function _M.validate(t, schema, is_update)
errors = utils.add_error(errors, column, column.." is required")
end

-- Check field against a custom function only if the value requirement has been satisfied
if v.func and type(v.func) == "function" and errors == nil then
-- Check field against a custom function only if there is no error on that field already
if v.func and type(v.func) == "function" and (errors == nil or errors[column] == nil) then
local ok, err, new_fields = v.func(t[column], t)
if not ok and err then
errors = utils.add_error(errors, column, err)
Expand Down
52 changes: 0 additions & 52 deletions spec/integration/admin_api/admin_api_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -90,58 +90,6 @@ describe("Admin API", function()

end)

describe("APIs Schema", function()

it("should return error with wrong target_url", function()
local response, status = http_client.post(spec_helper.API_URL.."/apis", {
public_dns = "hello.com",
target_url = "asdasd"
})

assert.are.equal(400, status)
assert.are.equal("Invalid target URL", cjson.decode(response).target_url)
end)

it("should return error with wrong target_url protocol", function()
local response, status = http_client.post(spec_helper.API_URL.."/apis", {
public_dns = "hello.com",
target_url = "wot://hello.com/"
})

assert.are.equal(400, status)
assert.are.equal("Supported protocols are HTTP and HTTPS", cjson.decode(response).target_url)
end)

it("should work without a path", function()
local response, status = http_client.post(spec_helper.API_URL.."/apis", {
public_dns = "hello.com",
target_url = "http://hello.com"
})

local body = cjson.decode(response)
assert.are.equal(201, status)
assert.are.equal("http://hello.com/", body.target_url)

-- Clean up
http_client.delete(spec_helper.API_URL.."/apis/"..body.id)
end)

it("should work without upper case protocol", function()
local response, status = http_client.post(spec_helper.API_URL.."/apis", {
public_dns = "hello2.com",
target_url = "HTTP://hello.com/world"
})

local body = cjson.decode(response)
assert.are.equal(201, status)
assert.are.equal("http://hello.com/world", cjson.decode(response).target_url)

-- Clean up
http_client.delete(spec_helper.API_URL.."/apis/"..body.id)
end)

end)

describe("POST", function()
describe("application/x-www-form-urlencoded", function()
test_for_each_endpoint(function(endpoint, base_url)
Expand Down
2 changes: 1 addition & 1 deletion spec/unit/dao/cassandra_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ describe("Cassandra DAO", function()
assert.truthy(err)
assert.is_daoError(err)
assert.True(err.unique)
assert.are.same("Plugin already exists", err.message)
assert.are.same("Plugin configuration already exists", err.message)
end)

it("should not insert a plugin if this plugin doesn't exist (not installed)", function()
Expand Down
46 changes: 46 additions & 0 deletions spec/unit/dao/entities_schemas_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
local validate = require("kong.dao.schemas_validation").validate
local api_schema = require "kong.dao.schemas.apis"

require "kong.tools.ngx_stub"

describe("Entities Schemas", function()
describe("APIs", function()

it("should return error with wrong target_url", function()
local valid, errors = validate({
public_dns = "hello.com",
target_url = "asdasd"
}, api_schema)
assert.False(valid)
assert.same("Invalid target URL", errors.target_url)
end)

it("should return error with wrong target_url protocol", function()
local valid, errors = validate({
public_dns = "hello.com",
target_url = "wot://hello.com/"
}, api_schema)
assert.False(valid)
assert.same("Supported protocols are HTTP and HTTPS", errors.target_url)
end)

it("should work without a path", function()
local valid, errors = validate({
public_dns = "hello.com",
target_url = "http://hello.com"
}, api_schema)
assert.True(valid)
assert.falsy(errors)
end)

it("should work without upper case protocol", function()
local valid, errors = validate({
public_dns = "hello2.com",
target_url = "HTTP://hello.com/world"
}, api_schema)
assert.True(valid)
assert.falsy(errors)
end)

end)
end)
2 changes: 1 addition & 1 deletion spec/unit/schemas_spec.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
local schemas = require "kong.dao.schemas"
local schemas = require "kong.dao.schemas_validation"
local constants = require "kong.constants"
local validate = schemas.validate

Expand Down

0 comments on commit dc8cbdd

Please sign in to comment.