Moonshark/tests/sessions.lua

398 lines
11 KiB
Lua

require("tests")
local sessions = require("sessions")
-- Clean up test files
os.remove("test_sessions.json")
os.remove("test_sessions2.json")
-- ======================================================================
-- SESSION STORE INITIALIZATION
-- ======================================================================
test("Session store initialization", function()
assert(sessions.init("test_sessions", "test_sessions.json"))
assert(sessions.init("memory_sessions"))
-- Test with explicit store name
assert(sessions.init("named_sessions", "test_sessions2.json"))
end)
test("Session ID generation", function()
local id1 = sessions.generate_id()
local id2 = sessions.generate_id()
assert_equal(32, #id1)
assert_equal(32, #id2)
assert(id1 ~= id2, "Session IDs should be unique")
-- Check character set (alphanumeric)
assert(id1:match("^[a-zA-Z0-9]+$"), "Session ID should be alphanumeric")
end)
-- ======================================================================
-- BASIC SESSION OPERATIONS
-- ======================================================================
test("Session creation and retrieval", function()
sessions.init("basic_test")
local session_id = sessions.generate_id()
local session_data = {
user_id = 123,
username = "testuser",
role = "admin",
permissions = {"read", "write"}
}
assert(sessions.create(session_id, session_data))
local retrieved = sessions.get(session_id)
assert_equal(123, retrieved.user_id)
assert_equal("testuser", retrieved.username)
assert_equal("admin", retrieved.role)
assert_table_equal({"read", "write"}, retrieved.permissions)
assert(retrieved._created ~= nil)
assert(retrieved._last_accessed ~= nil)
-- Test non-existent session
assert_equal(nil, sessions.get("nonexistent"))
end)
test("Session updates", function()
sessions.init("update_test")
local session_id = sessions.generate_id()
sessions.create(session_id, {count = 1})
local session = sessions.get(session_id)
local new_data = {
count = 2,
new_field = "added"
}
assert(sessions.update(session_id, new_data))
local updated = sessions.get(session_id)
assert_equal(2, updated.count)
assert_equal("added", updated.new_field)
assert(updated._created ~= nil)
assert(updated._last_accessed ~= nil)
end)
test("Session deletion", function()
sessions.init("delete_test")
local session_id = sessions.generate_id()
sessions.create(session_id, {temp = true})
assert(sessions.get(session_id) ~= nil)
assert(sessions.delete(session_id))
assert_equal(nil, sessions.get(session_id))
-- Delete non-existent session
assert(not sessions.delete("nonexistent"))
end)
test("Session existence check", function()
sessions.init("exists_test")
local session_id = sessions.generate_id()
assert(not sessions.exists(session_id))
sessions.create(session_id, {test = true})
assert(sessions.exists(session_id))
sessions.delete(session_id)
assert(not sessions.exists(session_id))
end)
-- ======================================================================
-- MULTI-STORE OPERATIONS
-- ======================================================================
test("Multiple session stores", function()
assert(sessions.init("store1", "store1.json"))
assert(sessions.init("store2", "store2.json"))
local id1 = sessions.generate_id()
local id2 = sessions.generate_id()
-- Create sessions in different stores
assert(sessions.create(id1, {store = "store1"}, "store1"))
assert(sessions.create(id2, {store = "store2"}, "store2"))
-- Verify isolation
assert_equal(nil, sessions.get(id1, "store2"))
assert_equal(nil, sessions.get(id2, "store1"))
-- Verify correct retrieval
local s1 = sessions.get(id1, "store1")
local s2 = sessions.get(id2, "store2")
assert_equal("store1", s1.store)
assert_equal("store2", s2.store)
os.remove("store1.json")
os.remove("store2.json")
end)
test("Default store behavior", function()
sessions.reset()
sessions.init("default_store")
local session_id = sessions.generate_id()
sessions.create(session_id, {test = "default"})
-- Should work without specifying store
local retrieved = sessions.get(session_id)
assert_equal("default", retrieved.test)
end)
-- ======================================================================
-- SESSION CLEANUP
-- ======================================================================
test("Session cleanup", function()
sessions.init("cleanup_test")
local old_session = sessions.generate_id()
local new_session = sessions.generate_id()
sessions.create(old_session, {test = "old"}, "cleanup_test")
sessions.create(new_session, {test = "new"}, "cleanup_test")
-- Wait to create age difference
os.execute("sleep 2")
-- Access new session to update timestamp
sessions.get(new_session, "cleanup_test")
-- Clean up sessions older than 1 second
local deleted = sessions.cleanup(1, "cleanup_test")
assert(deleted >= 1)
-- New session should remain (recently accessed)
assert(sessions.get(new_session, "cleanup_test") ~= nil)
end)
-- ======================================================================
-- SESSION LISTING AND COUNTING
-- ======================================================================
test("Session listing and counting", function()
sessions.init("list_test")
local ids = {}
for i = 1, 5 do
local id = sessions.generate_id()
sessions.create(id, {index = i}, "list_test")
table.insert(ids, id)
end
local session_list = sessions.list("list_test")
assert_equal(5, #session_list)
local count = sessions.count("list_test")
assert_equal(5, count)
-- Verify all IDs are in the list
local id_set = {}
for _, id in ipairs(session_list) do
id_set[id] = true
end
for _, id in ipairs(ids) do
assert(id_set[id], "Session ID should be in list")
end
end)
-- ======================================================================
-- OBJECT-ORIENTED INTERFACE
-- ======================================================================
test("OOP session store", function()
local store = sessions.create_store("oop_sessions", "oop_test.json")
local session_id = sessions.generate_id()
local data = {user = "oop_test", role = "admin"}
assert(store:create(session_id, data))
local retrieved = store:get(session_id)
assert_equal("oop_test", retrieved.user)
assert_equal("admin", retrieved.role)
retrieved.last_action = "login"
assert(store:update(session_id, retrieved))
local updated = store:get(session_id)
assert_equal("login", updated.last_action)
assert(store:exists(session_id))
assert_equal(1, store:count())
local session_list = store:list()
assert_equal(1, #session_list)
assert_equal(session_id, session_list[1])
assert(store:delete(session_id))
assert(not store:exists(session_id))
store:close()
os.remove("oop_test.json")
end)
-- ======================================================================
-- ERROR HANDLING
-- ======================================================================
test("Session error handling", function()
sessions.reset()
-- Try operations without initialization
local success1, err1 = pcall(sessions.create, "test_id", {})
assert(not success1)
local success2, err2 = pcall(sessions.get, "test_id")
assert(not success2)
-- Initialize and test invalid inputs
sessions.init("error_test")
-- Invalid session ID type
local success3, err3 = pcall(sessions.create, 123, {})
assert(not success3)
-- Invalid data type
local success4, err4 = pcall(sessions.create, "test", "not_a_table")
assert(not success4)
-- Invalid store name
local success5, err5 = pcall(sessions.get, "test", 123)
assert(not success5)
end)
-- ======================================================================
-- DATA PERSISTENCE
-- ======================================================================
test("Session persistence", function()
sessions.init("persist_test", "persist_sessions.json")
local session_id = sessions.generate_id()
local data = {
user_id = 789,
settings = {theme = "dark", lang = "en"},
cart = {items = {"item1", "item2"}, total = 25.99}
}
sessions.create(session_id, data, "persist_test")
sessions.close("persist_test")
-- Reinitialize and verify data persists
sessions.init("persist_test", "persist_sessions.json")
local retrieved = sessions.get(session_id, "persist_test")
assert_equal(789, retrieved.user_id)
assert_equal("dark", retrieved.settings.theme)
assert_equal("en", retrieved.settings.lang)
assert_equal(2, #retrieved.cart.items)
assert_equal(25.99, retrieved.cart.total)
sessions.close("persist_test")
os.remove("persist_sessions.json")
end)
-- ======================================================================
-- COMPLEX DATA STRUCTURES
-- ======================================================================
test("Complex session data", function()
sessions.init("complex_test")
local session_id = sessions.generate_id()
local complex_data = {
user = {
id = 456,
profile = {
name = "Jane Doe",
email = "jane@example.com",
preferences = {
notifications = true,
privacy = "friends_only"
}
}
},
activity = {
pages_visited = {"home", "profile", "settings"},
actions = {
{type = "login", time = os.time()},
{type = "view_page", page = "profile", time = os.time()}
}
},
metadata = {
ip = "192.168.1.1",
user_agent = "Test Browser 1.0"
}
}
sessions.create(session_id, complex_data)
local retrieved = sessions.get(session_id)
assert_equal(456, retrieved.user.id)
assert_equal("Jane Doe", retrieved.user.profile.name)
assert_equal(true, retrieved.user.profile.preferences.notifications)
assert_equal(3, #retrieved.activity.pages_visited)
assert_equal("login", retrieved.activity.actions[1].type)
assert_equal("192.168.1.1", retrieved.metadata.ip)
end)
-- ======================================================================
-- WORKFLOW INTEGRATION
-- ======================================================================
test("Session workflow integration", function()
sessions.init("workflow_test")
-- Simulate user workflow
local session_id = sessions.generate_id()
-- User login
sessions.create(session_id, {
user_id = 999,
username = "workflow_user",
status = "logged_in"
})
-- User adds items to cart
local session = sessions.get(session_id)
session.cart = {"item1", "item2"}
session.cart_total = 19.99
sessions.update(session_id, session)
-- User proceeds to checkout
session = sessions.get(session_id)
session.checkout_step = "payment"
session.payment_method = "credit_card"
sessions.update(session_id, session)
-- Verify final state
local final_session = sessions.get(session_id)
assert_equal(999, final_session.user_id)
assert_equal("logged_in", final_session.status)
assert_equal(2, #final_session.cart)
assert_equal(19.99, final_session.cart_total)
assert_equal("payment", final_session.checkout_step)
assert_equal("credit_card", final_session.payment_method)
-- User completes order and logs out
sessions.delete(session_id)
assert_equal(nil, sessions.get(session_id))
end)
-- Clean up test files
os.remove("test_sessions.json")
os.remove("test_sessions2.json")
summary()
test_exit()