fix(xiaoyuzhou): validate limits and tighten e2e

This commit is contained in:
jackwener committed 2026-03-18 16:38:09 +08:00
1 parent 5e667b9c2f
commit bde1c53a3e
2 files changed
+38 -7

No files matched your search

+5 -1
View File
@@ -19,7 +19,11 @@ cli({
const podcast = pageProps.podcast;
if (!podcast) throw new CliError('NOT_FOUND', 'Podcast not found', 'Please check the ID');
const allEpisodes = podcast.episodes ?? [];
const limit = Math.max(1, Math.min(Number(args.limit) ?? 15, allEpisodes.length));
const requestedLimit = Number(args.limit);
if (!Number.isInteger(requestedLimit) || requestedLimit < 1) {
throw new CliError('INVALID_ARGUMENT', 'limit must be a positive integer', 'Example: --limit 5');
}
const limit = Math.min(requestedLimit, allEpisodes.length);
const episodes = allEpisodes.slice(0, limit);
return episodes.map((ep: any) => ({
eid: ep.eid,
+33 -6
View File
@@ -6,6 +6,11 @@
import { describe, it, expect } from 'vitest';
import { runCli, parseJsonOutput } from './helpers.js';
function isExpectedXiaoyuzhouRestriction(code: number, stderr: string): boolean {
if (code === 0) return false;
return /Error \[FETCH_ERROR\]: HTTP (403|429|451|503)\b/.test(stderr);
}
describe('public commands E2E', () => {
// ── hackernews ──
it('hackernews top returns structured data', async () => {
@@ -56,8 +61,12 @@ describe('public commands E2E', () => {
// ── xiaoyuzhou (Chinese site — may return empty on overseas CI runners) ──
it('xiaoyuzhou podcast returns podcast profile', async () => {
const { stdout, code } = await runCli(['xiaoyuzhou', 'podcast', '6013f9f58e2f7ee375cf4216', '-f', 'json']);
if (code !== 0) { console.warn('xiaoyuzhou podcast skipped (geo-blocked?)'); return; }
const { stdout, stderr, code } = await runCli(['xiaoyuzhou', 'podcast', '6013f9f58e2f7ee375cf4216', '-f', 'json']);
if (isExpectedXiaoyuzhouRestriction(code, stderr)) {
console.warn(`xiaoyuzhou podcast skipped: ${stderr.trim()}`);
return;
}
expect(code).toBe(0);
const data = parseJsonOutput(stdout);
expect(Array.isArray(data)).toBe(true);
expect(data.length).toBe(1);
@@ -67,8 +76,12 @@ describe('public commands E2E', () => {
}, 30_000);
it('xiaoyuzhou podcast-episodes returns episode list', async () => {
const { stdout, code } = await runCli(['xiaoyuzhou', 'podcast-episodes', '6013f9f58e2f7ee375cf4216', '-f', 'json']);
if (code !== 0) { console.warn('xiaoyuzhou podcast-episodes skipped (geo-blocked?)'); return; }
const { stdout, stderr, code } = await runCli(['xiaoyuzhou', 'podcast-episodes', '6013f9f58e2f7ee375cf4216', '-f', 'json']);
if (isExpectedXiaoyuzhouRestriction(code, stderr)) {
console.warn(`xiaoyuzhou podcast-episodes skipped: ${stderr.trim()}`);
return;
}
expect(code).toBe(0);
const data = parseJsonOutput(stdout);
expect(Array.isArray(data)).toBe(true);
expect(data.length).toBeGreaterThanOrEqual(1);
@@ -78,8 +91,12 @@ describe('public commands E2E', () => {
}, 30_000);
it('xiaoyuzhou episode returns episode detail', async () => {
const { stdout, code } = await runCli(['xiaoyuzhou', 'episode', '69b3b675772ac2295bfc01d0', '-f', 'json']);
if (code !== 0) { console.warn('xiaoyuzhou episode skipped (geo-blocked?)'); return; }
const { stdout, stderr, code } = await runCli(['xiaoyuzhou', 'episode', '69b3b675772ac2295bfc01d0', '-f', 'json']);
if (isExpectedXiaoyuzhouRestriction(code, stderr)) {
console.warn(`xiaoyuzhou episode skipped: ${stderr.trim()}`);
return;
}
expect(code).toBe(0);
const data = parseJsonOutput(stdout);
expect(Array.isArray(data)).toBe(true);
expect(data.length).toBe(1);
@@ -88,4 +105,14 @@ describe('public commands E2E', () => {
expect(data[0]).toHaveProperty('plays');
expect(data[0]).toHaveProperty('comments');
}, 30_000);
it('xiaoyuzhou podcast-episodes rejects invalid limit', async () => {
const { stderr, code } = await runCli(['xiaoyuzhou', 'podcast-episodes', '6013f9f58e2f7ee375cf4216', '--limit', 'abc', '-f', 'json']);
if (isExpectedXiaoyuzhouRestriction(code, stderr)) {
console.warn(`xiaoyuzhou invalid-limit skipped: ${stderr.trim()}`);
return;
}
expect(code).not.toBe(0);
expect(stderr).toMatch(/limit must be a positive integer|Argument "limit" must be a valid number/);
}, 30_000);
});