File size: 5,223 Bytes
149698e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#!/usr/bin/env node
// scripts/test-all.ts
//
// ICC Interac Manager β€” Master Test Runner
// Run: npx tsx scripts/test-all.ts
//
// Runs all test suites in the correct order:
//   1. Unit tests (no server needed)
//   2. Health check (validates environment)
//   3. API tests (requires server running)
//   4. WebSocket tests (requires server running)
//   5. AI parsing tests (requires API keys)

import 'dotenv/config';
import { execSync } from 'child_process';
import path from 'path';
import { fileURLToPath } from 'url';

const BOLD = '\x1b[1m';
const RESET = '\x1b[0m';
const GREEN = '\x1b[32m';
const RED = '\x1b[31m';
const YELLOW = '\x1b[33m';
const CYAN = '\x1b[36m';

const scriptsDir = path.dirname(fileURLToPath(import.meta.url));

interface TestSuite {
  name: string;
  file: string;
  requiresServer: boolean;
  requiresAI: boolean;
}

const suites: TestSuite[] = [
  { name: '1. Unit Tests',         file: 'test-units.ts',       requiresServer: false, requiresAI: false },
  { name: '2. Health Check',       file: 'healthcheck.ts',      requiresServer: false, requiresAI: false },
  { name: '3. API Endpoint Tests', file: 'test-api.ts',         requiresServer: true,  requiresAI: false },
  { name: '4. WebSocket Tests',    file: 'test-websocket.ts',   requiresServer: true,  requiresAI: false },
  { name: '5. AI Parsing Tests',   file: 'test-ai-parsing.ts',  requiresServer: false, requiresAI: true },
];

async function main() {
  console.log(`\n${BOLD}╔══════════════════════════════════════════╗${RESET}`);
  console.log(`${BOLD}β•‘   ICC Interac Manager β€” Test Runner      β•‘${RESET}`);
  console.log(`${BOLD}β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•${RESET}\n`);

  let totalPassed = 0;
  let totalFailed = 0;
  const results: { name: string; status: 'pass' | 'fail' | 'skip' }[] = [];

  // Check if server is running
  let serverRunning = false;
  try {
    const port = process.env.PORT || '3001';
    const res = await fetch(`http://localhost:${port}/api/health`, { signal: AbortSignal.timeout(2000) });
    serverRunning = res.ok;
  } catch {}

  if (!serverRunning) {
    console.log(`${YELLOW}⚠️  Server not running on port ${process.env.PORT || '3001'}${RESET}`);
    console.log(`   Some tests will be skipped. Start server with:`);
    console.log(`   ${CYAN}npx tsx packages/server/src/index.ts${RESET}\n`);
  }

  for (const suite of suites) {
    console.log(`${BOLD}━━━ ${suite.name} ━━━${RESET}`);

    // Skip conditions
    if (suite.requiresServer && !serverRunning) {
      console.log(`  ${YELLOW}⏭️  Skipped (server not running)${RESET}\n`);
      results.push({ name: suite.name, status: 'skip' });
      continue;
    }

    if (suite.requiresAI && !process.env.GROQ_API_KEY && !process.env.MISTRAL_API_KEY) {
      console.log(`  ${YELLOW}⏭️  Skipped (no AI API keys)${RESET}\n`);
      results.push({ name: suite.name, status: 'skip' });
      continue;
    }

    try {
      const filePath = path.join(scriptsDir, suite.file);
      execSync(`npx tsx "${filePath}"`, {
        stdio: 'inherit',
        env: { ...process.env },
        cwd: process.cwd(),
      });
      results.push({ name: suite.name, status: 'pass' });
      totalPassed++;
    } catch (error: any) {
      results.push({ name: suite.name, status: 'fail' });
      totalFailed++;
    }

    console.log('');
  }

  // ═══ FINAL SUMMARY ═══
  console.log(`${BOLD}╔══════════════════════════════════════════╗${RESET}`);
  console.log(`${BOLD}β•‘   Final Results                          β•‘${RESET}`);
  console.log(`${BOLD}╠══════════════════════════════════════════╣${RESET}`);

  for (const r of results) {
    const icon = r.status === 'pass' ? `${GREEN}βœ…` : r.status === 'fail' ? `${RED}❌` : `${YELLOW}⏭️ `;
    console.log(`${BOLD}β•‘${RESET}  ${icon} ${r.name}${RESET}`);
  }

  console.log(`${BOLD}╠══════════════════════════════════════════╣${RESET}`);
  const skipped = results.filter((r) => r.status === 'skip').length;
  console.log(`${BOLD}β•‘${RESET}  Suites: ${GREEN}${totalPassed} passed${RESET}, ${RED}${totalFailed} failed${RESET}, ${YELLOW}${skipped} skipped${RESET}`);
  console.log(`${BOLD}β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•${RESET}\n`);

  if (totalFailed === 0 && skipped === 0) {
    console.log(`${GREEN}πŸŽ‰ All tests passed! Your ICC app is ready.${RESET}\n`);
  } else if (totalFailed === 0) {
    console.log(`${YELLOW}⚠️  Some tests skipped. Run the server and add API keys to test everything.${RESET}\n`);
  } else {
    console.log(`${RED}πŸ”§ Fix the failing tests above, then re-run.${RESET}\n`);
  }

  process.exit(totalFailed > 0 ? 1 : 0);
}

main().catch(console.error);