Initial commit: Telegram Management System
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:
你的用户名
2025-11-04 15:37:50 +08:00
commit 237c7802e5
3674 changed files with 525172 additions and 0 deletions

View File

@@ -0,0 +1,241 @@
// Integration Test Setup
const mongoose = require('mongoose');
const { MongoMemoryServer } = require('mongodb-memory-server');
const Redis = require('ioredis-mock');
const amqp = require('amqplib');
const { Pool } = require('pg');
const { Client } = require('@elastic/elasticsearch');
const { v4: uuidv4 } = require('uuid');
class TestEnvironment {
constructor() {
this.mongoServer = null;
this.redisClient = null;
this.rabbitConnection = null;
this.pgPool = null;
this.esClient = null;
this.servers = new Map();
}
async setup() {
console.log('Setting up test environment...');
// Setup MongoDB
this.mongoServer = await MongoMemoryServer.create();
const mongoUri = this.mongoServer.getUri();
await mongoose.connect(mongoUri);
// Setup Redis Mock
this.redisClient = new Redis({
data: {}
});
// Setup PostgreSQL (using test database)
this.pgPool = new Pool({
host: process.env.TEST_POSTGRES_HOST || 'localhost',
port: process.env.TEST_POSTGRES_PORT || 5432,
user: process.env.TEST_POSTGRES_USER || 'test_user',
password: process.env.TEST_POSTGRES_PASSWORD || 'test_pass',
database: process.env.TEST_POSTGRES_DB || 'marketing_test'
});
// Create test database schema
await this.setupPostgresSchema();
// Setup RabbitMQ connection
if (process.env.TEST_RABBITMQ_URL) {
try {
this.rabbitConnection = await amqp.connect(process.env.TEST_RABBITMQ_URL);
this.rabbitChannel = await this.rabbitConnection.createChannel();
} catch (error) {
console.warn('RabbitMQ not available for tests:', error.message);
}
}
// Setup Elasticsearch Mock
this.esClient = {
index: jest.fn().mockResolvedValue({ body: { _id: uuidv4() } }),
search: jest.fn().mockResolvedValue({ body: { hits: { hits: [] } } }),
bulk: jest.fn().mockResolvedValue({ body: { errors: false } }),
ping: jest.fn().mockResolvedValue(true)
};
// Set environment variables for services
process.env.MONGODB_URI = mongoUri;
process.env.REDIS_HOST = 'localhost';
process.env.NODE_ENV = 'test';
process.env.JWT_SECRET = 'test-jwt-secret-key-for-testing-only';
process.env.ENCRYPTION_KEY = 'test-encryption-key-32-chars-long';
console.log('Test environment setup complete');
}
async setupPostgresSchema() {
const schemas = [
// Users table
`CREATE TABLE IF NOT EXISTS users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
username VARCHAR(255) UNIQUE NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)`,
// API Keys table
`CREATE TABLE IF NOT EXISTS api_keys (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id),
key_hash VARCHAR(255) UNIQUE NOT NULL,
name VARCHAR(255),
permissions JSONB DEFAULT '[]',
last_used_at TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
expires_at TIMESTAMP
)`,
// Telegram Accounts table
`CREATE TABLE IF NOT EXISTS telegram_accounts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
phone_number VARCHAR(20) UNIQUE NOT NULL,
api_id VARCHAR(255),
api_hash VARCHAR(255),
session_data TEXT,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)`
];
for (const schema of schemas) {
await this.pgPool.query(schema);
}
}
async startService(name, app, port) {
return new Promise((resolve) => {
const server = app.listen(port, () => {
console.log(`Test ${name} service started on port ${port}`);
this.servers.set(name, server);
resolve(server);
});
});
}
async cleanup() {
console.log('Cleaning up test environment...');
// Close all servers
for (const [name, server] of this.servers) {
await new Promise((resolve) => {
server.close(resolve);
});
console.log(`Closed ${name} server`);
}
// Cleanup databases
if (mongoose.connection.readyState === 1) {
await mongoose.disconnect();
}
if (this.mongoServer) {
await this.mongoServer.stop();
}
if (this.pgPool) {
await this.pgPool.end();
}
if (this.rabbitConnection) {
await this.rabbitChannel.close();
await this.rabbitConnection.close();
}
if (this.redisClient) {
this.redisClient.disconnect();
}
console.log('Test environment cleanup complete');
}
// Helper methods for tests
async createTestUser(userData = {}) {
const defaultData = {
username: `testuser_${Date.now()}`,
email: `test_${Date.now()}@example.com`,
password: 'TestPassword123!'
};
const user = { ...defaultData, ...userData };
// Hash password
const bcrypt = require('bcryptjs');
const passwordHash = await bcrypt.hash(user.password, 10);
// Insert into database
const result = await this.pgPool.query(
'INSERT INTO users (username, email, password_hash) VALUES ($1, $2, $3) RETURNING *',
[user.username, user.email, passwordHash]
);
return {
...result.rows[0],
password: user.password // Return plain password for testing
};
}
async createTestApiKey(userId) {
const crypto = require('crypto');
const apiKey = `test_${crypto.randomBytes(16).toString('hex')}`;
const keyHash = crypto.createHash('sha256').update(apiKey).digest('hex');
const result = await this.pgPool.query(
'INSERT INTO api_keys (user_id, key_hash, name, permissions) VALUES ($1, $2, $3, $4) RETURNING *',
[userId, keyHash, 'Test API Key', JSON.stringify(['read', 'write'])]
);
return {
...result.rows[0],
apiKey // Return plain key for testing
};
}
async createTestTelegramAccount(data = {}) {
const defaultData = {
phone_number: `+1234567${Date.now().toString().slice(-4)}`,
api_id: '12345',
api_hash: 'test_api_hash',
session_data: 'test_session_data'
};
const account = { ...defaultData, ...data };
const result = await this.pgPool.query(
'INSERT INTO telegram_accounts (phone_number, api_id, api_hash, session_data) VALUES ($1, $2, $3, $4) RETURNING *',
[account.phone_number, account.api_id, account.api_hash, account.session_data]
);
return result.rows[0];
}
getRedisClient() {
return this.redisClient;
}
getMongoConnection() {
return mongoose.connection;
}
getPostgresPool() {
return this.pgPool;
}
getRabbitChannel() {
return this.rabbitChannel;
}
getElasticsearchClient() {
return this.esClient;
}
}
module.exports = TestEnvironment;