# test_security_lock_parity.gd —— 40250 仓库安全密码与装备防丢锁定 1:1 纯净回归测试套件 extends SceneTree const SecurityLockSystem = preload("res://security_lock_system.gd") var _passed := 0 var _failed := 0 func _assert(cond: bool, msg: String) -> void: if cond: _passed += 1 print(" [PASS] %s" % msg) else: _failed += 1 printerr(" [FAIL] %s" % msg) func _init() -> void: print("\n=== Running test_security_lock_parity (Direction 4: Security Lock System 1:1) ===") _test_safebox_password_auth() _test_safebox_password_change() _test_item_security_lock_and_unlock() _test_item_action_gates() _test_character_deletion_code() _finish() func _test_safebox_password_auth() -> void: print("\n--- Test 1: Safebox Password Authentication & Lockout ---") var sec := SecurityLockSystem.new() var unlock_data := {"fired": false} sec.safebox_unlocked.connect(func(): unlock_data["fired"] = true) _assert(sec.safebox_password == "000000", "Default safebox password is '000000'") _assert(sec.is_safebox_unlocked == false, "Safebox initially closed") # Wrong password 1st time var res1 = sec.open_safebox("111111") _assert(res1["ok"] == false and res1["reason"] == "WRONG_PASSWORD", "Wrong password fails") _assert(res1["remaining_attempts"] == 4, "4 attempts remaining") # Fail 4 more times to reach 5 sec.open_safebox("111111") sec.open_safebox("111111") sec.open_safebox("111111") var res5 = sec.open_safebox("111111") _assert(res5["ok"] == false and res5["reason"] == "WRONG_PASSWORD_LOCKOUT", "5th failure triggers lockout") _assert(sec.is_locked_out == true, "is_locked_out is true") # Blocked while locked out even with correct password var locked_res = sec.open_safebox("000000") _assert(locked_res["ok"] == false and locked_res["reason"] == "LOCKOUT", "Action blocked while locked out") # Reset lockout sec.reset_lockout() _assert(sec.is_locked_out == false and sec.failed_attempts == 0, "Lockout reset successfully") # Now correct password opens safebox var ok_res = sec.open_safebox("000000") _assert(ok_res["ok"] == true, "Correct password opened safebox") _assert(sec.is_safebox_unlocked == true, "Safebox is unlocked") _assert(unlock_data["fired"] == true, "safebox_unlocked signal fired") # Close safebox var close_data := {"fired": false} sec.safebox_closed.connect(func(): close_data["fired"] = true) sec.close_safebox() _assert(sec.is_safebox_unlocked == false, "Safebox closed") _assert(close_data["fired"] == true, "safebox_closed signal fired") func _test_safebox_password_change() -> void: print("\n--- Test 2: Password Change Validation (Strict 6 Digits) ---") var sec := SecurityLockSystem.new() # Wrong old password var r1 = sec.change_safebox_password("999999", "123456") _assert(r1["ok"] == false and r1["reason"] == "WRONG_OLD_PASSWORD", "Wrong old password rejected") # Invalid format: 5 digits var r2 = sec.change_safebox_password("000000", "12345") _assert(r2["ok"] == false and r2["reason"] == "INVALID_PASSWORD_FORMAT", "5-digit password rejected") # Invalid format: 7 digits var r3 = sec.change_safebox_password("000000", "1234567") _assert(r3["ok"] == false and r3["reason"] == "INVALID_PASSWORD_FORMAT", "7-digit password rejected") # Invalid format: Contains non-digits var r4 = sec.change_safebox_password("000000", "12a456") _assert(r4["ok"] == false and r4["reason"] == "INVALID_PASSWORD_FORMAT", "Alphanumeric password rejected") # Same password var r5 = sec.change_safebox_password("000000", "000000") _assert(r5["ok"] == false and r5["reason"] == "SAME_PASSWORD", "Identical new password rejected") # Valid change to "888888" var pwd_data := {"fired": false, "new_pwd": ""} sec.password_changed.connect(func(np: String): pwd_data["fired"] = true pwd_data["new_pwd"] = np ) var r6 = sec.change_safebox_password("000000", "888888") _assert(r6["ok"] == true, "Valid 6-digit password changed successfully") _assert(sec.safebox_password == "888888", "Active password updated to '888888'") _assert(pwd_data["fired"] == true and pwd_data["new_pwd"] == "888888", "password_changed signal fired") # Verify old password no longer works var old_try = sec.open_safebox("000000") _assert(old_try["ok"] == false, "Old password '000000' no longer valid") # Verify new password works var new_try = sec.open_safebox("888888") _assert(new_try["ok"] == true, "New password '888888' valid") func _test_item_security_lock_and_unlock() -> void: print("\n--- Test 3: Item Anti-Theft Lock & Unlock ---") var sec := SecurityLockSystem.new() var test_item: Dictionary = { "vnum": 169, "name": "战神之剑+9", "count": 1 } var lock_signal := {"fired": false, "name": ""} sec.item_locked.connect(func(n: String): lock_signal["fired"] = true lock_signal["name"] = n ) var unlock_signal := {"fired": false, "name": ""} sec.item_unlocked.connect(func(n: String): unlock_signal["fired"] = true unlock_signal["name"] = n ) # Lock with wrong password var r1 = sec.lock_item(test_item, "999999") _assert(r1["ok"] == false and r1["reason"] == "WRONG_SECURITY_PASSWORD", "Wrong password prevents locking") # Lock with correct password var r2 = sec.lock_item(test_item, "000000") _assert(r2["ok"] == true, "Item locked successfully") _assert(test_item["is_locked"] == true, "Item is_locked flag is true") _assert(lock_signal["fired"] == true and lock_signal["name"] == "战神之剑+9", "item_locked signal fired") # Attempt to lock already locked item var r3 = sec.lock_item(test_item, "000000") _assert(r3["ok"] == false and r3["reason"] == "ALREADY_LOCKED", "Already locked item rejected") # Unlock with wrong password var r4 = sec.unlock_item(test_item, "999999") _assert(r4["ok"] == false and r4["reason"] == "WRONG_SECURITY_PASSWORD", "Wrong password prevents unlocking") # Unlock with correct password var r5 = sec.unlock_item(test_item, "000000") _assert(r5["ok"] == true, "Item unlocked successfully") _assert(test_item["is_locked"] == false, "Item is_locked flag is false") _assert(unlock_signal["fired"] == true and unlock_signal["name"] == "战神之剑+9", "item_unlocked signal fired") # Attempt to unlock unlocked item var r6 = sec.unlock_item(test_item, "000000") _assert(r6["ok"] == false and r6["reason"] == "NOT_LOCKED", "Already unlocked item rejected") func _test_item_action_gates() -> void: print("\n--- Test 4: Action Protection Gates (Drop, Sell, Destroy, Trade, Refine) ---") var sec := SecurityLockSystem.new() var normal_item: Dictionary = {"vnum": 10, "name": "木剑+0", "is_locked": false} var locked_item: Dictionary = {"vnum": 11299, "name": "黑钢甲+9", "is_locked": true} # Normal item allowed everywhere _assert(sec.can_drop_item(normal_item)["allowed"] == true, "Normal item can be dropped") _assert(sec.can_sell_item(normal_item)["allowed"] == true, "Normal item can be sold") _assert(sec.can_destroy_item(normal_item)["allowed"] == true, "Normal item can be destroyed") _assert(sec.can_trade_item(normal_item)["allowed"] == true, "Normal item can be traded") _assert(sec.can_refine_item(normal_item)["allowed"] == true, "Normal item can be refined") # Locked item blocked everywhere with ITEM_LOCKED var drop_gate = sec.can_drop_item(locked_item) _assert(drop_gate["allowed"] == false and drop_gate["reason"] == "ITEM_LOCKED", "Locked item DROP blocked") var sell_gate = sec.can_sell_item(locked_item) _assert(sell_gate["allowed"] == false and sell_gate["reason"] == "ITEM_LOCKED", "Locked item SELL blocked") var destroy_gate = sec.can_destroy_item(locked_item) _assert(destroy_gate["allowed"] == false and destroy_gate["reason"] == "ITEM_LOCKED", "Locked item DESTROY blocked") var trade_gate = sec.can_trade_item(locked_item) _assert(trade_gate["allowed"] == false and trade_gate["reason"] == "ITEM_LOCKED", "Locked item TRADE blocked") var refine_gate = sec.can_refine_item(locked_item) _assert(refine_gate["allowed"] == false and refine_gate["reason"] == "ITEM_LOCKED", "Locked item REFINE blocked") func _test_character_deletion_code() -> void: print("\n--- Test 5: 7-Digit Character Deletion Security Code ---") var sec := SecurityLockSystem.new() _assert(sec.char_delete_code == "1234567", "Default 7-digit deletion code is '1234567'") # Invalid length: 6 digits var r1 = sec.verify_character_deletion("123456") _assert(r1["ok"] == false and r1["reason"] == "INVALID_CODE_FORMAT", "6-digit deletion code rejected") # Invalid format: non-numeric var r2 = sec.verify_character_deletion("123456a") _assert(r2["ok"] == false and r2["reason"] == "INVALID_CODE_FORMAT", "Alphanumeric deletion code rejected") # Wrong 7-digit code var r3 = sec.verify_character_deletion("7654321") _assert(r3["ok"] == false and r3["reason"] == "WRONG_DELETE_CODE", "Wrong deletion code rejected") # Correct 7-digit code var r4 = sec.verify_character_deletion("1234567") _assert(r4["ok"] == true, "Correct 7-digit code authorizes deletion") func _finish() -> void: print("\n==========================================") print("Security Lock Parity Test Results: %d Passed, %d Failed" % [_passed, _failed]) print("==========================================") if _failed > 0: quit(1) else: quit(0)