Initial commit: Telegram Management System
Some checks failed
Deploy / deploy (push) Has been cancelled
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>
This commit is contained in:
238
backend/test/setup.js
Normal file
238
backend/test/setup.js
Normal file
@@ -0,0 +1,238 @@
|
||||
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;
|
||||
Reference in New Issue
Block a user