51 lines
3.1 KiB
JavaScript
51 lines
3.1 KiB
JavaScript
import assert from 'assert';
|
|
import { generateSecureKey, hashKey, verifyKeyHash } from '../utils/crypto.js';
|
|
import { LockManager } from '../socket/lockManager.js';
|
|
async function runTests() {
|
|
console.log('🧪 Starting Logic & Security Verification Tests...\n');
|
|
// Test 1: Key Generation & SHA-256 Hashing
|
|
console.log('Test 1: Key generation and SHA-256 hashing...');
|
|
const key1 = generateSecureKey(32);
|
|
const key2 = generateSecureKey(32);
|
|
assert.notStrictEqual(key1, key2, 'Keys must be uniquely generated');
|
|
assert(key1.length > 20, 'Key length should be substantial');
|
|
const hash1 = hashKey(key1);
|
|
const hash2 = hashKey(key2);
|
|
assert.notStrictEqual(hash1, hash2, 'Hashes must differ');
|
|
assert.strictEqual(hash1, hashKey(key1), 'Hash function must be deterministic');
|
|
assert.strictEqual(verifyKeyHash(key1, hash1), true, 'Key verification must succeed for valid key');
|
|
assert.strictEqual(verifyKeyHash('wrong-key', hash1), false, 'Key verification must fail for invalid key');
|
|
console.log('✅ Test 1 Passed: Crypto and Hashing work properly!\n');
|
|
// Test 2: In-Memory Field-Level Lock Manager
|
|
console.log('Test 2: Field-Level Lock Manager & Concurrency...');
|
|
const ticketId = 'ticket-uuid-123';
|
|
const userA = { socketId: 'sock-A', userId: 'user-A', userName: 'Player One' };
|
|
const userB = { socketId: 'sock-B', userId: 'user-B', userName: 'Player Two' };
|
|
// User A acquires lock
|
|
const resA = LockManager.acquireLock(ticketId, 'description', userA.socketId, userA.userId, userA.userName);
|
|
assert.strictEqual(resA.success, true, 'User A should acquire free lock');
|
|
assert.strictEqual(resA.lock?.userId, 'user-A');
|
|
// User B tries to acquire same lock
|
|
const resB = LockManager.acquireLock(ticketId, 'description', userB.socketId, userB.userId, userB.userName);
|
|
assert.strictEqual(resB.success, false, 'User B must be rejected while User A holds lock');
|
|
assert.strictEqual(resB.currentHolder?.userId, 'user-A');
|
|
// User A refreshes lock
|
|
const resARefresh = LockManager.acquireLock(ticketId, 'description', userA.socketId, userA.userId, userA.userName);
|
|
assert.strictEqual(resARefresh.success, true, 'User A should be able to refresh own lock');
|
|
// User A releases lock
|
|
const released = LockManager.releaseLock(ticketId, 'description', userA.socketId);
|
|
assert.notStrictEqual(released, null, 'Lock should be released');
|
|
// Now User B can acquire lock
|
|
const resB2 = LockManager.acquireLock(ticketId, 'description', userB.socketId, userB.userId, userB.userName);
|
|
assert.strictEqual(resB2.success, true, 'User B should acquire lock after release');
|
|
// Socket disconnect cleanup
|
|
const cleaned = LockManager.releaseSocketLocks(userB.socketId);
|
|
assert.strictEqual(cleaned.length, 1, 'Should clean up 1 lock on disconnect');
|
|
console.log('✅ Test 2 Passed: LockManager concurrency & conflict resolution works!\n');
|
|
console.log('🎉 All backend logic tests passed successfully!');
|
|
}
|
|
runTests().catch((err) => {
|
|
console.error('❌ Test failed:', err);
|
|
process.exit(1);
|
|
});
|