196 lines
5.0 KiB
JavaScript
196 lines
5.0 KiB
JavaScript
const http = require('http');
|
|
|
|
// 简单的 HTTP 客户端来处理 cookies
|
|
class SimpleAPITester {
|
|
constructor(baseUrl) {
|
|
this.baseUrl = baseUrl;
|
|
this.cookies = new Map();
|
|
}
|
|
|
|
async request(path, options = {}) {
|
|
return new Promise((resolve, reject) => {
|
|
const url = new URL(path, this.baseUrl);
|
|
const opts = {
|
|
hostname: url.hostname,
|
|
port: url.port,
|
|
path: url.pathname + url.search,
|
|
method: options.method || 'GET',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
...options.headers
|
|
}
|
|
};
|
|
|
|
// 添加 cookies
|
|
if (this.cookies.size > 0) {
|
|
opts.headers.Cookie = Array.from(this.cookies.entries())
|
|
.map(([k, v]) => `${k}=${v}`)
|
|
.join('; ');
|
|
}
|
|
|
|
const req = http.request(opts, (res) => {
|
|
let data = '';
|
|
res.on('data', chunk => data += chunk);
|
|
res.on('end', () => {
|
|
// 保存 cookies
|
|
if (res.headers['set-cookie']) {
|
|
res.headers['set-cookie'].forEach(cookie => {
|
|
const [nameValue] = cookie.split(';');
|
|
const [name, value] = nameValue.split('=');
|
|
if (name && value) {
|
|
this.cookies.set(name.trim(), value.trim());
|
|
}
|
|
});
|
|
}
|
|
|
|
try {
|
|
const json = JSON.parse(data);
|
|
resolve({ status: res.statusCode, data: json, headers: res.headers });
|
|
} catch {
|
|
resolve({ status: res.statusCode, data, headers: res.headers });
|
|
}
|
|
});
|
|
});
|
|
|
|
req.on('error', reject);
|
|
|
|
if (options.body) {
|
|
req.write(JSON.stringify(options.body));
|
|
}
|
|
|
|
req.end();
|
|
});
|
|
}
|
|
|
|
async register(email, password, name) {
|
|
console.log('📝 注册用户...');
|
|
const response = await this.request('/api/auth/register', {
|
|
method: 'POST',
|
|
body: { email, password, name }
|
|
});
|
|
console.log(`状态: ${response.status}`);
|
|
console.log(response.data);
|
|
return response;
|
|
}
|
|
|
|
async getCSRFToken() {
|
|
console.log('🔐 获取 CSRF token...');
|
|
const response = await this.request('/api/auth/signin');
|
|
const csrfCookie = this.cookies.get('next-auth.csrf-token');
|
|
if (csrfCookie) {
|
|
const [token] = csrfCookie.split('|');
|
|
return token;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
async login(email, password) {
|
|
console.log('🔑 登录...');
|
|
const csrfToken = await this.getCSRFToken();
|
|
|
|
if (!csrfToken) {
|
|
throw new Error('无法获取 CSRF token');
|
|
}
|
|
|
|
const response = await this.request('/api/auth/signin', {
|
|
method: 'POST',
|
|
body: {
|
|
email,
|
|
password,
|
|
csrfToken,
|
|
redirect: false
|
|
}
|
|
});
|
|
|
|
return response;
|
|
}
|
|
|
|
async createTree(name, description) {
|
|
console.log('🌳 创建家族树...');
|
|
const response = await this.request('/api/trees', {
|
|
method: 'POST',
|
|
body: { name, description }
|
|
});
|
|
console.log(`状态: ${response.status}`);
|
|
console.log(response.data);
|
|
return response;
|
|
}
|
|
|
|
async getTrees() {
|
|
console.log('📋 获取家族树列表...');
|
|
const response = await this.request('/api/trees');
|
|
console.log(`状态: ${response.status}`);
|
|
console.log(JSON.stringify(response.data, null, 2));
|
|
return response;
|
|
}
|
|
|
|
async createMember(treeId, memberData) {
|
|
console.log('👤 创建成员...');
|
|
const response = await this.request(`/api/trees/${treeId}/members`, {
|
|
method: 'POST',
|
|
body: memberData
|
|
});
|
|
console.log(`状态: ${response.status}`);
|
|
console.log(response.data);
|
|
return response;
|
|
}
|
|
|
|
async getMembers(treeId) {
|
|
console.log('👥 获取成员列表...');
|
|
const response = await this.request(`/api/trees/${treeId}/members`);
|
|
console.log(`状态: ${response.status}`);
|
|
console.log(JSON.stringify(response.data, null, 2));
|
|
return response;
|
|
}
|
|
}
|
|
|
|
async function runTests() {
|
|
const tester = new SimpleAPITester('http://localhost:3000');
|
|
|
|
try {
|
|
console.log('🚀 开始完整 API 测试...\n');
|
|
|
|
// 1. 注册用户
|
|
await tester.register('api-test@example.com', 'password123', 'API测试用户');
|
|
console.log('');
|
|
|
|
// 2. 登录
|
|
await tester.login('api-test@example.com', 'password123');
|
|
console.log('');
|
|
|
|
// 3. 创建家族树
|
|
const treeResponse = await tester.createTree('API测试家族树', '通过API创建');
|
|
console.log('');
|
|
|
|
if (treeResponse.status === 201) {
|
|
const treeId = treeResponse.data.tree.id;
|
|
|
|
// 4. 获取家族树列表
|
|
await tester.getTrees();
|
|
console.log('');
|
|
|
|
// 5. 创建成员
|
|
await tester.createMember(treeId, {
|
|
surname: '李',
|
|
givenName: '明',
|
|
fullName: '李明',
|
|
gender: 'MALE',
|
|
generation: 1,
|
|
birthDate: '1990-01-01'
|
|
});
|
|
console.log('');
|
|
|
|
// 6. 获取成员列表
|
|
await tester.getMembers(treeId);
|
|
console.log('');
|
|
}
|
|
|
|
console.log('✅ 所有测试完成!');
|
|
|
|
} catch (error) {
|
|
console.error('❌ 测试失败:', error);
|
|
}
|
|
}
|
|
|
|
runTests();
|