Skip to content

test: add qs arrayLimit regression coverage for #9672#9680

Open
b0a7 wants to merge 1 commit into
ChainSafe:unstablefrom
b0a7:b0a7/query-string-arraylimit-coverage
Open

test: add qs arrayLimit regression coverage for #9672#9680
b0a7 wants to merge 1 commit into
ChainSafe:unstablefrom
b0a7:b0a7/query-string-arraylimit-coverage

Conversation

@b0a7

@b0a7 b0a7 commented Jul 18, 2026

Copy link
Copy Markdown

Motivation

Unit tests did not catch issue #9672 (which was fixed in #9673), and still don't after the fix. Production code and the API test harness each configured qs separately, and existing tests never sent query arrays longer than the qs default arrayLimit of 20.

Description

  • Share one parseRestQueryString between production (RestApiServer) and the API test server
  • Enforce Beacon API maxItems in route schemas (validator id: 64; data-column indices: NUMBER_OF_COLUMNS)
  • Add exhaustive unit coverage for accepted and rejected array lengths

Evidence (local): issue9672_ut.zip

  1. On the pre-refactor fix commit, disable production qs arrayLimit only → original generic-server UTs still PASS
  2. On this PR, disable shared qs arrayLimit → new limit suite FAILS
  3. this PR code → new limit suite PASSES

Test plan

  • @lodestar/api unit tests, including queryStringArrayLimits.test.ts
  • CI lint / check-types / unit

AI Assistance Disclosure

This PR was written primarily by Cursor.

Share the REST querystring parser between production and tests, enforce
Beacon API maxItems in route schemas, and add exhaustive array-limit tests
so this class of regression is caught in unit tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
@b0a7
b0a7 requested a review from a team as a code owner July 18, 2026 16:05

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request centralizes and standardizes REST query string array parsing and validation limits. It introduces specific schema types (UintArrayMaxColumns and UintOrStringArrayMax64) to enforce maximum item limits on query parameters like validator IDs and data-column indices. Additionally, it extracts the query string parsing logic into a shared helper parseRestQueryString and removes redundant qs dependencies from beacon-node. Feedback on this PR suggests optimizing the new unit tests by testing representative boundary values instead of generating every single integer up to the maximum limit, which avoids running hundreds of sequential HTTP injections and speeds up the test suite.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +38 to +40
function lengthsUpTo(max: number): number[] {
return Array.from({length: max}, (_, i) => i + 1);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using lengthsUpTo to generate every single integer up to 64 and 128 results in 384 individual test cases. Since each test case spins up a Fastify instance and performs an HTTP injection (server.inject), running hundreds of these sequentially can significantly slow down the unit test suite. Instead of testing every single length, we can test representative boundary values (e.g., 1, 2, the default qs limit 20, 21, max - 1, and max). This maintains the same level of confidence and coverage while reducing the test count from 384 to 24, making the test suite much faster and more efficient.

Suggested change
function lengthsUpTo(max: number): number[] {
return Array.from({length: max}, (_, i) => i + 1);
}
function lengthsUpTo(max: number): number[] {
return Array.from(new Set([1, 2, 20, 21, max - 1, max])).filter((n) => n > 0 && n <= max);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants