#!/usr/bin/env node /** * Local test script for the new token caching system * This tests the hybrid keychain + AWS approach without MCP */ import { UpworkClient } from "./src/services/upwork-client.js"; import { getProposalDetailsTool } from "./src/tools/proposal/get-proposal-details.js"; import { refreshTokenTool } from "./src/tools/token/refresh-token.js"; const TEST_PROPOSAL_ID = "1958709255028473857"; async function testTokenCaching() { console.log("๐Ÿงช Testing Upwork Token Caching System\n"); const upworkClient = new UpworkClient(); console.log("=".repeat(80)); console.log("๐Ÿ” TEST 1: First API Call (Should Cache Tokens)"); console.log("=".repeat(80)); try { const result1 = await getProposalDetailsTool.handler( { proposalId: TEST_PROPOSAL_ID }, upworkClient ); if (result1.isError) { console.log("โŒ First call failed:", result1.content[0].text); } else { console.log("โœ… First call succeeded"); // Show just the summary part, not the full JSON const text = result1.content[0].text; const summaryEnd = text.indexOf('\n\n๐Ÿ“Š **Full Proposal Data**:'); const summary = summaryEnd > -1 ? text.substring(0, summaryEnd) : text; console.log(summary); } } catch (error) { console.error("โŒ First call error:", error.message); } console.log("\n" + "=".repeat(80)); console.log("โšก TEST 2: Second API Call (Should Use Cache)"); console.log("=".repeat(80)); try { const start = Date.now(); const result2 = await getProposalDetailsTool.handler( { proposalId: TEST_PROPOSAL_ID }, upworkClient ); const elapsed = Date.now() - start; if (result2.isError) { console.log("โŒ Second call failed:", result2.content[0].text); } else { console.log(`โœ… Second call succeeded in ${elapsed}ms (should be faster due to caching)`); } } catch (error) { console.error("โŒ Second call error:", error.message); } console.log("\n" + "=".repeat(80)); console.log("๐Ÿ”„ TEST 3: Token Refresh Tool"); console.log("=".repeat(80)); try { const refreshResult = await refreshTokenTool.handler( { accountType: "freelancer" }, upworkClient ); if (refreshResult.isError) { console.log("โŒ Token refresh failed:", refreshResult.content[0].text); } else { console.log("โœ… Token refresh succeeded"); console.log(refreshResult.content[0].text); } } catch (error) { console.error("โŒ Token refresh error:", error.message); } console.log("\n" + "=".repeat(80)); console.log("๐ŸŽฏ TEST 4: API Call After Refresh (Should Use New Cache)"); console.log("=".repeat(80)); try { const result4 = await getProposalDetailsTool.handler( { proposalId: TEST_PROPOSAL_ID }, upworkClient ); if (result4.isError) { console.log("โŒ Post-refresh call failed:", result4.content[0].text); } else { console.log("โœ… Post-refresh call succeeded"); } } catch (error) { console.error("โŒ Post-refresh call error:", error.message); } console.log("\n" + "=".repeat(80)); console.log("๐Ÿ“Š TEST 5: Token Age Diagnostics"); console.log("=".repeat(80)); try { const age = await upworkClient.getTokenAge('freelancer'); if (age !== null) { console.log(`๐Ÿ•’ Token age: ${Math.floor(age / 60)} minutes and ${age % 60} seconds`); } else { console.log("โ“ No token age information available"); } } catch (error) { console.error("โŒ Token age check error:", error.message); } console.log("\n๐ŸŽ‰ All tests completed!"); console.log("\n๐Ÿ“ **What To Look For:**"); console.log("- First call should say 'fetching from AWS' or 'using cached tokens'"); console.log("- Second call should be faster and say 'using cached tokens'"); console.log("- Token refresh should clear cache and get fresh from AWS"); console.log("- Check ~/.mcp-upwork/ directory for local token files"); console.log("- Look for keychain entries (Keychain Access app on Mac)"); } // Run the test if this file is executed directly if (import.meta.url === `file://${process.argv[1]}`) { testTokenCaching().catch(console.error); } export { testTokenCaching };