mirror of
https://github.com/cliffe/BreakEscape.git
synced 2026-02-20 13:50:46 +00:00
Add comprehensive unlock system tests
Created test suite with 34 tests covering all unlock scenarios and security: DOOR TESTS (10 tests): - PIN/password validation (correct/incorrect, case sensitivity) - Key unlocks (client-validated) - Unlocked doors (method='unlocked') CONTAINER TESTS (8 tests): - PIN/password validation - Key, lockpick, biometric, bluetooth, RFID unlocks - Unlocked containers NPC UNLOCK TESTS (6 tests): ✅ NPC can unlock door/container if encountered and has permission 🔒 SECURITY: Fails if NPC not encountered 🔒 SECURITY: Fails if NPC lacks permission for that target 🔒 SECURITY: Fails for non-existent NPC 🔒 SECURITY: Fails if unlockable is not an array SECURITY TESTS - BYPASS PREVENTION (4 tests): 🔒 CRITICAL: Locked door CANNOT be bypassed with method='unlocked' 🔒 CRITICAL: Locked container CANNOT be bypassed with method='unlocked' ✅ Unlocked door CAN use method='unlocked' ✅ Unlocked container CAN use method='unlocked' ERROR CASES (3 tests): - Non-existent doors/objects return 422 - Invalid methods return 422 DATA FILTERING (2 tests): - Verify 'requires' field filtered from responses - Verify recursive filtering of contents INTEGRATION (1 test): - Multiple sequential unlocks - Idempotent operations Test Results: 34 runs, 115 assertions, 0 failures Server Implementation: - validate_npc_unlock: Validates NPC encounter and permission list - find_npc_in_scenario: Searches all rooms for NPC - method='npc': New unlock method requiring NPC id as attempt Client Implementation: - Updated handleUnlockDoor to call server API with method='npc' - Server validates all NPC unlock requests - No client-side lock manipulation Security Principle: All unlock authorization is server-side. Client cannot bypass locks by manipulating state or claiming NPC unlocks.
This commit is contained in:
@@ -159,6 +159,12 @@ module BreakEscape
|
||||
return false
|
||||
end
|
||||
|
||||
# NPC unlock: Validate NPC has been encountered and has permission to unlock this door
|
||||
if method == 'npc'
|
||||
npc_id = attempt # NPC id is passed as 'attempt'
|
||||
return validate_npc_unlock(npc_id, target_id)
|
||||
end
|
||||
|
||||
case method
|
||||
when 'key', 'lockpick', 'biometric', 'bluetooth', 'rfid'
|
||||
# Client validated the unlock - trust it
|
||||
@@ -193,6 +199,12 @@ module BreakEscape
|
||||
return false
|
||||
end
|
||||
|
||||
# NPC unlock: Validate NPC has been encountered and has permission to unlock this object
|
||||
if method == 'npc'
|
||||
npc_id = attempt # NPC id is passed as 'attempt'
|
||||
return validate_npc_unlock(npc_id, target_id)
|
||||
end
|
||||
|
||||
case method
|
||||
when 'key', 'lockpick', 'biometric', 'bluetooth', 'rfid'
|
||||
# Client validated the unlock - trust it
|
||||
@@ -209,6 +221,44 @@ module BreakEscape
|
||||
end
|
||||
end
|
||||
|
||||
# Validate NPC unlock permission
|
||||
def validate_npc_unlock(npc_id, target_id)
|
||||
Rails.logger.info "[BreakEscape] Validating NPC unlock: npc=#{npc_id}, target=#{target_id}"
|
||||
|
||||
# Find NPC in scenario data
|
||||
npc = find_npc_in_scenario(npc_id)
|
||||
unless npc
|
||||
Rails.logger.warn "[BreakEscape] NPC not found: #{npc_id}"
|
||||
return false
|
||||
end
|
||||
|
||||
# Check if player has encountered this NPC
|
||||
unless player_state['encounteredNPCs']&.include?(npc_id)
|
||||
Rails.logger.warn "[BreakEscape] Player has not encountered NPC: #{npc_id}"
|
||||
return false
|
||||
end
|
||||
|
||||
# Check if NPC has permission to unlock this target
|
||||
unlockable = npc['unlockable']
|
||||
unless unlockable.is_a?(Array) && unlockable.include?(target_id)
|
||||
Rails.logger.warn "[BreakEscape] NPC #{npc_id} does not have permission to unlock #{target_id}"
|
||||
return false
|
||||
end
|
||||
|
||||
Rails.logger.info "[BreakEscape] NPC unlock validated: #{npc_id} can unlock #{target_id}"
|
||||
true
|
||||
end
|
||||
|
||||
# Find NPC in scenario data
|
||||
def find_npc_in_scenario(npc_id)
|
||||
scenario_data['rooms']&.each do |_room_id, room_data|
|
||||
room_data['npcs']&.each do |npc|
|
||||
return npc if npc['id'] == npc_id
|
||||
end
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def filter_requires_and_contents_recursive(obj)
|
||||
|
||||
@@ -442,19 +442,58 @@ export default class PersonChatConversation {
|
||||
* Handle unlock_door tag
|
||||
* @param {string} doorId - Door to unlock
|
||||
*/
|
||||
handleUnlockDoor(doorId) {
|
||||
async handleUnlockDoor(doorId) {
|
||||
if (!doorId) return;
|
||||
|
||||
console.log(`🔓 Unlocking door: ${doorId}`);
|
||||
|
||||
// Dispatch event for interactions system to handle
|
||||
const event = new CustomEvent('ink-action', {
|
||||
detail: {
|
||||
action: 'unlock_door',
|
||||
doorId: doorId
|
||||
|
||||
console.log(`🔓 NPC unlocking door: ${doorId}`);
|
||||
|
||||
// SECURITY: Call server API with NPC unlock method
|
||||
// Server will validate NPC has been encountered and has permission
|
||||
const apiClient = window.ApiClient || window.APIClient;
|
||||
const gameId = window.breakEscapeConfig?.gameId;
|
||||
|
||||
if (!apiClient || !gameId) {
|
||||
console.error('ApiClient or gameId not available for NPC unlock');
|
||||
window.gameAlert('Failed to unlock door', 'error', 'Error', 3000);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await apiClient.unlock('door', doorId, this.npc.id, 'npc');
|
||||
|
||||
if (response.success) {
|
||||
console.log(`✅ NPC ${this.npc.id} successfully unlocked door ${doorId}`);
|
||||
window.gameAlert(`Door unlocked!`, 'success', 'Access Granted', 3000);
|
||||
|
||||
// Trigger door unlock visual update if door sprite exists
|
||||
const doorSprite = this.findDoorSprite(doorId);
|
||||
if (doorSprite && window.unlockDoor) {
|
||||
window.unlockDoor(doorSprite, response.roomData);
|
||||
}
|
||||
} else {
|
||||
console.error('NPC unlock failed:', response);
|
||||
window.gameAlert('Failed to unlock door', 'error', 'Error', 3000);
|
||||
}
|
||||
});
|
||||
window.dispatchEvent(event);
|
||||
} catch (error) {
|
||||
console.error('NPC unlock error:', error);
|
||||
window.gameAlert('Failed to unlock door', 'error', 'Error', 3000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find door sprite by room ID
|
||||
* @param {string} roomId - Room ID to find door for
|
||||
*/
|
||||
findDoorSprite(roomId) {
|
||||
// Search through all door sprites in the game
|
||||
if (!window.game || !window.game.children) return null;
|
||||
|
||||
const doors = window.game.children.list.filter(child =>
|
||||
child.doorProperties &&
|
||||
child.doorProperties.connectedRoom === roomId
|
||||
);
|
||||
|
||||
return doors.length > 0 ? doors[0] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -21060,3 +21060,989 @@ Processing by BreakEscape::GamesController#unlock as HTML
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Completed 200 OK in 4ms (Views: 0.1ms | ActiveRecord: 0.6ms (5 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mActiveRecord::InternalMetadata Load (0.4ms)[0m [1m[34mSELECT * FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = ? ORDER BY "ar_internal_metadata"."key" ASC LIMIT 1[0m [[nil, "schema_sha1"]]
|
||||
[1m[36mActiveRecord::SchemaMigration Load (0.2ms)[0m [1m[34mSELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC[0m
|
||||
[1m[36mTRANSACTION (0.3ms)[0m [1m[36mbegin transaction[0m
|
||||
[1m[35m (0.6ms)[0m [1m[35mPRAGMA foreign_keys[0m
|
||||
[1m[35m (0.0ms)[0m [1m[35mPRAGMA defer_foreign_keys[0m
|
||||
[1m[35m (0.1ms)[0m [1m[35mPRAGMA defer_foreign_keys = ON[0m
|
||||
[1m[35m (0.0ms)[0m [1m[35mPRAGMA foreign_keys = OFF[0m
|
||||
[1m[36mFixtures Load (0.2ms)[0m [1m[31mDELETE FROM "break_escape_demo_users";
|
||||
DELETE FROM "break_escape_missions";
|
||||
INSERT INTO "break_escape_demo_users" ("id", "handle", "created_at", "updated_at") VALUES (149617800, 'test_user', '2025-11-21 23:40:56', '2025-11-21 23:40:56');
|
||||
INSERT INTO "break_escape_demo_users" ("id", "handle", "created_at", "updated_at") VALUES (618102942, 'other_user', '2025-11-21 23:40:56', '2025-11-21 23:40:56');
|
||||
INSERT INTO "break_escape_missions" ("id", "name", "display_name", "description", "published", "difficulty_level", "created_at", "updated_at") VALUES (418560898, 'ceo_exfil', 'CEO Exfiltration', 'Test scenario', 1, 3, '2025-11-21 23:40:56', '2025-11-21 23:40:56');
|
||||
INSERT INTO "break_escape_missions" ("id", "name", "display_name", "description", "published", "difficulty_level", "created_at", "updated_at") VALUES (636030761, 'test_unpublished', 'Unpublished Test', 'Not visible', 0, 1, '2025-11-21 23:40:56', '2025-11-21 23:40:56')[0m
|
||||
[1m[35m (0.0ms)[0m [1m[35mPRAGMA defer_foreign_keys = 0[0m
|
||||
[1m[35m (0.0ms)[0m [1m[35mPRAGMA foreign_keys = 1[0m
|
||||
[1m[36mTRANSACTION (7.1ms)[0m [1m[36mcommit transaction[0m
|
||||
[1m[35m (0.1ms)[0m [1m[35mPRAGMA foreign_key_check[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
--------------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_SECURITY:_NPC_unlock_fails_if_unlockable_is_not_an_array
|
||||
--------------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.2ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.2ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.7ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:40:56.331119"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:40:56.330405"], ["updated_at", "2025-11-21 23:40:56.330405"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Update (0.3ms)[0m [1m[33mUPDATE "break_escape_games" SET "scenario_data" = ?, "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}],\"npcs\":[{\"id\":\"helper_npc\",\"displayName\":\"Helpful Contact\",\"unlockable\":\"office_pin\"}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[\"helper_npc\"],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:40:56.334523"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:40:56 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"door", "targetId"=>"office_pin", "attempt"=>"helper_npc", "method"=>"npc", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.2ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=door, id=office_pin, attempt=helper_npc, method=npc
|
||||
[BreakEscape] Validating NPC unlock: npc=helper_npc, target=office_pin
|
||||
[BreakEscape] NPC helper_npc does not have permission to unlock office_pin
|
||||
Completed 422 Unprocessable Content in 33ms (Views: 0.4ms | ActiveRecord: 0.4ms (3 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
------------------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_SECURITY:_NPC_unlock_fails_if_player_has_not_encountered_NPC
|
||||
------------------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.2ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.5ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:40:56.467243"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:40:56.467011"], ["updated_at", "2025-11-21 23:40:56.467011"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Update (0.2ms)[0m [1m[33mUPDATE "break_escape_games" SET "scenario_data" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}],\"npcs\":[{\"id\":\"helper_npc\",\"displayName\":\"Helpful Contact\",\"unlockable\":[\"office_pin\"]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["updated_at", "2025-11-21 23:40:56.469132"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:40:56 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"door", "targetId"=>"office_pin", "attempt"=>"helper_npc", "method"=>"npc", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.2ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=door, id=office_pin, attempt=helper_npc, method=npc
|
||||
[BreakEscape] Validating NPC unlock: npc=helper_npc, target=office_pin
|
||||
[BreakEscape] Player has not encountered NPC: helper_npc
|
||||
Completed 422 Unprocessable Content in 2ms (Views: 0.1ms | ActiveRecord: 0.3ms (3 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_NPC_can_unlock_door_if_player_has_encountered_them_and_NPC_has_permission
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.3ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:40:56.477393"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:40:56.477211"], ["updated_at", "2025-11-21 23:40:56.477211"]]
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Update (0.2ms)[0m [1m[33mUPDATE "break_escape_games" SET "scenario_data" = ?, "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}],\"npcs\":[{\"id\":\"helper_npc\",\"displayName\":\"Helpful Contact\",\"unlockable\":[\"office_pin\",\"office_password\"]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[\"helper_npc\"],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:40:56.478824"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:40:56 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"door", "targetId"=>"office_pin", "attempt"=>"helper_npc", "method"=>"npc", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=door, id=office_pin, attempt=helper_npc, method=npc
|
||||
[BreakEscape] Validating NPC unlock: npc=helper_npc, target=office_pin
|
||||
[BreakEscape] NPC unlock validated: helper_npc can unlock office_pin
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Mission Load (0.3ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::Game Update (0.1ms)[0m [1m[33mUPDATE "break_escape_games" SET "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\",\"office_pin\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[\"helper_npc\"],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:40:56.484470"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Completed 200 OK in 5ms (Views: 0.1ms | ActiveRecord: 0.7ms (5 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[36mbegin transaction[0m
|
||||
-----------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_SECURITY:_NPC_unlock_fails_for_non-existent_NPC
|
||||
-----------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.4ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:40:56.489275"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:40:56.489092"], ["updated_at", "2025-11-21 23:40:56.489092"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Update (0.3ms)[0m [1m[33mUPDATE "break_escape_games" SET "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[\"helper_npc\"],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:40:56.490777"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:40:56 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"door", "targetId"=>"office_pin", "attempt"=>"fake_npc", "method"=>"npc", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=door, id=office_pin, attempt=fake_npc, method=npc
|
||||
[BreakEscape] Validating NPC unlock: npc=fake_npc, target=office_pin
|
||||
[BreakEscape] NPC not found: fake_npc
|
||||
Completed 422 Unprocessable Content in 2ms (Views: 0.1ms | ActiveRecord: 0.2ms (3 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_SECURITY:_NPC_unlock_fails_if_NPC_doesn't_have_permission_for_that_door
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.4ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:40:56.497351"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:40:56.497172"], ["updated_at", "2025-11-21 23:40:56.497172"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Update (0.2ms)[0m [1m[33mUPDATE "break_escape_games" SET "scenario_data" = ?, "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}],\"npcs\":[{\"id\":\"helper_npc\",\"displayName\":\"Helpful Contact\",\"unlockable\":[\"office_password\"]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[\"helper_npc\"],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:40:56.498946"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:40:56 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"door", "targetId"=>"office_pin", "attempt"=>"helper_npc", "method"=>"npc", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=door, id=office_pin, attempt=helper_npc, method=npc
|
||||
[BreakEscape] Validating NPC unlock: npc=helper_npc, target=office_pin
|
||||
[BreakEscape] NPC helper_npc does not have permission to unlock office_pin
|
||||
Completed 422 Unprocessable Content in 2ms (Views: 0.1ms | ActiveRecord: 0.2ms (3 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
------------------------------------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_NPC_can_unlock_container_if_player_has_encountered_them_and_NPC_has_permission
|
||||
------------------------------------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.4ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:40:56.506227"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:40:56.506047"], ["updated_at", "2025-11-21 23:40:56.506047"]]
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Update (0.3ms)[0m [1m[33mUPDATE "break_escape_games" SET "scenario_data" = ?, "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}],\"npcs\":[{\"id\":\"helper_npc\",\"displayName\":\"Helpful Contact\",\"unlockable\":[\"safe_pin\",\"cabinet_password\"]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[\"helper_npc\"],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:40:56.508108"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:40:56 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"object", "targetId"=>"safe_pin", "attempt"=>"helper_npc", "method"=>"npc", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=object, id=safe_pin, attempt=helper_npc, method=npc
|
||||
[BreakEscape] Found object: id=safe_pin, name=PIN Safe, locked=true, requires=1234
|
||||
[BreakEscape] Validating NPC unlock: npc=helper_npc, target=safe_pin
|
||||
[BreakEscape] NPC unlock validated: helper_npc can unlock safe_pin
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Mission Load (0.3ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::Game Update (0.1ms)[0m [1m[33mUPDATE "break_escape_games" SET "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[\"safe_pin\"],\"inventory\":[],\"encounteredNPCs\":[\"helper_npc\"],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:40:56.524379"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Completed 200 OK in 15ms (Views: 0.1ms | ActiveRecord: 0.7ms (5 queries, 0 cached) | GC: 10.0ms)
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mActiveRecord::InternalMetadata Load (0.4ms)[0m [1m[34mSELECT * FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = ? ORDER BY "ar_internal_metadata"."key" ASC LIMIT 1[0m [[nil, "schema_sha1"]]
|
||||
[1m[36mActiveRecord::SchemaMigration Load (0.2ms)[0m [1m[34mSELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
[1m[35m (0.4ms)[0m [1m[35mPRAGMA foreign_keys[0m
|
||||
[1m[35m (0.0ms)[0m [1m[35mPRAGMA defer_foreign_keys[0m
|
||||
[1m[35m (0.0ms)[0m [1m[35mPRAGMA defer_foreign_keys = ON[0m
|
||||
[1m[35m (0.0ms)[0m [1m[35mPRAGMA foreign_keys = OFF[0m
|
||||
[1m[36mFixtures Load (0.2ms)[0m [1m[31mDELETE FROM "break_escape_demo_users";
|
||||
DELETE FROM "break_escape_missions";
|
||||
INSERT INTO "break_escape_demo_users" ("id", "handle", "created_at", "updated_at") VALUES (149617800, 'test_user', '2025-11-21 23:41:20', '2025-11-21 23:41:20');
|
||||
INSERT INTO "break_escape_demo_users" ("id", "handle", "created_at", "updated_at") VALUES (618102942, 'other_user', '2025-11-21 23:41:20', '2025-11-21 23:41:20');
|
||||
INSERT INTO "break_escape_missions" ("id", "name", "display_name", "description", "published", "difficulty_level", "created_at", "updated_at") VALUES (418560898, 'ceo_exfil', 'CEO Exfiltration', 'Test scenario', 1, 3, '2025-11-21 23:41:20', '2025-11-21 23:41:20');
|
||||
INSERT INTO "break_escape_missions" ("id", "name", "display_name", "description", "published", "difficulty_level", "created_at", "updated_at") VALUES (636030761, 'test_unpublished', 'Unpublished Test', 'Not visible', 0, 1, '2025-11-21 23:41:20', '2025-11-21 23:41:20')[0m
|
||||
[1m[35m (0.1ms)[0m [1m[35mPRAGMA defer_foreign_keys = 0[0m
|
||||
[1m[35m (0.0ms)[0m [1m[35mPRAGMA foreign_keys = 1[0m
|
||||
[1m[36mTRANSACTION (5.2ms)[0m [1m[36mcommit transaction[0m
|
||||
[1m[35m (0.1ms)[0m [1m[35mPRAGMA foreign_key_check[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
------------------------------------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_NPC_can_unlock_container_if_player_has_encountered_them_and_NPC_has_permission
|
||||
------------------------------------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.3ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.2ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.6ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.031490"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.030707"], ["updated_at", "2025-11-21 23:41:21.030707"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Update (0.5ms)[0m [1m[33mUPDATE "break_escape_games" SET "scenario_data" = ?, "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}],\"npcs\":[{\"id\":\"helper_npc\",\"displayName\":\"Helpful Contact\",\"unlockable\":[\"safe_pin\",\"cabinet_password\"]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[\"helper_npc\"],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:41:21.034592"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"object", "targetId"=>"safe_pin", "attempt"=>"helper_npc", "method"=>"npc", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.3ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.2ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=object, id=safe_pin, attempt=helper_npc, method=npc
|
||||
[BreakEscape] Found object: id=safe_pin, name=PIN Safe, locked=true, requires=1234
|
||||
[BreakEscape] Validating NPC unlock: npc=helper_npc, target=safe_pin
|
||||
[BreakEscape] NPC unlock validated: helper_npc can unlock safe_pin
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Mission Load (0.3ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::Game Update (0.1ms)[0m [1m[33mUPDATE "break_escape_games" SET "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[\"safe_pin\"],\"inventory\":[],\"encounteredNPCs\":[\"helper_npc\"],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:41:21.150118"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Completed 200 OK in 38ms (Views: 0.5ms | ActiveRecord: 1.0ms (5 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mBreakEscape::Game Load (0.2ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
--------------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_container_with_RFID_lock:_should_trust_client_validation
|
||||
--------------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.4ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.176406"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.176190"], ["updated_at", "2025-11-21 23:41:21.176190"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"object", "targetId"=>"door_rfid", "attempt"=>nil, "method"=>"rfid", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=object, id=door_rfid, attempt=, method=rfid
|
||||
[BreakEscape] Found object: id=door_rfid, name=RFID Door, locked=true, requires=admin_badge
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Mission Load (0.2ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::Game Update (0.1ms)[0m [1m[33mUPDATE "break_escape_games" SET "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[\"door_rfid\"],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:41:21.182607"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Completed 200 OK in 4ms (Views: 0.1ms | ActiveRecord: 0.6ms (5 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
---------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_door_with_PIN_lock:_correct_PIN_should_unlock
|
||||
---------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.3ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.186527"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.186348"], ["updated_at", "2025-11-21 23:41:21.186348"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"door", "targetId"=>"office_pin", "attempt"=>"9876", "method"=>"pin", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=door, id=office_pin, attempt=9876, method=pin
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Mission Load (0.2ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::Game Update (0.1ms)[0m [1m[33mUPDATE "break_escape_games" SET "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\",\"office_pin\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:41:21.191396"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Completed 200 OK in 4ms (Views: 0.1ms | ActiveRecord: 0.6ms (5 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_SECURITY:_method='unlocked'_only_works_for_actually_unlocked_containers
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.4ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.195618"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.195431"], ["updated_at", "2025-11-21 23:41:21.195431"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"object", "targetId"=>"chest_unlocked", "attempt"=>nil, "method"=>"unlocked", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=object, id=chest_unlocked, attempt=, method=unlocked
|
||||
[BreakEscape] Found object: id=chest_unlocked, name=Open Chest, locked=false, requires=
|
||||
[BreakEscape] Object is unlocked in server data, granting access
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Mission Load (0.2ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::Game Update (0.1ms)[0m [1m[33mUPDATE "break_escape_games" SET "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[\"chest_unlocked\"],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:41:21.200607"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Completed 200 OK in 3ms (Views: 0.1ms | ActiveRecord: 0.6ms (5 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[36mbegin transaction[0m
|
||||
-----------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_SECURITY:_NPC_unlock_fails_for_non-existent_NPC
|
||||
-----------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.4ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.204400"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.204209"], ["updated_at", "2025-11-21 23:41:21.204209"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Update (0.2ms)[0m [1m[33mUPDATE "break_escape_games" SET "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[\"helper_npc\"],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:41:21.205928"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"door", "targetId"=>"office_pin", "attempt"=>"fake_npc", "method"=>"npc", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=door, id=office_pin, attempt=fake_npc, method=npc
|
||||
[BreakEscape] Validating NPC unlock: npc=fake_npc, target=office_pin
|
||||
[BreakEscape] NPC not found: fake_npc
|
||||
Completed 422 Unprocessable Content in 2ms (Views: 0.1ms | ActiveRecord: 0.3ms (3 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
--------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_container_with_PIN_lock:_incorrect_PIN_should_fail
|
||||
--------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.3ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.213008"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.212836"], ["updated_at", "2025-11-21 23:41:21.212836"]]
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"object", "targetId"=>"safe_pin", "attempt"=>"0000", "method"=>"pin", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=object, id=safe_pin, attempt=0000, method=pin
|
||||
[BreakEscape] Found object: id=safe_pin, name=PIN Safe, locked=true, requires=1234
|
||||
[BreakEscape] Password validation: required='1234', attempt='0000', result=false
|
||||
Completed 422 Unprocessable Content in 2ms (Views: 0.1ms | ActiveRecord: 0.2ms (3 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
-------------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_container_with_password_lock:_empty_attempt_should_fail
|
||||
-------------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.5ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.233413"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.219937"], ["updated_at", "2025-11-21 23:41:21.219937"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"object", "targetId"=>"cabinet_password", "attempt"=>"", "method"=>"password", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=object, id=cabinet_password, attempt=, method=password
|
||||
[BreakEscape] Found object: id=cabinet_password, name=Password Cabinet, locked=true, requires=secret123
|
||||
[BreakEscape] Password validation: required='secret123', attempt='', result=false
|
||||
Completed 422 Unprocessable Content in 2ms (Views: 0.1ms | ActiveRecord: 0.2ms (3 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_NPC_can_unlock_door_if_player_has_encountered_them_and_NPC_has_permission
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.2ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (3.0ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.4ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.245201"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.245006"], ["updated_at", "2025-11-21 23:41:21.245006"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Update (0.2ms)[0m [1m[33mUPDATE "break_escape_games" SET "scenario_data" = ?, "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}],\"npcs\":[{\"id\":\"helper_npc\",\"displayName\":\"Helpful Contact\",\"unlockable\":[\"office_pin\",\"office_password\"]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[\"helper_npc\"],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:41:21.246804"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"door", "targetId"=>"office_pin", "attempt"=>"helper_npc", "method"=>"npc", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=door, id=office_pin, attempt=helper_npc, method=npc
|
||||
[BreakEscape] Validating NPC unlock: npc=helper_npc, target=office_pin
|
||||
[BreakEscape] NPC unlock validated: helper_npc can unlock office_pin
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Mission Load (0.2ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::Game Update (0.1ms)[0m [1m[33mUPDATE "break_escape_games" SET "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\",\"office_pin\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[\"helper_npc\"],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:41:21.251901"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Completed 200 OK in 4ms (Views: 0.1ms | ActiveRecord: 0.6ms (5 queries, 0 cached) | GC: 10.0ms)
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
-----------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_door_with_password_lock:_case_sensitivity
|
||||
-----------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.5ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.256123"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.255945"], ["updated_at", "2025-11-21 23:41:21.255945"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"door", "targetId"=>"office_password", "attempt"=>"OpenSesame", "method"=>"password", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=door, id=office_password, attempt=OpenSesame, method=password
|
||||
Completed 422 Unprocessable Content in 2ms (Views: 0.1ms | ActiveRecord: 0.2ms (3 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
---------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_door_with_PIN_lock:_incorrect_PIN_should_fail
|
||||
---------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.3ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.264398"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.264196"], ["updated_at", "2025-11-21 23:41:21.264196"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"door", "targetId"=>"office_pin", "attempt"=>"0000", "method"=>"pin", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=door, id=office_pin, attempt=0000, method=pin
|
||||
Completed 422 Unprocessable Content in 2ms (Views: 0.1ms | ActiveRecord: 0.2ms (3 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mBreakEscape::Game Load (0.2ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
------------------------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_SECURITY:_method='unlocked'_only_works_for_actually_unlocked_doors
|
||||
------------------------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.4ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.273841"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.273599"], ["updated_at", "2025-11-21 23:41:21.273599"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"door", "targetId"=>"office_unlocked", "attempt"=>nil, "method"=>"unlocked", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=door, id=office_unlocked, attempt=, method=unlocked
|
||||
[BreakEscape] Door is unlocked in server data, granting access
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Mission Load (0.2ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::Game Update (0.1ms)[0m [1m[33mUPDATE "break_escape_games" SET "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\",\"office_unlocked\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:41:21.279539"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Completed 200 OK in 4ms (Views: 0.1ms | ActiveRecord: 0.6ms (5 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.2ms)[0m [1m[36mbegin transaction[0m
|
||||
--------------------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_container_unlock_response_should_filter_requires_from_contents
|
||||
--------------------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.5ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.284501"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.284155"], ["updated_at", "2025-11-21 23:41:21.284155"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"object", "targetId"=>"safe_pin", "attempt"=>"1234", "method"=>"pin", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=object, id=safe_pin, attempt=1234, method=pin
|
||||
[BreakEscape] Found object: id=safe_pin, name=PIN Safe, locked=true, requires=1234
|
||||
[BreakEscape] Password validation: required='1234', attempt='1234', result=true
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Mission Load (0.3ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::Game Update (0.1ms)[0m [1m[33mUPDATE "break_escape_games" SET "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[\"safe_pin\"],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:41:21.291090"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Completed 200 OK in 5ms (Views: 0.1ms | ActiveRecord: 0.7ms (5 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_SECURITY:_NPC_unlock_fails_if_NPC_doesn't_have_permission_for_that_door
|
||||
-----------------------------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.3ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.295096"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.294919"], ["updated_at", "2025-11-21 23:41:21.294919"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Update (0.4ms)[0m [1m[33mUPDATE "break_escape_games" SET "scenario_data" = ?, "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}],\"npcs\":[{\"id\":\"helper_npc\",\"displayName\":\"Helpful Contact\",\"unlockable\":[\"office_password\"]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[\"helper_npc\"],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:41:21.296652"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"door", "targetId"=>"office_pin", "attempt"=>"helper_npc", "method"=>"npc", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=door, id=office_pin, attempt=helper_npc, method=npc
|
||||
[BreakEscape] Validating NPC unlock: npc=helper_npc, target=office_pin
|
||||
[BreakEscape] NPC helper_npc does not have permission to unlock office_pin
|
||||
Completed 422 Unprocessable Content in 2ms (Views: 0.1ms | ActiveRecord: 0.2ms (3 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
-------------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_door_with_password_lock:_incorrect_password_should_fail
|
||||
-------------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.2ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.4ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.304994"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.304741"], ["updated_at", "2025-11-21 23:41:21.304741"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"door", "targetId"=>"office_password", "attempt"=>"wrongpassword", "method"=>"password", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=door, id=office_password, attempt=wrongpassword, method=password
|
||||
Completed 422 Unprocessable Content in 2ms (Views: 0.1ms | ActiveRecord: 0.2ms (3 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
-------------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_container_with_lockpick:_should_trust_client_validation
|
||||
-------------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.4ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.323432"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.323171"], ["updated_at", "2025-11-21 23:41:21.323171"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"object", "targetId"=>"box_lockpick", "attempt"=>nil, "method"=>"lockpick", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=object, id=box_lockpick, attempt=, method=lockpick
|
||||
[BreakEscape] Found object: id=box_lockpick, name=Lockpickable Box, locked=true, requires=
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Mission Load (0.3ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::Game Update (0.2ms)[0m [1m[33mUPDATE "break_escape_games" SET "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[\"box_lockpick\"],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:41:21.328815"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Completed 200 OK in 5ms (Views: 0.1ms | ActiveRecord: 0.7ms (5 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
-----------------------------------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_door_unlock_response_should_not_expose_'requires'_field_for_exploitable_locks
|
||||
-----------------------------------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.3ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.334489"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.334303"], ["updated_at", "2025-11-21 23:41:21.334303"]]
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"door", "targetId"=>"office_pin", "attempt"=>"9876", "method"=>"pin", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=door, id=office_pin, attempt=9876, method=pin
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Mission Load (0.3ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::Game Update (0.1ms)[0m [1m[33mUPDATE "break_escape_games" SET "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\",\"office_pin\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:41:21.340672"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Completed 200 OK in 5ms (Views: 0.1ms | ActiveRecord: 0.8ms (5 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[36mbegin transaction[0m
|
||||
--------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_unlock_non-existent_object_should_fail
|
||||
--------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.3ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.345306"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.344700"], ["updated_at", "2025-11-21 23:41:21.344700"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"object", "targetId"=>"non_existent_object", "attempt"=>"1234", "method"=>"pin", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=object, id=non_existent_object, attempt=1234, method=pin
|
||||
[BreakEscape] Object not found: non_existent_object
|
||||
Completed 422 Unprocessable Content in 2ms (Views: 0.1ms | ActiveRecord: 0.2ms (3 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
--------------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_SECURITY:_NPC_unlock_fails_if_unlockable_is_not_an_array
|
||||
--------------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.3ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.352910"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.352694"], ["updated_at", "2025-11-21 23:41:21.352694"]]
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Update (0.2ms)[0m [1m[33mUPDATE "break_escape_games" SET "scenario_data" = ?, "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}],\"npcs\":[{\"id\":\"helper_npc\",\"displayName\":\"Helpful Contact\",\"unlockable\":\"office_pin\"}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[\"helper_npc\"],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:41:21.354396"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"door", "targetId"=>"office_pin", "attempt"=>"helper_npc", "method"=>"npc", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=door, id=office_pin, attempt=helper_npc, method=npc
|
||||
[BreakEscape] Validating NPC unlock: npc=helper_npc, target=office_pin
|
||||
[BreakEscape] NPC helper_npc does not have permission to unlock office_pin
|
||||
Completed 422 Unprocessable Content in 2ms (Views: 0.1ms | ActiveRecord: 0.2ms (3 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[36mbegin transaction[0m
|
||||
---------------------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_SECURITY:_locked_door_cannot_be_bypassed_with_method='unlocked'
|
||||
---------------------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.3ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.361204"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.361041"], ["updated_at", "2025-11-21 23:41:21.361041"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"door", "targetId"=>"office_pin", "attempt"=>nil, "method"=>"unlocked", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=door, id=office_pin, attempt=, method=unlocked
|
||||
[BreakEscape] SECURITY VIOLATION: Client sent method='unlocked' for LOCKED door office_pin
|
||||
Completed 422 Unprocessable Content in 2ms (Views: 0.1ms | ActiveRecord: 0.3ms (3 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
-------------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_door_with_password_lock:_correct_password_should_unlock
|
||||
-------------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.3ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.368967"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.368791"], ["updated_at", "2025-11-21 23:41:21.368791"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"door", "targetId"=>"office_password", "attempt"=>"opensesame", "method"=>"password", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=door, id=office_password, attempt=opensesame, method=password
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Mission Load (0.5ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::Game Update (0.1ms)[0m [1m[33mUPDATE "break_escape_games" SET "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\",\"office_password\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:41:21.374399"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Completed 200 OK in 4ms (Views: 0.1ms | ActiveRecord: 0.9ms (5 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
-------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_unlock_same_door_twice_should_be_idempotent
|
||||
-------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.4ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.379071"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.378899"], ["updated_at", "2025-11-21 23:41:21.378899"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"door", "targetId"=>"office_pin", "attempt"=>"9876", "method"=>"pin", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=door, id=office_pin, attempt=9876, method=pin
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Mission Load (0.2ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::Game Update (0.1ms)[0m [1m[33mUPDATE "break_escape_games" SET "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\",\"office_pin\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:41:21.384841"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Completed 200 OK in 4ms (Views: 0.1ms | ActiveRecord: 0.6ms (5 queries, 0 cached) | GC: 0.0ms)
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"door", "targetId"=>"office_pin", "attempt"=>"9876", "method"=>"pin", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=door, id=office_pin, attempt=9876, method=pin
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Mission Load (0.2ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Completed 200 OK in 3ms (Views: 0.1ms | ActiveRecord: 0.5ms (4 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_SECURITY:_locked_container_cannot_be_bypassed_with_method='unlocked'
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.4ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.400753"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.400540"], ["updated_at", "2025-11-21 23:41:21.400540"]]
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"object", "targetId"=>"safe_pin", "attempt"=>nil, "method"=>"unlocked", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=object, id=safe_pin, attempt=, method=unlocked
|
||||
[BreakEscape] Found object: id=safe_pin, name=PIN Safe, locked=true, requires=1234
|
||||
[BreakEscape] SECURITY VIOLATION: Client sent method='unlocked' for LOCKED object safe_pin
|
||||
Completed 422 Unprocessable Content in 2ms (Views: 0.1ms | ActiveRecord: 0.2ms (3 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
-----------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_unlocked_door:_should_grant_access_without_validation
|
||||
-----------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.3ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.408538"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.408338"], ["updated_at", "2025-11-21 23:41:21.408338"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"door", "targetId"=>"office_unlocked", "attempt"=>nil, "method"=>"unlocked", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=door, id=office_unlocked, attempt=, method=unlocked
|
||||
[BreakEscape] Door is unlocked in server data, granting access
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Mission Load (0.2ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::Game Update (0.1ms)[0m [1m[33mUPDATE "break_escape_games" SET "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\",\"office_unlocked\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:41:21.413516"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Completed 200 OK in 4ms (Views: 0.1ms | ActiveRecord: 0.6ms (5 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[36mbegin transaction[0m
|
||||
--------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_unlock_with_invalid_method_should_fail
|
||||
--------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.3ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.417612"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.417429"], ["updated_at", "2025-11-21 23:41:21.417429"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"door", "targetId"=>"office_pin", "attempt"=>"9876", "method"=>"invalid_method", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=door, id=office_pin, attempt=9876, method=invalid_method
|
||||
Completed 422 Unprocessable Content in 2ms (Views: 0.1ms | ActiveRecord: 0.2ms (3 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
-------------------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_container_with_biometric_lock:_should_trust_client_validation
|
||||
-------------------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.3ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.424257"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.424056"], ["updated_at", "2025-11-21 23:41:21.424056"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"object", "targetId"=>"scanner_biometric", "attempt"=>nil, "method"=>"biometric", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=object, id=scanner_biometric, attempt=, method=biometric
|
||||
[BreakEscape] Found object: id=scanner_biometric, name=Biometric Scanner, locked=true, requires=ceo_fingerprint
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Mission Load (0.2ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::Game Update (0.2ms)[0m [1m[33mUPDATE "break_escape_games" SET "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[\"scanner_biometric\"],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:41:21.428900"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Completed 200 OK in 4ms (Views: 0.1ms | ActiveRecord: 0.6ms (5 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
------------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_multiple_unlock_attempts_should_update_state_correctly
|
||||
------------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.3ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.433125"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.432924"], ["updated_at", "2025-11-21 23:41:21.432924"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"door", "targetId"=>"office_pin", "attempt"=>"9876", "method"=>"pin", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=door, id=office_pin, attempt=9876, method=pin
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Mission Load (0.3ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::Game Update (0.1ms)[0m [1m[33mUPDATE "break_escape_games" SET "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\",\"office_pin\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:41:21.437659"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Completed 200 OK in 4ms (Views: 0.1ms | ActiveRecord: 0.7ms (5 queries, 0 cached) | GC: 0.0ms)
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"door", "targetId"=>"office_password", "attempt"=>"opensesame", "method"=>"password", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=door, id=office_password, attempt=opensesame, method=password
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Mission Load (0.2ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::Game Update (0.1ms)[0m [1m[33mUPDATE "break_escape_games" SET "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\",\"office_pin\",\"office_password\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:41:21.442786"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Completed 200 OK in 3ms (Views: 0.1ms | ActiveRecord: 0.7ms (5 queries, 0 cached) | GC: 0.0ms)
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"object", "targetId"=>"safe_pin", "attempt"=>"1234", "method"=>"pin", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=object, id=safe_pin, attempt=1234, method=pin
|
||||
[BreakEscape] Found object: id=safe_pin, name=PIN Safe, locked=true, requires=1234
|
||||
[BreakEscape] Password validation: required='1234', attempt='1234', result=true
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Mission Load (0.2ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::Game Update (0.1ms)[0m [1m[33mUPDATE "break_escape_games" SET "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\",\"office_pin\",\"office_password\"],\"unlockedObjects\":[\"safe_pin\"],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:41:21.447411"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Completed 200 OK in 3ms (Views: 0.1ms | ActiveRecord: 0.6ms (5 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[36mbegin transaction[0m
|
||||
-------------------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_container_with_bluetooth_lock:_should_trust_client_validation
|
||||
-------------------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.3ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.451190"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.451026"], ["updated_at", "2025-11-21 23:41:21.451026"]]
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"object", "targetId"=>"terminal_bluetooth", "attempt"=>nil, "method"=>"bluetooth", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=object, id=terminal_bluetooth, attempt=, method=bluetooth
|
||||
[BreakEscape] Found object: id=terminal_bluetooth, name=Bluetooth Terminal, locked=true, requires=admin_device
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Mission Load (0.2ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::Game Update (0.1ms)[0m [1m[33mUPDATE "break_escape_games" SET "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[\"terminal_bluetooth\"],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:41:21.455705"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Completed 200 OK in 3ms (Views: 0.1ms | ActiveRecord: 0.6ms (5 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_unlock_non-existent_door_should_fail
|
||||
------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.3ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.459101"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.458933"], ["updated_at", "2025-11-21 23:41:21.458933"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"door", "targetId"=>"non_existent_room", "attempt"=>"1234", "method"=>"pin", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=door, id=non_existent_room, attempt=1234, method=pin
|
||||
Completed 422 Unprocessable Content in 2ms (Views: 0.1ms | ActiveRecord: 0.2ms (3 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
--------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_door_with_key_lock:_should_trust_client_validation
|
||||
--------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.3ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.468819"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.468657"], ["updated_at", "2025-11-21 23:41:21.468657"]]
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"door", "targetId"=>"office_key", "attempt"=>nil, "method"=>"key", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=door, id=office_key, attempt=, method=key
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Mission Load (0.2ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::Game Update (0.1ms)[0m [1m[33mUPDATE "break_escape_games" SET "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\",\"office_key\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:41:21.473733"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Completed 200 OK in 3ms (Views: 0.1ms | ActiveRecord: 0.6ms (5 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[36mbegin transaction[0m
|
||||
-------------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_container_with_key_lock:_should_trust_client_validation
|
||||
-------------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.3ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.477910"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.477722"], ["updated_at", "2025-11-21 23:41:21.477722"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"object", "targetId"=>"drawer_key", "attempt"=>nil, "method"=>"key", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=object, id=drawer_key, attempt=, method=key
|
||||
[BreakEscape] Found object: id=drawer_key, name=Locked Drawer, locked=true, requires=drawer_key
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Mission Load (0.3ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::Game Update (0.2ms)[0m [1m[33mUPDATE "break_escape_games" SET "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[\"drawer_key\"],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:41:21.482653"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Completed 200 OK in 4ms (Views: 0.1ms | ActiveRecord: 0.7ms (5 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[36mbegin transaction[0m
|
||||
--------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_container_with_PIN_lock:_correct_PIN_should_unlock
|
||||
--------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.3ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.486316"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.486148"], ["updated_at", "2025-11-21 23:41:21.486148"]]
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"object", "targetId"=>"safe_pin", "attempt"=>"1234", "method"=>"pin", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=object, id=safe_pin, attempt=1234, method=pin
|
||||
[BreakEscape] Found object: id=safe_pin, name=PIN Safe, locked=true, requires=1234
|
||||
[BreakEscape] Password validation: required='1234', attempt='1234', result=true
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Mission Load (0.2ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::Game Update (0.1ms)[0m [1m[33mUPDATE "break_escape_games" SET "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[\"safe_pin\"],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:41:21.490833"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Completed 200 OK in 3ms (Views: 0.1ms | ActiveRecord: 0.6ms (5 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[36mbegin transaction[0m
|
||||
------------------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_SECURITY:_NPC_unlock_fails_if_player_has_not_encountered_NPC
|
||||
------------------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.3ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.495089"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.494909"], ["updated_at", "2025-11-21 23:41:21.494909"]]
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Update (0.2ms)[0m [1m[33mUPDATE "break_escape_games" SET "scenario_data" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}],\"npcs\":[{\"id\":\"helper_npc\",\"displayName\":\"Helpful Contact\",\"unlockable\":[\"office_pin\"]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["updated_at", "2025-11-21 23:41:21.496534"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"door", "targetId"=>"office_pin", "attempt"=>"helper_npc", "method"=>"npc", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=door, id=office_pin, attempt=helper_npc, method=npc
|
||||
[BreakEscape] Validating NPC unlock: npc=helper_npc, target=office_pin
|
||||
[BreakEscape] Player has not encountered NPC: helper_npc
|
||||
Completed 422 Unprocessable Content in 2ms (Views: 0.1ms | ActiveRecord: 0.2ms (3 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[36mbegin transaction[0m
|
||||
------------------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_container_with_password_lock:_correct_password_should_unlock
|
||||
------------------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.3ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.503357"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.503144"], ["updated_at", "2025-11-21 23:41:21.503144"]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"object", "targetId"=>"cabinet_password", "attempt"=>"secret123", "method"=>"password", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=object, id=cabinet_password, attempt=secret123, method=password
|
||||
[BreakEscape] Found object: id=cabinet_password, name=Password Cabinet, locked=true, requires=secret123
|
||||
[BreakEscape] Password validation: required='secret123', attempt='secret123', result=true
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Mission Load (0.2ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::Game Update (0.1ms)[0m [1m[33mUPDATE "break_escape_games" SET "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[\"cabinet_password\"],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:41:21.508174"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Completed 200 OK in 4ms (Views: 0.1ms | ActiveRecord: 0.6ms (5 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[36mbegin transaction[0m
|
||||
----------------------------------------------------------------------------------------------
|
||||
BreakEscape::UnlockSystemTest: test_unlocked_container:_should_grant_access_without_validation
|
||||
----------------------------------------------------------------------------------------------
|
||||
[1m[36mBreakEscape::Mission Load (0.1ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Game Create (0.3ms)[0m [1m[32mINSERT INTO "break_escape_games" ("player_type", "player_id", "mission_id", "scenario_data", "player_state", "status", "started_at", "completed_at", "score", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING "id"[0m [["player_type", "BreakEscape::DemoUser"], ["player_id", 149617800], ["mission_id", 418560898], ["scenario_data", "{\"startRoom\":\"lobby\",\"rooms\":{\"lobby\":{\"type\":\"office_lobby\",\"locked\":false,\"connections\":{\"north\":\"office_pin\",\"south\":\"office_password\",\"east\":\"office_key\",\"west\":\"office_unlocked\"},\"objects\":[{\"id\":\"safe_pin\",\"name\":\"PIN Safe\",\"type\":\"safe\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"1234\",\"contents\":[{\"type\":\"document\",\"name\":\"Secret Document\"}]},{\"id\":\"cabinet_password\",\"name\":\"Password Cabinet\",\"type\":\"cabinet\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"secret123\",\"contents\":[{\"type\":\"key\",\"name\":\"Master Key\"}]},{\"id\":\"drawer_key\",\"name\":\"Locked Drawer\",\"type\":\"drawer\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"drawer_key\",\"contents\":[{\"type\":\"note\",\"name\":\"Important Note\"}]},{\"id\":\"box_lockpick\",\"name\":\"Lockpickable Box\",\"type\":\"box\",\"locked\":true,\"lockType\":\"lockpick\",\"difficulty\":3,\"contents\":[{\"type\":\"coin\",\"name\":\"Gold Coin\"}]},{\"id\":\"scanner_biometric\",\"name\":\"Biometric Scanner\",\"type\":\"scanner\",\"locked\":true,\"lockType\":\"biometric\",\"requires\":\"ceo_fingerprint\",\"contents\":[{\"type\":\"usb\",\"name\":\"Data USB\"}]},{\"id\":\"terminal_bluetooth\",\"name\":\"Bluetooth Terminal\",\"type\":\"terminal\",\"locked\":true,\"lockType\":\"bluetooth\",\"requires\":\"admin_device\",\"contents\":[{\"type\":\"file\",\"name\":\"Access Codes\"}]},{\"id\":\"door_rfid\",\"name\":\"RFID Door\",\"type\":\"door\",\"locked\":true,\"lockType\":\"rfid\",\"requires\":\"admin_badge\",\"contents\":[{\"type\":\"keycard\",\"name\":\"Security Card\"}]},{\"id\":\"chest_unlocked\",\"name\":\"Open Chest\",\"type\":\"chest\",\"locked\":false,\"contents\":[{\"type\":\"tool\",\"name\":\"Wrench\"}]}]},\"office_pin\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"pin\",\"requires\":\"9876\",\"connections\":{\"south\":\"lobby\"},\"objects\":[]},\"office_password\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"password\",\"requires\":\"opensesame\",\"connections\":{\"north\":\"lobby\"},\"objects\":[]},\"office_key\":{\"type\":\"office\",\"locked\":true,\"lockType\":\"key\",\"requires\":\"office_key\",\"connections\":{\"west\":\"lobby\"},\"objects\":[]},\"office_unlocked\":{\"type\":\"office\",\"locked\":false,\"connections\":{\"east\":\"lobby\"},\"objects\":[]}}}"], ["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["status", "in_progress"], ["started_at", "2025-11-21 23:41:21.511990"], ["completed_at", nil], ["score", 0], ["created_at", "2025-11-21 23:41:21.511832"], ["updated_at", "2025-11-21 23:41:21.511832"]]
|
||||
[1m[36mTRANSACTION (0.0ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Started POST "/break_escape/games/1/unlock" for 127.0.0.1 at 2025-11-21 23:41:21 +0000
|
||||
Processing by BreakEscape::GamesController#unlock as HTML
|
||||
Parameters: {"targetType"=>"object", "targetId"=>"chest_unlocked", "attempt"=>nil, "method"=>"unlocked", "id"=>"1"}
|
||||
[1m[36mBreakEscape::Game Load (0.2ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.1ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" ORDER BY "break_escape_demo_users"."id" ASC LIMIT ?[0m [["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::DemoUser Load (0.2ms)[0m [1m[34mSELECT "break_escape_demo_users".* FROM "break_escape_demo_users" WHERE "break_escape_demo_users"."id" = ? LIMIT ?[0m [["id", 149617800], ["LIMIT", 1]]
|
||||
[BreakEscape] validate_unlock: type=object, id=chest_unlocked, attempt=, method=unlocked
|
||||
[BreakEscape] Found object: id=chest_unlocked, name=Open Chest, locked=false, requires=
|
||||
[BreakEscape] Object is unlocked in server data, granting access
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mSAVEPOINT active_record_1[0m
|
||||
[1m[36mBreakEscape::Mission Load (0.3ms)[0m [1m[34mSELECT "break_escape_missions".* FROM "break_escape_missions" WHERE "break_escape_missions"."id" = ? LIMIT ?[0m [["id", 418560898], ["LIMIT", 1]]
|
||||
[1m[36mBreakEscape::Game Update (0.1ms)[0m [1m[33mUPDATE "break_escape_games" SET "player_state" = ?, "updated_at" = ? WHERE "break_escape_games"."id" = ?[0m [["player_state", "{\"currentRoom\":\"lobby\",\"unlockedRooms\":[\"lobby\"],\"unlockedObjects\":[\"chest_unlocked\"],\"inventory\":[],\"encounteredNPCs\":[],\"globalVariables\":{},\"biometricSamples\":[],\"biometricUnlocks\":[],\"bluetoothDevices\":[],\"notes\":[],\"health\":100}"], ["updated_at", "2025-11-21 23:41:21.517299"], ["id", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[35mRELEASE SAVEPOINT active_record_1[0m
|
||||
Completed 200 OK in 4ms (Views: 0.1ms | ActiveRecord: 0.8ms (5 queries, 0 cached) | GC: 0.0ms)
|
||||
[1m[36mBreakEscape::Game Load (0.1ms)[0m [1m[34mSELECT "break_escape_games".* FROM "break_escape_games" WHERE "break_escape_games"."id" = ? LIMIT ?[0m [["id", 1], ["LIMIT", 1]]
|
||||
[1m[36mTRANSACTION (0.1ms)[0m [1m[31mrollback transaction[0m
|
||||
|
||||
Binary file not shown.
@@ -491,6 +491,164 @@ module BreakEscape
|
||||
assert_equal false, json['success']
|
||||
end
|
||||
|
||||
# =============================================================================
|
||||
# NPC UNLOCK TESTS
|
||||
# =============================================================================
|
||||
|
||||
test "NPC can unlock door if player has encountered them and NPC has permission" do
|
||||
# Add NPC with unlock permission to scenario
|
||||
@game.scenario_data['rooms']['lobby']['npcs'] = [
|
||||
{
|
||||
'id' => 'helper_npc',
|
||||
'displayName' => 'Helpful Contact',
|
||||
'unlockable' => ['office_pin', 'office_password']
|
||||
}
|
||||
]
|
||||
# Mark NPC as encountered
|
||||
@game.player_state['encounteredNPCs'] = ['helper_npc']
|
||||
@game.save!
|
||||
|
||||
post unlock_game_url(@game), params: {
|
||||
targetType: 'door',
|
||||
targetId: 'office_pin',
|
||||
attempt: 'helper_npc', # NPC id
|
||||
method: 'npc'
|
||||
}
|
||||
|
||||
assert_response :success
|
||||
json = JSON.parse(@response.body)
|
||||
assert json['success'], "NPC should be able to unlock door they have permission for"
|
||||
|
||||
@game.reload
|
||||
assert_includes @game.player_state['unlockedRooms'], 'office_pin'
|
||||
end
|
||||
|
||||
test "NPC can unlock container if player has encountered them and NPC has permission" do
|
||||
# Add NPC with unlock permission to scenario
|
||||
@game.scenario_data['rooms']['lobby']['npcs'] = [
|
||||
{
|
||||
'id' => 'helper_npc',
|
||||
'displayName' => 'Helpful Contact',
|
||||
'unlockable' => ['safe_pin', 'cabinet_password']
|
||||
}
|
||||
]
|
||||
# Mark NPC as encountered
|
||||
@game.player_state['encounteredNPCs'] = ['helper_npc']
|
||||
@game.save!
|
||||
|
||||
post unlock_game_url(@game), params: {
|
||||
targetType: 'object',
|
||||
targetId: 'safe_pin',
|
||||
attempt: 'helper_npc', # NPC id
|
||||
method: 'npc'
|
||||
}
|
||||
|
||||
assert_response :success
|
||||
json = JSON.parse(@response.body)
|
||||
assert json['success'], "NPC should be able to unlock container they have permission for"
|
||||
|
||||
@game.reload
|
||||
assert_includes @game.player_state['unlockedObjects'], 'safe_pin'
|
||||
end
|
||||
|
||||
test "SECURITY: NPC unlock fails if player has not encountered NPC" do
|
||||
# Add NPC with unlock permission to scenario but DON'T mark as encountered
|
||||
@game.scenario_data['rooms']['lobby']['npcs'] = [
|
||||
{
|
||||
'id' => 'helper_npc',
|
||||
'displayName' => 'Helpful Contact',
|
||||
'unlockable' => ['office_pin']
|
||||
}
|
||||
]
|
||||
@game.save!
|
||||
|
||||
post unlock_game_url(@game), params: {
|
||||
targetType: 'door',
|
||||
targetId: 'office_pin',
|
||||
attempt: 'helper_npc',
|
||||
method: 'npc'
|
||||
}
|
||||
|
||||
assert_response :unprocessable_entity,
|
||||
"SECURITY FAIL: Unlock succeeded without encountering NPC"
|
||||
json = JSON.parse(@response.body)
|
||||
assert_equal false, json['success']
|
||||
|
||||
@game.reload
|
||||
assert_not_includes @game.player_state['unlockedRooms'], 'office_pin'
|
||||
end
|
||||
|
||||
test "SECURITY: NPC unlock fails if NPC doesn't have permission for that door" do
|
||||
# Add NPC but without permission for this specific door
|
||||
@game.scenario_data['rooms']['lobby']['npcs'] = [
|
||||
{
|
||||
'id' => 'helper_npc',
|
||||
'displayName' => 'Helpful Contact',
|
||||
'unlockable' => ['office_password'] # Has permission for different door
|
||||
}
|
||||
]
|
||||
@game.player_state['encounteredNPCs'] = ['helper_npc']
|
||||
@game.save!
|
||||
|
||||
post unlock_game_url(@game), params: {
|
||||
targetType: 'door',
|
||||
targetId: 'office_pin', # Trying to unlock door not in NPC's unlockable list
|
||||
attempt: 'helper_npc',
|
||||
method: 'npc'
|
||||
}
|
||||
|
||||
assert_response :unprocessable_entity,
|
||||
"SECURITY FAIL: NPC unlocked door they don't have permission for"
|
||||
json = JSON.parse(@response.body)
|
||||
assert_equal false, json['success']
|
||||
|
||||
@game.reload
|
||||
assert_not_includes @game.player_state['unlockedRooms'], 'office_pin'
|
||||
end
|
||||
|
||||
test "SECURITY: NPC unlock fails for non-existent NPC" do
|
||||
# Try to use non-existent NPC
|
||||
@game.player_state['encounteredNPCs'] = ['helper_npc']
|
||||
@game.save!
|
||||
|
||||
post unlock_game_url(@game), params: {
|
||||
targetType: 'door',
|
||||
targetId: 'office_pin',
|
||||
attempt: 'fake_npc', # Non-existent NPC
|
||||
method: 'npc'
|
||||
}
|
||||
|
||||
assert_response :unprocessable_entity,
|
||||
"SECURITY FAIL: Unlock succeeded with non-existent NPC"
|
||||
json = JSON.parse(@response.body)
|
||||
assert_equal false, json['success']
|
||||
end
|
||||
|
||||
test "SECURITY: NPC unlock fails if unlockable is not an array" do
|
||||
# Malformed NPC data - unlockable is not an array
|
||||
@game.scenario_data['rooms']['lobby']['npcs'] = [
|
||||
{
|
||||
'id' => 'helper_npc',
|
||||
'displayName' => 'Helpful Contact',
|
||||
'unlockable' => 'office_pin' # String instead of array
|
||||
}
|
||||
]
|
||||
@game.player_state['encounteredNPCs'] = ['helper_npc']
|
||||
@game.save!
|
||||
|
||||
post unlock_game_url(@game), params: {
|
||||
targetType: 'door',
|
||||
targetId: 'office_pin',
|
||||
attempt: 'helper_npc',
|
||||
method: 'npc'
|
||||
}
|
||||
|
||||
assert_response :unprocessable_entity,
|
||||
"SECURITY FAIL: Unlock succeeded with malformed unlockable data"
|
||||
json = JSON.parse(@response.body)
|
||||
assert_equal false, json['success']
|
||||
end
|
||||
|
||||
# =============================================================================
|
||||
# SECURITY TESTS - CLIENT BYPASS ATTEMPTS
|
||||
# =============================================================================
|
||||
|
||||
Reference in New Issue
Block a user