160 lines
5.5 KiB
JavaScript
160 lines
5.5 KiB
JavaScript
'use strict';
|
|
|
|
const assert = require('assert');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const vm = require('vm');
|
|
const db = require('../src/core/database');
|
|
const accountsRouter = require('../src/routes/accounts');
|
|
|
|
function routeHandler(routePath) {
|
|
const layer = accountsRouter.stack.find(item => (
|
|
item.route
|
|
&& item.route.path === routePath
|
|
&& item.route.methods.get
|
|
));
|
|
assert(layer, `未找到 GET ${routePath}`);
|
|
return layer.route.stack[0].handle;
|
|
}
|
|
|
|
function invoke(handler, params = {}, remoteAddress = '127.0.0.1') {
|
|
const response = {
|
|
statusCode: 200,
|
|
headers: {},
|
|
body: null,
|
|
status(code) {
|
|
this.statusCode = code;
|
|
return this;
|
|
},
|
|
set(name, value) {
|
|
this.headers[String(name).toLowerCase()] = value;
|
|
return this;
|
|
},
|
|
json(body) {
|
|
this.body = body;
|
|
return this;
|
|
},
|
|
};
|
|
handler({ params, socket: { remoteAddress } }, response);
|
|
return response;
|
|
}
|
|
|
|
(async () => {
|
|
const originalGetAccount = db.getAccount;
|
|
const originalGetAllAccounts = db.getAllAccounts;
|
|
const originalGetStagingBatch = db.getStagingBatch;
|
|
try {
|
|
const session = {
|
|
user: { email: 'session@example.com' },
|
|
expires: '2099-01-01T00:00:00.000Z',
|
|
accessToken: 'test-token',
|
|
};
|
|
const account = {
|
|
email: 'session@example.com',
|
|
chatgpt_status: '已登录',
|
|
chatgpt_session: JSON.stringify(session),
|
|
};
|
|
db.getAccount = () => account;
|
|
db.getAllAccounts = () => [account];
|
|
|
|
const listResponse = invoke(routeHandler('/'));
|
|
assert.strictEqual(listResponse.statusCode, 200);
|
|
assert.strictEqual(listResponse.body.data[0].chatgpt_session, undefined, '账号列表不得返回 Session');
|
|
|
|
const sessionResponse = invoke(routeHandler('/:email/chatgpt-session'), {
|
|
email: encodeURIComponent(account.email),
|
|
});
|
|
assert.strictEqual(sessionResponse.statusCode, 200);
|
|
assert.strictEqual(sessionResponse.headers['cache-control'], 'no-store');
|
|
assert.deepStrictEqual(sessionResponse.body.data, session);
|
|
|
|
const remoteSessionResponse = invoke(routeHandler('/:email/chatgpt-session'), {
|
|
email: encodeURIComponent(account.email),
|
|
}, '192.0.2.10');
|
|
assert.strictEqual(remoteSessionResponse.statusCode, 403);
|
|
assert.strictEqual(remoteSessionResponse.headers['cache-control'], 'no-store');
|
|
assert.strictEqual(JSON.stringify(remoteSessionResponse.body).includes('test-token'), false);
|
|
|
|
db.getStagingBatch = () => ({
|
|
batch: { id: 1, selected_fields: JSON.stringify(['email', 'chatgpt_session']) },
|
|
accounts: [account],
|
|
});
|
|
const stagedWithSession = invoke(routeHandler('/staging/:batchId'), { batchId: '1' });
|
|
assert.strictEqual(stagedWithSession.body.data.accounts[0].chatgpt_session, account.chatgpt_session);
|
|
const remoteStagedWithSession = invoke(
|
|
routeHandler('/staging/:batchId'),
|
|
{ batchId: '1' },
|
|
'192.0.2.10',
|
|
);
|
|
assert.strictEqual(remoteStagedWithSession.statusCode, 403);
|
|
assert.strictEqual(JSON.stringify(remoteStagedWithSession.body).includes('test-token'), false);
|
|
|
|
db.getStagingBatch = () => ({
|
|
batch: { id: 2, selected_fields: JSON.stringify(['email']) },
|
|
accounts: [account],
|
|
});
|
|
const stagedWithoutSession = invoke(routeHandler('/staging/:batchId'), { batchId: '2' });
|
|
assert.strictEqual(stagedWithoutSession.body.data.accounts[0].chatgpt_session, undefined);
|
|
|
|
db.getAccount = () => ({ email: account.email, chatgpt_session: null });
|
|
const emptyResponse = invoke(routeHandler('/:email/chatgpt-session'), {
|
|
email: encodeURIComponent(account.email),
|
|
});
|
|
assert.strictEqual(emptyResponse.statusCode, 404);
|
|
assert.match(emptyResponse.body.msg, /尚未保存/);
|
|
|
|
const appSource = fs.readFileSync(path.join(__dirname, '..', 'public', 'app.js'), 'utf8');
|
|
let clipboardText = '';
|
|
const context = vm.createContext({
|
|
console,
|
|
Set,
|
|
Map,
|
|
Date,
|
|
JSON,
|
|
Math,
|
|
String,
|
|
Object,
|
|
Array,
|
|
RegExp,
|
|
setTimeout,
|
|
clearTimeout,
|
|
navigator: {
|
|
clipboard: {
|
|
writeText: async text => { clipboardText = text; },
|
|
},
|
|
},
|
|
fetch: async () => ({
|
|
ok: true,
|
|
status: 200,
|
|
json: async () => ({ success: true, data: session }),
|
|
}),
|
|
});
|
|
vm.runInContext(`${appSource}\nthis.__geminiApp = geminiApp;`, context, { filename: 'public/app.js' });
|
|
const app = context.__geminiApp();
|
|
await app.openChatgptSession(account);
|
|
assert.strictEqual(app.showChatgptSessionModal, true);
|
|
assert.strictEqual(app.chatgptSessionLoading, false);
|
|
assert.strictEqual(JSON.parse(app.chatgptSessionText).user.email, account.email);
|
|
await app.copyChatgptSession();
|
|
assert.strictEqual(clipboardText, app.chatgptSessionText);
|
|
|
|
app._exportList = [{ email: account.email }];
|
|
Object.keys(app.exportFields).forEach(key => { app.exportFields[key] = false; });
|
|
app.exportFields.email = true;
|
|
app.exportFields.chatgpt_session = true;
|
|
app.exportMode = { file: false, clipboard: true, staging: false };
|
|
app.addLog = () => {};
|
|
await app.confirmExport();
|
|
assert.strictEqual(clipboardText, `${account.email}----${JSON.stringify(session)}`);
|
|
|
|
console.log('chatgpt_session_access.test.js: PASS');
|
|
} finally {
|
|
db.getAccount = originalGetAccount;
|
|
db.getAllAccounts = originalGetAllAccounts;
|
|
db.getStagingBatch = originalGetStagingBatch;
|
|
}
|
|
})().catch(error => {
|
|
console.error(error);
|
|
process.exitCode = 1;
|
|
});
|