Files
wehub-resource-sync 9b395f5cc3
E2E Headed Chrome / e2e-headed (macos-15) (push) Has been cancelled
E2E Headed Chrome / e2e-headed (ubuntu-latest) (push) Has been cancelled
E2E Headed Chrome / e2e-headed (windows-latest) (push) Has been cancelled
CI / build (macos-latest) (push) Has been cancelled
CI / build (ubuntu-latest) (push) Has been cancelled
CI / build (windows-latest) (push) Has been cancelled
CI / unit-test (push) Has been cancelled
CI / bun-test (push) Has been cancelled
CI / adapter-test (push) Has been cancelled
CI / smoke-test (macos-latest) (push) Has been cancelled
CI / smoke-test (ubuntu-latest) (push) Has been cancelled
Security Audit / audit (push) Has been cancelled
Build Chrome Extension / build (push) Has been cancelled
Trigger Website Rebuild (Docs Updated) / dispatch (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:39:48 +08:00

244 lines
9.1 KiB
JavaScript

import { beforeEach, describe, expect, it, vi } from 'vitest';
const { mockReadPdfFile, mockRequestJson, mockUploadPresignedPdf, mockValidateHelpfulness, mockParseYesNo, } = vi.hoisted(() => ({
mockReadPdfFile: vi.fn(),
mockRequestJson: vi.fn(),
mockUploadPresignedPdf: vi.fn(),
mockValidateHelpfulness: vi.fn(),
mockParseYesNo: vi.fn(),
}));
vi.mock('./utils.js', async () => {
const actual = await vi.importActual('./utils.js');
return {
...actual,
readPdfFile: mockReadPdfFile,
requestJson: mockRequestJson,
uploadPresignedPdf: mockUploadPresignedPdf,
validateHelpfulness: mockValidateHelpfulness,
parseYesNo: mockParseYesNo,
};
});
import { getRegistry } from '@jackwener/opencli/registry';
import './submit.js';
import './review.js';
import './feedback.js';
describe('paperreview submit command', () => {
beforeEach(() => {
mockReadPdfFile.mockReset();
mockRequestJson.mockReset();
mockUploadPresignedPdf.mockReset();
mockValidateHelpfulness.mockReset();
mockParseYesNo.mockReset();
});
it('supports dry run without any remote request', async () => {
const cmd = getRegistry().get('paperreview/submit');
expect(cmd?.func).toBeTypeOf('function');
mockReadPdfFile.mockResolvedValue({
buffer: Buffer.from('%PDF'),
fileName: 'paper.pdf',
resolvedPath: '/tmp/paper.pdf',
sizeBytes: 4096,
});
const result = await cmd.func({
pdf: './paper.pdf',
email: 'wang2629651228@gmail.com',
venue: 'RAL',
'dry-run': true,
'prepare-only': false,
});
expect(mockRequestJson).not.toHaveBeenCalled();
expect(result).toMatchObject({
status: 'dry-run',
file: 'paper.pdf',
email: 'wang2629651228@gmail.com',
venue: 'RAL',
});
});
it('treats explicit false flags as false and performs the real submission path', async () => {
const cmd = getRegistry().get('paperreview/submit');
expect(cmd?.func).toBeTypeOf('function');
mockReadPdfFile.mockResolvedValue({
buffer: Buffer.from('%PDF'),
fileName: 'paper.pdf',
resolvedPath: '/tmp/paper.pdf',
sizeBytes: 4096,
});
mockRequestJson
.mockResolvedValueOnce({
response: { ok: true, status: 200 },
payload: {
success: true,
presigned_url: 'https://upload.example.com',
presigned_fields: { key: 'uploads/paper.pdf' },
s3_key: 'uploads/paper.pdf',
},
})
.mockResolvedValueOnce({
response: { ok: true, status: 200 },
payload: {
success: true,
token: 'tok_false',
message: 'Submission accepted',
},
});
const result = await cmd.func({
pdf: './paper.pdf',
email: 'wang2629651228@gmail.com',
venue: 'RAL',
'dry-run': false,
'prepare-only': false,
});
expect(mockUploadPresignedPdf).toHaveBeenCalledTimes(1);
expect(result).toMatchObject({
status: 'submitted',
token: 'tok_false',
review_url: 'https://paperreview.ai/review?token=tok_false',
});
});
it('supports prepare-only without uploading the PDF', async () => {
const cmd = getRegistry().get('paperreview/submit');
expect(cmd?.func).toBeTypeOf('function');
mockReadPdfFile.mockResolvedValue({
buffer: Buffer.from('%PDF'),
fileName: 'paper.pdf',
resolvedPath: '/tmp/paper.pdf',
sizeBytes: 4096,
});
mockRequestJson.mockResolvedValueOnce({
response: { ok: true, status: 200 },
payload: {
success: true,
presigned_url: 'https://upload.example.com',
presigned_fields: { key: 'uploads/paper.pdf' },
s3_key: 'uploads/paper.pdf',
},
});
const result = await cmd.func({
pdf: './paper.pdf',
email: 'wang2629651228@gmail.com',
venue: 'RAL',
'dry-run': false,
'prepare-only': true,
});
expect(mockUploadPresignedPdf).not.toHaveBeenCalled();
expect(mockRequestJson).toHaveBeenCalledTimes(1);
expect(result).toMatchObject({
status: 'prepared',
s3_key: 'uploads/paper.pdf',
});
});
it('requests an upload URL, uploads the PDF, and confirms the submission', async () => {
const cmd = getRegistry().get('paperreview/submit');
expect(cmd?.func).toBeTypeOf('function');
mockReadPdfFile.mockResolvedValue({
buffer: Buffer.from('%PDF'),
fileName: 'paper.pdf',
resolvedPath: '/tmp/paper.pdf',
sizeBytes: 4096,
});
mockRequestJson
.mockResolvedValueOnce({
response: { ok: true, status: 200 },
payload: {
success: true,
presigned_url: 'https://upload.example.com',
presigned_fields: { key: 'uploads/paper.pdf' },
s3_key: 'uploads/paper.pdf',
},
})
.mockResolvedValueOnce({
response: { ok: true, status: 200 },
payload: {
success: true,
token: 'tok_123',
message: 'Submission accepted',
},
});
const result = await cmd.func({
pdf: './paper.pdf',
email: 'wang2629651228@gmail.com',
venue: 'RAL',
'dry-run': false,
'prepare-only': false,
});
expect(mockRequestJson).toHaveBeenNthCalledWith(1, '/api/get-upload-url', expect.objectContaining({
method: 'POST',
body: JSON.stringify({
filename: 'paper.pdf',
venue: 'RAL',
}),
}));
expect(mockUploadPresignedPdf).toHaveBeenCalledWith('https://upload.example.com', expect.objectContaining({ fileName: 'paper.pdf' }), expect.objectContaining({ s3_key: 'uploads/paper.pdf' }));
expect(mockRequestJson).toHaveBeenNthCalledWith(2, '/api/confirm-upload', expect.objectContaining({
method: 'POST',
body: expect.any(FormData),
}));
expect(result).toMatchObject({
status: 'submitted',
token: 'tok_123',
review_url: 'https://paperreview.ai/review?token=tok_123',
});
});
});
describe('paperreview review command', () => {
beforeEach(() => {
mockRequestJson.mockReset();
});
it('returns processing status when the review is not ready yet', async () => {
const cmd = getRegistry().get('paperreview/review');
expect(cmd?.func).toBeTypeOf('function');
mockRequestJson.mockResolvedValue({
response: { status: 202 },
payload: { detail: 'Review is still processing.' },
});
const result = await cmd.func({ token: 'tok_123' });
expect(result).toMatchObject({
status: 'processing',
token: 'tok_123',
review_url: 'https://paperreview.ai/review?token=tok_123',
message: 'Review is still processing.',
});
});
});
describe('paperreview feedback command', () => {
beforeEach(() => {
mockRequestJson.mockReset();
mockValidateHelpfulness.mockReset();
mockParseYesNo.mockReset();
});
it('normalizes feedback inputs and posts them to the API', async () => {
const cmd = getRegistry().get('paperreview/feedback');
expect(cmd?.func).toBeTypeOf('function');
mockValidateHelpfulness.mockReturnValue(4);
mockParseYesNo.mockReturnValueOnce(true).mockReturnValueOnce(false);
mockRequestJson.mockResolvedValue({
response: { ok: true, status: 200 },
payload: { message: 'Thanks for the feedback.' },
});
const result = await cmd.func({
token: 'tok_123',
helpfulness: 4,
'critical-error': 'yes',
'actionable-suggestions': 'no',
'additional-comments': 'Helpful summary, but the contribution section needs more detail.',
});
expect(mockRequestJson).toHaveBeenCalledWith('/api/feedback/tok_123', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
helpfulness: 4,
has_critical_error: true,
has_actionable_suggestions: false,
additional_comments: 'Helpful summary, but the contribution section needs more detail.',
}),
});
expect(result).toMatchObject({
status: 'submitted',
token: 'tok_123',
helpfulness: 4,
critical_error: true,
actionable_suggestions: false,
message: 'Thanks for the feedback.',
});
});
});