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,239 @@
// API Gateway Integration Tests
const TestEnvironment = require('./setup');
const TestHelpers = require('./helpers');
const apiGatewayApp = require('../../services/api-gateway/src/app');
describe('API Gateway Integration Tests', () => {
let testEnv;
let helpers;
let apiClient;
let testUser;
let apiKey;
const API_GATEWAY_PORT = 13000;
const API_BASE_URL = `http://localhost:${API_GATEWAY_PORT}/api/v1`;
beforeAll(async () => {
testEnv = new TestEnvironment();
helpers = new TestHelpers(testEnv);
// Setup test environment
await testEnv.setup();
// Setup mocks
helpers.setupMocks();
// Start API Gateway
await testEnv.startService('api-gateway', apiGatewayApp, API_GATEWAY_PORT);
// Create test user and API key
testUser = await testEnv.createTestUser();
apiKey = await testEnv.createTestApiKey(testUser.id);
// Create authenticated client
apiClient = await helpers.createAuthenticatedClient(`http://localhost:${API_GATEWAY_PORT}`, testUser);
});
afterAll(async () => {
helpers.cleanupMocks();
await testEnv.cleanup();
});
describe('Authentication', () => {
test('should authenticate with JWT token', async () => {
const response = await apiClient.get('/api/v1/auth/me');
const data = helpers.expectApiSuccess(response);
expect(data.user).toBeDefined();
expect(data.user.id).toBe(testUser.id);
expect(data.user.username).toBe(testUser.username);
});
test('should reject invalid token', async () => {
const invalidClient = require('axios').create({
baseURL: `http://localhost:${API_GATEWAY_PORT}`,
headers: {
'Authorization': 'Bearer invalid-token'
},
validateStatus: () => true
});
const response = await invalidClient.get('/api/v1/auth/me');
helpers.expectApiError(response, 401, 'Invalid token');
});
test('should authenticate with API key', async () => {
const apiKeyClient = require('axios').create({
baseURL: `http://localhost:${API_GATEWAY_PORT}`,
headers: {
'X-API-Key': apiKey.apiKey
},
validateStatus: () => true
});
const response = await apiKeyClient.get('/api/v1/auth/me');
const data = helpers.expectApiSuccess(response);
expect(data.user).toBeDefined();
expect(data.apiKey).toBeDefined();
});
});
describe('Rate Limiting', () => {
test('should enforce rate limits', async () => {
const requests = [];
// Make many requests quickly
for (let i = 0; i < 105; i++) {
requests.push(
apiClient.get('/api/v1/health').catch(e => e.response)
);
}
const responses = await Promise.all(requests);
// Check that some requests were rate limited
const rateLimited = responses.filter(r => r.status === 429);
expect(rateLimited.length).toBeGreaterThan(0);
// Verify rate limit headers
const limitedResponse = rateLimited[0];
expect(limitedResponse.headers['x-ratelimit-limit']).toBeDefined();
expect(limitedResponse.headers['x-ratelimit-remaining']).toBeDefined();
expect(limitedResponse.headers['x-ratelimit-reset']).toBeDefined();
});
});
describe('Service Routing', () => {
test('should route to orchestrator service', async () => {
const campaign = await helpers.createTestCampaign();
const response = await apiClient.get(`/api/v1/campaigns/${campaign.campaignId}`);
const data = helpers.expectApiSuccess(response);
expect(data.campaign).toBeDefined();
expect(data.campaign.campaignId).toBe(campaign.campaignId);
});
test('should route to analytics service', async () => {
const response = await apiClient.get('/api/v1/analytics/metrics', {
params: {
startDate: new Date(Date.now() - 86400000).toISOString(),
endDate: new Date().toISOString()
}
});
const data = helpers.expectApiSuccess(response);
expect(data.metrics).toBeDefined();
});
test('should handle service unavailable', async () => {
// Try to access a non-existent service endpoint
const response = await apiClient.get('/api/v1/nonexistent/endpoint');
helpers.expectApiError(response, 404);
});
});
describe('CORS', () => {
test('should handle CORS preflight requests', async () => {
const axios = require('axios');
const response = await axios.options(`http://localhost:${API_GATEWAY_PORT}/api/v1/health`, {
headers: {
'Origin': 'http://localhost:3008',
'Access-Control-Request-Method': 'GET',
'Access-Control-Request-Headers': 'authorization'
},
validateStatus: () => true
});
expect(response.status).toBe(204);
expect(response.headers['access-control-allow-origin']).toBe('http://localhost:3008');
expect(response.headers['access-control-allow-methods']).toContain('GET');
expect(response.headers['access-control-allow-headers']).toContain('authorization');
});
test('should reject unauthorized origins', async () => {
const axios = require('axios');
const response = await axios.get(`http://localhost:${API_GATEWAY_PORT}/api/v1/health`, {
headers: {
'Origin': 'http://unauthorized.com'
},
validateStatus: () => true
});
expect(response.headers['access-control-allow-origin']).toBeUndefined();
});
});
describe('Error Handling', () => {
test('should handle validation errors', async () => {
const response = await apiClient.post('/api/v1/campaigns', {
// Missing required fields
name: 'Test Campaign'
});
helpers.expectApiError(response, 400);
expect(response.data.errors).toBeDefined();
});
test('should handle internal server errors gracefully', async () => {
// Force an error by sending invalid data type
const response = await apiClient.post('/api/v1/campaigns', 'invalid-data-type');
helpers.expectApiError(response, 400);
expect(response.data.error).toBeDefined();
});
});
describe('Health Checks', () => {
test('should return health status', async () => {
const response = await apiClient.get('/api/v1/health');
const data = helpers.expectApiSuccess(response);
expect(data.status).toBe('healthy');
expect(data.timestamp).toBeDefined();
expect(data.version).toBeDefined();
});
test('should return detailed service health', async () => {
const response = await apiClient.get('/api/v1/health/services');
const data = helpers.expectApiSuccess(response);
expect(data.services).toBeDefined();
expect(data.services['api-gateway']).toBeDefined();
expect(data.services['api-gateway'].status).toBe('healthy');
});
});
describe('Request Logging', () => {
test('should log requests with correlation ID', async () => {
const correlationId = 'test-correlation-' + Date.now();
const response = await apiClient.get('/api/v1/health', {
headers: {
'X-Correlation-ID': correlationId
}
});
helpers.expectApiSuccess(response);
expect(response.headers['x-correlation-id']).toBe(correlationId);
});
});
describe('API Versioning', () => {
test('should support multiple API versions', async () => {
// Test v1
const v1Response = await apiClient.get('/api/v1/health');
helpers.expectApiSuccess(v1Response);
// Test v2 (if implemented)
const v2Response = await apiClient.get('/api/v2/health');
if (v2Response.status === 200) {
const data = helpers.expectApiSuccess(v2Response);
expect(data.apiVersion).toBe('v2');
} else {
// v2 not implemented yet
expect(v2Response.status).toBe(404);
}
});
});
});