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()