#!/usr/bin/env node
/**
* Test script to verify basic Keet messaging functionality.
* This test uses the actual Keet dependencies directly in Node.js.
*
* This is a fixed version that addresses issues with the original test.
*/
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
// Get the directory name of the current module
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// Configure logging
const logLevels = {
INFO: 'INFO',
ERROR: 'ERROR',
WARNING: 'WARNING'
};
function log(level, message) {
const timestamp = new Date().toISOString();
console.log(`[${timestamp}] [${level}] ${message}`);
}
// Import Keet dependencies
let KeetBackend, KeetCoreApi;
let KEET_AVAILABLE = false;
try {
// Dynamic imports to handle potential import failures gracefully
const backendModule = await import('@holepunchto/keet-backend');
const coreApiModule = await import('@holepunchto/keet-core-api');
// Try to get the exports
KeetBackend = backendModule.default || backendModule;
KeetCoreApi = coreApiModule.default || coreApiModule;
KEET_AVAILABLE = true;
log(logLevels.INFO, 'Successfully imported Keet dependencies');
} catch (error) {
log(logLevels.WARNING, `Failed to import Keet dependencies: ${error.message}`);
log(logLevels.WARNING, 'This test will be skipped');
}
/**
* Test basic Keet messaging functionality.
*/
async function testKeetMessaging() {
if (!KEET_AVAILABLE) {
log(logLevels.ERROR, 'Keet dependencies not available. Skipping test.');
return false;
}
try {
// Create a test storage directory
const storagePath = path.join(__dirname, '..', 'test-keet-storage');
if (!fs.existsSync(storagePath)) {
fs.mkdirSync(storagePath, { recursive: true });
}
// Initialize Keet backend
log(logLevels.INFO, 'Initializing Keet backend...');
const backend = new KeetBackend(storagePath, {
experimental: false,
devMirrors: false
});
// Wait for backend to be ready
await backend.ready();
// Check if we have an identity
log(logLevels.INFO, 'Checking identity...');
const identity = await backend.api.core.getIdentity();
log(logLevels.INFO, `Current identity: ${JSON.stringify(identity)}`);
// If we don't have an identity, create one
if (!identity) {
log(logLevels.INFO, 'No identity found, generating a new one...');
await backend.api.core.generateIdentity();
const newIdentity = await backend.api.core.getIdentity();
log(logLevels.INFO, `New identity created: ${JSON.stringify(newIdentity)}`);
}
// Get recent rooms to see what we have
log(logLevels.INFO, 'Getting recent rooms...');
const recentRooms = await backend.api.core.getRecentRooms();
log(logLevels.INFO, `Found ${recentRooms.length} recent rooms`);
// Log all rooms for debugging
for (const room of recentRooms) {
log(logLevels.INFO, `Room: ${JSON.stringify(room)}`);
}
// Use the first room if available, otherwise create a new one
let roomId;
if (recentRooms.length > 0) {
roomId = recentRooms[0].roomId;
log(logLevels.INFO, `Using existing room: ${roomId}`);
} else {
// Create a new room
log(logLevels.INFO, 'No rooms found, creating a new one...');
// Check if the createRoom method is available
if (backend.api.core.createRoom) {
roomId = await backend.api.core.createRoom({
title: 'Test Room',
description: 'A test room for Keet messaging'
});
log(logLevels.INFO, `Created new room: ${roomId}`);
} else {
log(logLevels.ERROR, 'createRoom method not available');
return false;
}
}
// Try to get room metadata
try {
log(logLevels.INFO, `Getting room metadata for room: ${roomId}`);
const metadata = await backend.api.core.getLocalRoomMetadata(roomId);
log(logLevels.INFO, `Room metadata: ${JSON.stringify(metadata)}`);
} catch (error) {
log(logLevels.WARNING, `Failed to get room metadata: ${error.message}`);
}
// Try to get room members
try {
log(logLevels.INFO, `Getting room members for room: ${roomId}`);
const members = await backend.api.core.getMembers(roomId);
log(logLevels.INFO, `Room members: ${JSON.stringify(members)}`);
} catch (error) {
log(logLevels.WARNING, `Failed to get room members: ${error.message}`);
}
// Get messages from the room
try {
log(logLevels.INFO, `Getting messages from room: ${roomId}`);
const messages = await backend.api.core.getChatMessages(roomId);
log(logLevels.INFO, `Found ${messages.length} messages in the room`);
// Log all messages for debugging
log(logLevels.INFO, 'Listing all messages:');
for (const message of messages) {
log(logLevels.INFO, `Message: ${JSON.stringify(message)}`);
}
} catch (error) {
log(logLevels.WARNING, `Failed to get messages: ${error.message}`);
}
// Send a test message to the room
try {
const testMessage = 'This is a test message from the Keet messaging test';
log(logLevels.INFO, `Sending a test message to room: ${roomId}`);
await backend.api.core.addChatMessage(roomId, testMessage);
log(logLevels.INFO, 'Test message sent successfully!');
// Get messages again to verify the message was sent
log(logLevels.INFO, 'Getting messages again to verify...');
const updatedMessages = await backend.api.core.getChatMessages(roomId);
log(logLevels.INFO, `Found ${updatedMessages.length} messages in the room after sending`);
// Check if our message was added
let foundOurMessage = false;
for (const message of updatedMessages) {
if (message.chat && message.chat.text === testMessage) {
foundOurMessage = true;
log(logLevels.INFO, `Found our test message: ${JSON.stringify(message)}`);
break;
}
}
if (!foundOurMessage) {
log(logLevels.WARNING, 'Could not find our test message. This might indicate the message was not sent properly.');
// Log all messages for debugging
log(logLevels.INFO, 'Listing all messages after sending:');
for (const message of updatedMessages) {
log(logLevels.INFO, `Message: ${JSON.stringify(message)}`);
}
}
} catch (error) {
log(logLevels.WARNING, `Failed to send message: ${error.message}`);
}
// Keep the connection open for a short time to potentially receive messages
log(logLevels.INFO, 'Waiting for potential incoming messages (5 seconds)...');
await new Promise(resolve => setTimeout(resolve, 5000));
// Try to get messages one more time
try {
log(logLevels.INFO, `Getting messages from room one more time: ${roomId}`);
const finalMessages = await backend.api.core.getChatMessages(roomId);
log(logLevels.INFO, `Found ${finalMessages.length} messages in the room at the end`);
// Log all messages for debugging
log(logLevels.INFO, 'Listing all final messages:');
for (const message of finalMessages) {
log(logLevels.INFO, `Message: ${JSON.stringify(message)}`);
}
} catch (error) {
log(logLevels.WARNING, `Failed to get final messages: ${error.message}`);
}
// Clean up
log(logLevels.INFO, 'Cleaning up...');
// Close the backend
log(logLevels.INFO, 'Closing backend...');
await backend.close();
return true;
} catch (error) {
log(logLevels.ERROR, `Error in Keet messaging test: ${error.message}`);
log(logLevels.ERROR, error.stack);
return false;
}
}
// Run the test if this file is executed directly
if (import.meta.url === `file://${process.argv[1]}`) {
try {
const success = await testKeetMessaging();
if (success) {
log(logLevels.INFO, 'Keet messaging test successful!');
process.exit(0);
} else {
log(logLevels.ERROR, 'Keet messaging test failed!');
process.exit(1);
}
} catch (error) {
log(logLevels.ERROR, `Unhandled error: ${error.message}`);
log(logLevels.ERROR, error.stack);
process.exit(1);
}
}
export { testKeetMessaging };