add test data
This commit is contained in:
301
backend/scripts/analytics-test.ts
Normal file
301
backend/scripts/analytics-test.ts
Normal file
@@ -0,0 +1,301 @@
|
||||
import axios from 'axios';
|
||||
import dotenv from 'dotenv';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
// 加载 .env 文件
|
||||
dotenv.config();
|
||||
|
||||
const API_URL = `http://localhost:${process.env.PORT || 4000}/api`;
|
||||
let authToken: string;
|
||||
|
||||
// 测试数据
|
||||
const testData = {
|
||||
influencerId: '20000000-0000-0000-0000-000000000003',
|
||||
postId: '30000000-0000-0000-0000-000000000006',
|
||||
projectId: '10000000-0000-0000-0000-000000000001'
|
||||
};
|
||||
|
||||
// 测试账号信息
|
||||
const testAccount = {
|
||||
email: 'vitalitymailg@gmail.com',
|
||||
password: 'password123'
|
||||
};
|
||||
|
||||
// 设置请求客户端
|
||||
const apiClient = axios.create({
|
||||
baseURL: API_URL,
|
||||
timeout: 10000,
|
||||
validateStatus: () => true // 不抛出HTTP错误
|
||||
});
|
||||
|
||||
// 设置请求拦截器添加令牌
|
||||
apiClient.interceptors.request.use(config => {
|
||||
if (authToken) {
|
||||
config.headers.Authorization = `Bearer ${authToken}`;
|
||||
}
|
||||
return config;
|
||||
});
|
||||
|
||||
// 登录并获取令牌
|
||||
async function login() {
|
||||
try {
|
||||
console.log('🔑 登录获取认证令牌...');
|
||||
console.log(`使用账号: ${testAccount.email}`);
|
||||
|
||||
const response = await apiClient.post('/auth/login', {
|
||||
email: testAccount.email,
|
||||
password: testAccount.password
|
||||
});
|
||||
|
||||
console.log(`登录响应状态码: ${response.status}`);
|
||||
|
||||
// 根据实际响应结构调整获取token的逻辑
|
||||
if (response.status !== 200) {
|
||||
throw new Error(`登录失败: ${JSON.stringify(response.data)}`);
|
||||
}
|
||||
|
||||
// 默认假设响应中包含 access_token 或 token 字段
|
||||
if (response.data.access_token) {
|
||||
authToken = response.data.access_token;
|
||||
} else if (response.data.token) {
|
||||
authToken = response.data.token;
|
||||
} else if (response.data.data?.session?.access_token) {
|
||||
// Supabase 可能返回嵌套在 data.session 中的 token
|
||||
authToken = response.data.data.session.access_token;
|
||||
} else {
|
||||
console.log('警告: 响应中没有找到明确的 token 字段,尝试直接使用响应数据...');
|
||||
console.log('响应结构:', JSON.stringify(response.data, null, 2));
|
||||
|
||||
// 如果找不到标准字段,则尝试其他可能的位置
|
||||
authToken = response.data;
|
||||
}
|
||||
|
||||
if (!authToken) {
|
||||
throw new Error('未能从响应中提取认证令牌');
|
||||
}
|
||||
|
||||
console.log('✅ 登录成功,获取到令牌');
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('❌ 登录失败:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 测试网红指标追踪接口
|
||||
async function testInfluencerTrack() {
|
||||
try {
|
||||
console.log('\n🧪 测试网红指标追踪接口...');
|
||||
const response = await apiClient.post('/analytics/influencer/track', {
|
||||
influencer_id: testData.influencerId,
|
||||
metrics: {
|
||||
followers_count: 50000,
|
||||
video_count: 120,
|
||||
views_count: 1500000,
|
||||
likes_count: 300000
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`状态码: ${response.status}`);
|
||||
console.log('响应数据:', JSON.stringify(response.data, null, 2));
|
||||
|
||||
return response.status === 200;
|
||||
} catch (error) {
|
||||
console.error('测试失败:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 测试内容指标追踪接口
|
||||
async function testContentTrack() {
|
||||
try {
|
||||
console.log('\n🧪 测试内容指标追踪接口...');
|
||||
const response = await apiClient.post('/analytics/content/track', {
|
||||
post_id: testData.postId,
|
||||
metrics: {
|
||||
views_count: 5000,
|
||||
likes_count: 500,
|
||||
comments_count: 50,
|
||||
shares_count: 20
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`状态码: ${response.status}`);
|
||||
console.log('响应数据:', JSON.stringify(response.data, null, 2));
|
||||
|
||||
return response.status === 200;
|
||||
} catch (error) {
|
||||
console.error('测试失败:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 测试网红增长趋势接口
|
||||
async function testInfluencerGrowth() {
|
||||
try {
|
||||
console.log('\n🧪 测试网红增长趋势接口...');
|
||||
const response = await apiClient.get(`/analytics/influencer/${testData.influencerId}/growth`, {
|
||||
params: {
|
||||
metric: 'followers_count',
|
||||
timeframe: '6months',
|
||||
interval: 'month'
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`状态码: ${response.status}`);
|
||||
console.log('响应数据样例 (仅显示部分):', JSON.stringify({
|
||||
...response.data,
|
||||
data: response.data.data?.slice(0, 2) || []
|
||||
}, null, 2));
|
||||
|
||||
return response.status === 200;
|
||||
} catch (error) {
|
||||
console.error('测试失败:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 测试内容互动趋势接口
|
||||
async function testContentTrends() {
|
||||
try {
|
||||
console.log('\n🧪 测试内容互动趋势接口...');
|
||||
const response = await apiClient.get(`/analytics/content/${testData.postId}/trends`, {
|
||||
params: {
|
||||
metric: 'views_count',
|
||||
timeframe: '30days',
|
||||
interval: 'day'
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`状态码: ${response.status}`);
|
||||
console.log('响应数据样例 (仅显示部分):', JSON.stringify({
|
||||
...response.data,
|
||||
data: response.data.data?.slice(0, 2) || []
|
||||
}, null, 2));
|
||||
|
||||
return response.status === 200;
|
||||
} catch (error) {
|
||||
console.error('测试失败:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 测试项目概览接口
|
||||
async function testProjectOverview() {
|
||||
try {
|
||||
console.log('\n🧪 测试项目概览接口...');
|
||||
const response = await apiClient.get(`/analytics/project/${testData.projectId}/overview`, {
|
||||
params: {
|
||||
timeframe: '30days'
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`状态码: ${response.status}`);
|
||||
console.log('响应数据样例 (仅显示部分):', JSON.stringify({
|
||||
project: response.data.project,
|
||||
timeframe: response.data.timeframe,
|
||||
metrics: response.data.metrics,
|
||||
platforms: response.data.platforms,
|
||||
timeline: response.data.timeline?.slice(0, 2) || []
|
||||
}, null, 2));
|
||||
|
||||
return response.status === 200;
|
||||
} catch (error) {
|
||||
console.error('测试失败:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 测试项目表现最佳网红接口
|
||||
async function testProjectTopPerformers() {
|
||||
try {
|
||||
console.log('\n🧪 测试项目表现最佳网红接口...');
|
||||
const response = await apiClient.get(`/analytics/project/${testData.projectId}/top-performers`, {
|
||||
params: {
|
||||
metric: 'views_count',
|
||||
limit: '5',
|
||||
timeframe: '30days'
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`状态码: ${response.status}`);
|
||||
console.log('响应数据样例 (仅显示部分):', JSON.stringify({
|
||||
project_id: response.data.project_id,
|
||||
metric: response.data.metric,
|
||||
timeframe: response.data.timeframe,
|
||||
top_performers: response.data.top_performers?.slice(0, 2) || []
|
||||
}, null, 2));
|
||||
|
||||
return response.status === 200;
|
||||
} catch (error) {
|
||||
console.error('测试失败:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 测试项目报告导出接口
|
||||
async function testProjectReport() {
|
||||
try {
|
||||
console.log('\n🧪 测试项目报告接口...');
|
||||
const response = await apiClient.get(`/analytics/reports/project/${testData.projectId}`, {
|
||||
params: {
|
||||
timeframe: '30days',
|
||||
format: 'json'
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`状态码: ${response.status}`);
|
||||
console.log('响应数据样例 (仅显示部分):', JSON.stringify({
|
||||
report_type: response.data.report_type,
|
||||
generated_at: response.data.generated_at,
|
||||
project: response.data.project,
|
||||
summary: response.data.summary
|
||||
}, null, 2));
|
||||
|
||||
return response.status === 200;
|
||||
} catch (error) {
|
||||
console.error('测试失败:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 运行所有测试
|
||||
async function runTests() {
|
||||
console.log('🚀 开始 Analytics 接口测试...\n');
|
||||
|
||||
// 获取认证令牌
|
||||
const loginSuccess = await login();
|
||||
if (!loginSuccess) {
|
||||
console.error('由于登录失败,测试中止');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// 运行测试用例
|
||||
const results = {
|
||||
influencerTrack: await testInfluencerTrack(),
|
||||
contentTrack: await testContentTrack(),
|
||||
influencerGrowth: await testInfluencerGrowth(),
|
||||
contentTrends: await testContentTrends(),
|
||||
projectOverview: await testProjectOverview(),
|
||||
projectTopPerformers: await testProjectTopPerformers(),
|
||||
projectReport: await testProjectReport()
|
||||
};
|
||||
|
||||
// 显示测试结果摘要
|
||||
console.log('\n📊 测试结果摘要:');
|
||||
|
||||
for (const [test, passed] of Object.entries(results)) {
|
||||
console.log(`${passed ? '✅' : '❌'} ${test}`);
|
||||
}
|
||||
|
||||
const totalTests = Object.keys(results).length;
|
||||
const passedTests = Object.values(results).filter(Boolean).length;
|
||||
|
||||
console.log(`\n总结: ${passedTests}/${totalTests} 测试通过`);
|
||||
}
|
||||
|
||||
// 执行测试
|
||||
runTests().catch(error => {
|
||||
console.error('测试过程中发生错误:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user