Some checks failed
Deploy / deploy (push) Has been cancelled
Full-stack web application for Telegram management - Frontend: Vue 3 + Vben Admin - Backend: NestJS - Features: User management, group broadcast, statistics 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
238 lines
8.7 KiB
JavaScript
238 lines
8.7 KiB
JavaScript
const { Sequelize } = require('sequelize');
|
|
const Redis = require('ioredis');
|
|
|
|
// Test database configuration
|
|
const testDb = new Sequelize({
|
|
dialect: 'sqlite',
|
|
storage: ':memory:',
|
|
logging: false, // Disable logging during tests
|
|
define: {
|
|
timestamps: true,
|
|
underscored: false
|
|
}
|
|
});
|
|
|
|
// Test Redis client (using redis-mock for testing)
|
|
const MockRedis = require('ioredis-mock');
|
|
const testRedis = new MockRedis();
|
|
|
|
// Mock services for testing
|
|
class TestSetup {
|
|
static async setupDatabase() {
|
|
try {
|
|
// Import all models
|
|
const MAccountPool = require('../src/modes/MAccountPool');
|
|
const MAccountHealthScore = require('../src/modes/MAccountHealthScore');
|
|
const MAccountUsageRecord = require('../src/modes/MAccountUsageRecord');
|
|
const MGroupTask = require('../src/modes/MGroupTask');
|
|
const MRiskRule = require('../src/modes/MRiskRule');
|
|
const MRiskLog = require('../src/modes/MRiskLog');
|
|
const MAnomalyLog = require('../src/modes/MAnomalyLog');
|
|
|
|
// Override database instance for testing
|
|
const models = [
|
|
MAccountPool, MAccountHealthScore, MAccountUsageRecord,
|
|
MGroupTask, MRiskRule, MRiskLog, MAnomalyLog
|
|
];
|
|
|
|
// Recreate models with test database
|
|
for (const model of models) {
|
|
if (model.sequelize) {
|
|
// Re-define model with test database
|
|
const modelName = model.name;
|
|
const attributes = model.rawAttributes;
|
|
const options = model.options;
|
|
|
|
testDb.define(modelName, attributes, {
|
|
...options,
|
|
tableName: options.tableName || modelName
|
|
});
|
|
}
|
|
}
|
|
|
|
// Sync database
|
|
await testDb.sync({ force: true });
|
|
console.log('Test database setup complete');
|
|
|
|
} catch (error) {
|
|
console.error('Test database setup failed:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
static async setupRedis() {
|
|
// Clear all Redis data
|
|
await testRedis.flushall();
|
|
console.log('Test Redis setup complete');
|
|
}
|
|
|
|
static async createTestData() {
|
|
try {
|
|
// Create test accounts
|
|
const testAccounts = [
|
|
{
|
|
accountId: 1,
|
|
phone: '+1234567890',
|
|
status: 'active',
|
|
tier: 'normal',
|
|
healthScore: 85,
|
|
dailyLimit: 50,
|
|
hourlyLimit: 10,
|
|
totalSentCount: 100,
|
|
todaySentCount: 5,
|
|
consecutiveFailures: 0,
|
|
riskScore: 15,
|
|
priority: 60,
|
|
isActive: true
|
|
},
|
|
{
|
|
accountId: 2,
|
|
phone: '+1234567891',
|
|
status: 'warning',
|
|
tier: 'new',
|
|
healthScore: 65,
|
|
dailyLimit: 30,
|
|
hourlyLimit: 5,
|
|
totalSentCount: 20,
|
|
todaySentCount: 2,
|
|
consecutiveFailures: 1,
|
|
riskScore: 35,
|
|
priority: 40,
|
|
isActive: true
|
|
},
|
|
{
|
|
accountId: 3,
|
|
phone: '+1234567892',
|
|
status: 'limited',
|
|
tier: 'trusted',
|
|
healthScore: 45,
|
|
dailyLimit: 100,
|
|
hourlyLimit: 15,
|
|
totalSentCount: 500,
|
|
todaySentCount: 8,
|
|
consecutiveFailures: 3,
|
|
riskScore: 75,
|
|
priority: 20,
|
|
isActive: false
|
|
}
|
|
];
|
|
|
|
// Insert test accounts using raw SQL to avoid model issues
|
|
for (const account of testAccounts) {
|
|
await testDb.query(`
|
|
INSERT INTO accounts_pool
|
|
(accountId, phone, status, tier, healthScore, dailyLimit, hourlyLimit,
|
|
totalSentCount, todaySentCount, consecutiveFailures, riskScore, priority, isActive, createdAt, updatedAt)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, datetime('now'), datetime('now'))
|
|
`, {
|
|
replacements: [
|
|
account.accountId, account.phone, account.status, account.tier,
|
|
account.healthScore, account.dailyLimit, account.hourlyLimit,
|
|
account.totalSentCount, account.todaySentCount, account.consecutiveFailures,
|
|
account.riskScore, account.priority, account.isActive
|
|
]
|
|
});
|
|
}
|
|
|
|
// Create test tasks
|
|
const testTasks = [
|
|
{
|
|
name: 'Test Task 1',
|
|
status: 'completed',
|
|
targetInfo: JSON.stringify({ targets: [{ id: 1, name: 'Group 1' }] }),
|
|
messageContent: JSON.stringify({ content: 'Test message 1' }),
|
|
sendingStrategy: JSON.stringify({ type: 'sequential', interval: 1000 }),
|
|
successCount: 10,
|
|
failureCount: 2,
|
|
processedCount: 12
|
|
},
|
|
{
|
|
name: 'Test Task 2',
|
|
status: 'running',
|
|
targetInfo: JSON.stringify({ targets: [{ id: 2, name: 'Group 2' }] }),
|
|
messageContent: JSON.stringify({ content: 'Test message 2' }),
|
|
sendingStrategy: JSON.stringify({ type: 'parallel', interval: 2000 }),
|
|
successCount: 5,
|
|
failureCount: 1,
|
|
processedCount: 6
|
|
}
|
|
];
|
|
|
|
for (const task of testTasks) {
|
|
await testDb.query(`
|
|
INSERT INTO group_tasks
|
|
(name, status, targetInfo, messageContent, sendingStrategy, successCount, failureCount, processedCount, createdAt, updatedAt)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, datetime('now'), datetime('now'))
|
|
`, {
|
|
replacements: [
|
|
task.name, task.status, task.targetInfo, task.messageContent,
|
|
task.sendingStrategy, task.successCount, task.failureCount, task.processedCount
|
|
]
|
|
});
|
|
}
|
|
|
|
// Create test risk rules
|
|
const testRiskRules = [
|
|
{
|
|
name: 'Frequency Limit',
|
|
type: 'behavior',
|
|
category: 'frequency',
|
|
conditions: JSON.stringify({ timeWindow: 3600, threshold: 10 }),
|
|
action: 'delayed',
|
|
severity: 'medium',
|
|
priority: 70,
|
|
enabled: true
|
|
},
|
|
{
|
|
name: 'Account Health Check',
|
|
type: 'account',
|
|
category: 'health',
|
|
conditions: JSON.stringify({ healthThreshold: 50 }),
|
|
action: 'switched',
|
|
severity: 'high',
|
|
priority: 80,
|
|
enabled: true
|
|
}
|
|
];
|
|
|
|
for (const rule of testRiskRules) {
|
|
await testDb.query(`
|
|
INSERT INTO risk_rules
|
|
(name, type, category, conditions, action, severity, priority, enabled, triggerCount, createdAt, updatedAt)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0, datetime('now'), datetime('now'))
|
|
`, {
|
|
replacements: [
|
|
rule.name, rule.type, rule.category, rule.conditions,
|
|
rule.action, rule.severity, rule.priority, rule.enabled
|
|
]
|
|
});
|
|
}
|
|
|
|
console.log('Test data created successfully');
|
|
|
|
} catch (error) {
|
|
console.error('Failed to create test data:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
static async cleanup() {
|
|
try {
|
|
await testDb.close();
|
|
await testRedis.disconnect();
|
|
console.log('Test cleanup complete');
|
|
} catch (error) {
|
|
console.error('Test cleanup failed:', error);
|
|
}
|
|
}
|
|
|
|
static getTestDb() {
|
|
return testDb;
|
|
}
|
|
|
|
static getTestRedis() {
|
|
return testRedis;
|
|
}
|
|
}
|
|
|
|
module.exports = TestSetup; |