Testing scope Review and Recommendations #60
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Current Coverage Profile
Technical Analysis of Gaps
1. Absence of Ombi Integration Tests
Technical Requirement:
Ombi integration involves request enrichment (
decorateRequestsWithArrLinks), webhook processing, and cross-service linking between Ombi and *arr applications. These flows contain multiple conditional branches based on media type, ID variants, and admin status.Current Gap:
Zero dedicated integration tests exist for this subsystem despite its complexity and recent changes.
Technical Implication:
Without integration-level tests exercising the full request → enrichment → link generation pipeline, regression protection for this integration is absent. This reduces confidence in changes affecting ID extraction logic (
theTvDbId,tvDbId,theMovieDbId, etc.) and admin link generation.Recommendation:
Create a dedicated integration test suite (
tests/integration/ombi.test.js) covering:decorateRequestsWithArrLinksbehavior across movie/TV cases2. Untested Background Polling Engine
Technical Requirement:
The poller (
server/utils/poller.js) is responsible for periodic data aggregation from multiple external services, managing concurrency via apollingguard, notifying SSE subscribers, and handling graceful shutdown. It forms the backbone of the real-time dashboard behavior.Current Gap:
No unit or integration tests cover this component.
Technical Implication:
Key behaviors such as concurrent execution prevention, subscriber notification, error recovery paths, and interval-based scheduling remain unverified. This creates a blind spot in testing the system's core data freshness mechanism.
Recommendation:
Implement unit tests for
poller.jsfocusing on:pollingflag behavior)onPollComplete/offPollComplete)pollAllServicesPOLL_INTERVALconfigurations3. Exclusion of SSE Endpoint from Testing
Technical Requirement:
The
/api/dashboard/streamendpoint implements Server-Sent Events for real-time push updates. It is central to the application's stated real-time capabilities and interacts directly with the poller.Current Gap:
This endpoint is intentionally excluded from the test suite.
Technical Implication:
There is no automated verification of event emission timing, client connection lifecycle, proper cleanup on disconnect, or correct payload formatting for different event types (downloads, history, requests).
Recommendation:
Add integration tests for the SSE endpoint that verify:
4. Limited Coverage of Rate Limiting and Error Scenarios
Technical Requirement:
Production rate limiting and external service error handling (timeouts, 5xx responses, rate limit responses) are critical for system stability when interacting with Sonarr, Radarr, Ombi, and download clients.
Current Gap:
Most integration tests bypass rate limiting via
SKIP_RATE_LIMIT. There is minimal coverage of failure modes usingnock.Technical Implication:
The test suite does not exercise the system's resilience characteristics under load or external service degradation.
Recommendation:
SKIP_RATE_LIMITin integration testsnockfor:5. Insufficient Frontend Component Coverage
Technical Requirement:
The frontend renders dynamic UI elements based on data properties such as
arrType,arrLink,isAdmin,movieName, andseriesName. Conditional rendering logic directly affects user-facing features (e.g., service icons and deep links).Current Gap:
Coverage of
client/src/ui/downloads.jsand related components is low, with limited testing of conditional rendering paths.Technical Implication:
Changes to rendering logic for admin features or media-type differentiation carry higher regression risk without targeted component tests.
Recommendation:
Add Vitest + jsdom tests for:
createServiceIconsfunction and its conditional logicarrTypeandarrLinkmovieName) and series (seriesName) contentRecommended Coverage Targets
Based on the architectural characteristics of the system (real-time event-driven flows, multiple external integrations, admin-only features), the following targets are recommended:
These targets should be enforced via CI and reviewed periodically as new features are added.
Prioritized Action Plan
Phase 1 (Immediate)
Phase 2 (Short Term)
Phase 3 (Ongoing)
Conclusion
Effective test coverage for this system requires deliberate focus on the real-time, integration-heavy, and conditionally-rendered aspects of the architecture. The recommendations above are designed to align test scope with the technical requirements of background processing, external service resilience, and dynamic UI behavior.
Implementation of these improvements will provide stronger regression protection and greater confidence in the correctness of core system behaviors.
Implementation plan:
Implementation Plan - Issue #60 Testing Scope Review
This plan addresses the test coverage recommendations outlined in Issue #60. After performing a detailed analysis of the repository's existing test suites, we have discovered that several of the gaps claimed in the issue are already addressed in the codebase, while others are highly valid.
This plan presents our technical analysis, clarifies the discrepancies, and outlines a precise roadmap to implement the actual missing coverage.
Technical Analysis of Gaps
We compared the claims made in Issue #60 with the current state of the codebase. Here is our assessment:
1. Absence of Ombi Integration Tests
showAllparams, TV requests decoration withtvDbId(Issue #58), webhook status/enable/test routes, API errors, and local loopback fallbacks.2. Untested Background Polling Engine
tests/unit/utils/poller.test.jsto cover its core behaviors.3. Exclusion of SSE Endpoint from Testing
/api/dashboard/streamactually exist at the bottom of dashboard.test.js. They verify that the stream properly initializes, outputs correctly formatted SSE data, and honors theshowAlladmin parameter (utilizing atestClose=trueparameter to terminate the connection gracefully after the initial payload).tests/integration/dashboard.test.jsexercising connection termination cleanup (req.on('close')) to verify it successfully deregisters callbacks and prevents memory leaks.4. Limited Coverage of Rate Limiting and Error Scenarios
SKIP_RATE_LIMIT = '1'globally in setup.js to prevent test runners from exhausting the API limits from a single localhost origin.tests/integration/rateLimiter.test.jsthat explicitly clears/overridesprocess.env.SKIP_RATE_LIMITand makes sequential requests to verify that the rate limiter triggers (returns 429) as expected.5. Insufficient Frontend Component Coverage
renderTagBadges(). Key DOM construction functions likecreateServiceIcons()(conditionally rendering Sonarr/Radarr/Ombi deep-links based onarrType,arrLink, andstate.isAdmin) are untested.tests/frontend/ui/downloads.test.jsto testcreateServiceIcons()andcreateClientLogo()across all user roles and media types.User Review Required
We recommend retaining the global
SKIP_RATE_LIMITsettings intests/setup.jsfor overall suite stability, while utilizing a dedicated test file to isolate and assert rate-limiting logic.Open Questions
Proposed Changes
Tests Component
[NEW] poller.test.js
Create a new unit test suite testing:
pollAllServices()aborts early ifpolling = true.onPollComplete(cb)adds callbacks to the list,offPollComplete(cb)deletes them, and subscribers are successfully executed upon completing a poll.pollingstate is reset tofalsein thefinallyblock so future polls are not permanently blocked.shouldSkipInstancePolling()detects recent webhook activity incacheand correctly skips polling.WEBHOOK_FALLBACK_TIMEOUT, a full poll is forced.[NEW] rateLimiter.test.js
Create a dedicated rate limiter integration test suite:
process.env.SKIP_RATE_LIMITinside the test context.supertestto verify a429 Too Many Requestsis returned.[MODIFY] downloads.test.js
Modify and append new tests to cover:
createServiceIcons():ombiLinkis provided (for all users).arrType === 'sonarr'andarrLinkexists.arrType === 'radarr'andarrLinkexists.createClientLogo():<img>matchingdownload.clientand sets correct classes and titles.[MODIFY] dashboard.test.js
Append tests to cover SSE Stream Lifecycle details:
onPollCompleteandonHistoryUpdatelisteners on client close/abort, preventing connection-based memory leaks.Verification Plan
Automated Tests
Feedback on Implementation Plan (Issue #60)
Overall Assessment
The plan is well-structured, pragmatic, and correctly identifies which gaps from Issue #60 are already addressed versus which ones require action. The proposed test additions target the right architectural areas (real-time polling, SSE lifecycle, rate limiting resilience, and admin UI rendering). I support moving forward with this plan.
Detailed Feedback by Section
1. Ombi Integration Tests
Correct assessment. The existing
ombi.test.js(1,102 lines) already provides strong coverage, including recenttvDbIdhandling. No action required.2. Background Poller (
poller.test.js)Excellent scope. The planned coverage areas (concurrency guard, subscriber registry, error recovery, webhook bypass logic, and fallback timeout) are the highest-value behaviors to test.
Recommendation on Testing Approach:
Use a hybrid strategy:
vi.useFakeTimers()for timing-dependent tests (interval behavior andWEBHOOK_FALLBACK_TIMEOUT).shouldSkipInstancePolling(), error recovery infinally, subscriber management).This combination provides both behavioral and timing coverage without introducing flakiness.
3. SSE Endpoint Tests
Good direction. Adding tests for connection lifecycle (
req.on('close')), callback deregistration, and memory leak prevention is valuable.Additional suggestion: Consider also verifying that different event types (downloads, history, requests) are emitted with correct formatting.
4. Rate Limiting Tests (
rateLimiter.test.js)Strong approach. Creating an isolated test file that temporarily unsets
SKIP_RATE_LIMITis the correct technical decision. This maintains overall suite stability while still validating production rate limiting behavior.5. Frontend Component Tests (
downloads.test.js)Very good. Expanding coverage of
createServiceIcons()across all combinations ofarrType,arrLink, and admin state will help prevent regressions on the recent link button issues. TestingcreateClientLogo()fallback behavior is also useful.Answers to Open Questions
1. Rate Limiting Tests
Yes — I strongly recommend keeping the dedicated
rateLimiter.test.jsapproach. Isolating the test is architecturally cleaner than globally re-enabling rate limiting.2. Poller Timer Testing
I recommend using fake timers (
vi.useFakeTimers()) for comprehensive coverage of time-based behavior, combined with direct state machine testing for non-timing logic.Additional Recommendations
arrLinkdecoration (from the related Radarr link issue), consider adding a small test fordecorateDownloadsWithArrLinks()to maintain consistency with the existing Ombi decoration tests.POLL_INTERVALvalues.Final Verdict
This is a solid, focused plan. It addresses the real gaps efficiently without over-engineering. I recommend proceeding with implementation, incorporating the hybrid timer approach for the poller and the isolated rate limiter test.
Resolved in commit
aec0447. This has been merged into main (merge commit52806d0) and officially tagged in point release v1.7.30.Documentation formatting fix pushed to develop (
a4af160), main (4107bdf), and release/1.7.30 (585092a). Tag v1.7.30 recreated on main.