Page MenuHomePhabricator (Chris)

migrations_spec.lua
No OneTemporary

Authored By
Unknown
Size
10 KB
Referenced Files
None
Subscribers
None

migrations_spec.lua

--[[
Tests for database migrations.
Validates that migration SQL is well-formed by checking that each migration:
- Has an up() function
- Returns non-empty SQL
- Contains expected table/index creation statements
- Has valid SQL syntax (basic structural checks)
]]
describe('db.migrations', function()
describe('001_initial_schema', function()
local migration
before_each(function()
package.loaded['src.db.migrations.001_initial_schema'] = nil
migration = require('src.db.migrations.001_initial_schema')
end)
it('should have an up() function', function()
assert.are.equal('function', type(migration.up))
end)
it('should return non-empty SQL', function()
local sql = migration.up()
assert.is_truthy(sql)
assert.is_true(#sql > 0)
end)
it('should create users table', function()
local sql = migration.up()
assert.is_truthy(sql:match('CREATE TABLE IF NOT EXISTS users'))
end)
it('should create chats table', function()
local sql = migration.up()
assert.is_truthy(sql:match('CREATE TABLE IF NOT EXISTS chats'))
end)
it('should create chat_settings table', function()
local sql = migration.up()
assert.is_truthy(sql:match('CREATE TABLE IF NOT EXISTS chat_settings'))
end)
it('should create chat_members table', function()
local sql = migration.up()
assert.is_truthy(sql:match('CREATE TABLE IF NOT EXISTS chat_members'))
end)
it('should create bans table', function()
local sql = migration.up()
assert.is_truthy(sql:match('CREATE TABLE IF NOT EXISTS bans'))
end)
it('should create warnings table', function()
local sql = migration.up()
assert.is_truthy(sql:match('CREATE TABLE IF NOT EXISTS warnings'))
end)
it('should create filters table', function()
local sql = migration.up()
assert.is_truthy(sql:match('CREATE TABLE IF NOT EXISTS filters'))
end)
it('should create rules table', function()
local sql = migration.up()
assert.is_truthy(sql:match('CREATE TABLE IF NOT EXISTS rules'))
end)
it('should create welcome_messages table', function()
local sql = migration.up()
assert.is_truthy(sql:match('CREATE TABLE IF NOT EXISTS welcome_messages'))
end)
it('should create saved_notes table', function()
local sql = migration.up()
assert.is_truthy(sql:match('CREATE TABLE IF NOT EXISTS saved_notes'))
end)
it('should create admin_actions table', function()
local sql = migration.up()
assert.is_truthy(sql:match('CREATE TABLE IF NOT EXISTS admin_actions'))
end)
it('should create disabled_plugins table', function()
local sql = migration.up()
assert.is_truthy(sql:match('CREATE TABLE IF NOT EXISTS disabled_plugins'))
end)
it('should create triggers table', function()
local sql = migration.up()
assert.is_truthy(sql:match('CREATE TABLE IF NOT EXISTS triggers'))
end)
it('should create aliases table', function()
local sql = migration.up()
assert.is_truthy(sql:match('CREATE TABLE IF NOT EXISTS aliases'))
end)
it('should create user_locations table', function()
local sql = migration.up()
assert.is_truthy(sql:match('CREATE TABLE IF NOT EXISTS user_locations'))
end)
it('should create custom_commands table', function()
local sql = migration.up()
assert.is_truthy(sql:match('CREATE TABLE IF NOT EXISTS custom_commands'))
end)
it('should create indexes', function()
local sql = migration.up()
assert.is_truthy(sql:match('CREATE INDEX'))
end)
it('should have PRIMARY KEY on users.user_id', function()
local sql = migration.up()
assert.is_truthy(sql:match('user_id BIGINT PRIMARY KEY'))
end)
it('should have balanced parentheses', function()
local sql = migration.up()
local open = 0
for _ in sql:gmatch('%(') do open = open + 1 end
local close = 0
for _ in sql:gmatch('%)') do close = close + 1 end
assert.are.equal(open, close)
end)
it('should contain no stray control characters', function()
local sql = migration.up()
-- Only allow printable ASCII plus whitespace
local cleaned = sql:gsub('[%w%p%s]', '')
assert.are.equal(0, #cleaned)
end)
end)
describe('002_federation_tables', function()
local migration
before_each(function()
package.loaded['src.db.migrations.002_federation_tables'] = nil
migration = require('src.db.migrations.002_federation_tables')
end)
it('should have an up() function', function()
assert.are.equal('function', type(migration.up))
end)
it('should create federations table', function()
local sql = migration.up()
assert.is_truthy(sql:match('CREATE TABLE IF NOT EXISTS federations'))
end)
it('should create federation_admins table', function()
local sql = migration.up()
assert.is_truthy(sql:match('CREATE TABLE IF NOT EXISTS federation_admins'))
end)
it('should create federation_bans table', function()
local sql = migration.up()
assert.is_truthy(sql:match('CREATE TABLE IF NOT EXISTS federation_bans'))
end)
it('should create federation_chats table', function()
local sql = migration.up()
assert.is_truthy(sql:match('CREATE TABLE IF NOT EXISTS federation_chats'))
end)
it('should create federation_allowlist table', function()
local sql = migration.up()
assert.is_truthy(sql:match('CREATE TABLE IF NOT EXISTS federation_allowlist'))
end)
it('should use UUID for federation ID', function()
local sql = migration.up()
assert.is_truthy(sql:match('UUID'))
end)
it('should have CASCADE delete on foreign keys', function()
local sql = migration.up()
assert.is_truthy(sql:match('ON DELETE CASCADE'))
end)
it('should have indexes on frequently queried columns', function()
local sql = migration.up()
assert.is_truthy(sql:match('idx_federation_bans_user'))
assert.is_truthy(sql:match('idx_federation_chats_chat'))
end)
it('should have balanced parentheses', function()
local sql = migration.up()
local open = 0
for _ in sql:gmatch('%(') do open = open + 1 end
local close = 0
for _ in sql:gmatch('%)') do close = close + 1 end
assert.are.equal(open, close)
end)
end)
describe('003_statistics_tables', function()
local migration
before_each(function()
package.loaded['src.db.migrations.003_statistics_tables'] = nil
migration = require('src.db.migrations.003_statistics_tables')
end)
it('should have an up() function', function()
assert.are.equal('function', type(migration.up))
end)
it('should create message_stats table', function()
local sql = migration.up()
assert.is_truthy(sql:match('CREATE TABLE IF NOT EXISTS message_stats'))
end)
it('should create command_stats table', function()
local sql = migration.up()
assert.is_truthy(sql:match('CREATE TABLE IF NOT EXISTS command_stats'))
end)
it('should have composite primary key for message_stats', function()
local sql = migration.up()
assert.is_truthy(sql:match('PRIMARY KEY %(chat_id, user_id, date%)'))
end)
it('should have composite primary key for command_stats', function()
local sql = migration.up()
assert.is_truthy(sql:match('PRIMARY KEY %(chat_id, command, date%)'))
end)
it('should have date indexes', function()
local sql = migration.up()
assert.is_truthy(sql:match('idx_message_stats_date'))
assert.is_truthy(sql:match('idx_command_stats_date'))
end)
end)
describe('004_performance_indexes', function()
local migration
before_each(function()
package.loaded['src.db.migrations.004_performance_indexes'] = nil
migration = require('src.db.migrations.004_performance_indexes')
end)
it('should have an up() function', function()
assert.are.equal('function', type(migration.up))
end)
it('should be idempotent (IF NOT EXISTS)', function()
local sql = migration.up()
for stmt in sql:gmatch('[^;]+') do
stmt = stmt:match('^%s*(.-)%s*$')
if stmt ~= '' then
assert.is_truthy(stmt:match('IF NOT EXISTS'),
'Statement missing IF NOT EXISTS: ' .. stmt:sub(1, 80))
end
end
end)
it('should create federation and stats indexes', function()
local sql = migration.up()
assert.is_truthy(sql:match('idx_federation_bans_user'))
assert.is_truthy(sql:match('idx_federation_chats_chat'))
assert.is_truthy(sql:match('idx_msg_stats_chat_date'))
end)
it('should create chat_settings index', function()
local sql = migration.up()
assert.is_truthy(sql:match('idx_chat_settings_chat'))
end)
it('should create disabled_plugins index', function()
local sql = migration.up()
assert.is_truthy(sql:match('idx_disabled_plugins_chat'))
end)
end)
describe('migration runner', function()
local init_mod
before_each(function()
package.loaded['src.db.init'] = nil
package.loaded['src.core.logger'] = {
debug = function() end, info = function() end,
warn = function() end, error = function() end,
}
init_mod = require('src.db.init')
end)
it('should have a run function', function()
assert.are.equal('function', type(init_mod.run))
end)
it('should reference all 4 migrations in order', function()
-- The run function references migration_files internally
-- We verify the module loads without error which implies
-- the file list is valid
assert.is_not_nil(init_mod)
end)
end)
end)

File Metadata

Mime Type
application/javascript
Expires
Sat, Nov 14, 5:31 PM (12 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
113029
Default Alt Text
migrations_spec.lua (10 KB)

Event Timeline