Skip to content

test: unit tests for Redis config, cleanup jobs, and webhook retry job - #742

Merged
DeFiVC merged 2 commits into
ChainLearnOfficial:mainfrom
chigozirim007:test/chainlearn-kalveen-unit-tests
Oct 21, 2026
Merged

DeFiVC merged 2 commits into
ChainLearnOfficial:mainfrom
chigozirim007:test/chainlearn-kalveen-unit-tests

Conversation

@chigozirim007

Copy link
Copy Markdown
Contributor

closes #607
closes #609
closes #611

Note: #608 (unit tests for the AI client) is not included; tests/unit/quizzes/ai-client.test.ts already exists at exactly the path the issue asks for and covers request format, response parsing, timeout handling, retries, and the circuit breaker (8/8 passing). Confirmed, not claiming it here.

What's added

  • tests/unit/config/redis.test.ts (Add unit tests for Redis config #607): ioredis client construction from config.REDIS_URL, the retry strategy (linear backoff capped at 2000ms, gives up after 10 attempts), event handler registration, and closeRedis().
  • tests/unit/jobs/cleanup-idempotency.test.ts (Add unit tests for cleanup jobs #609): the interval scheduling wrapper around cleanupIdempotencyKeys() (the deletion logic itself already has its own tests in tests/unit/services/idempotency.test.ts). Scheduling, stopping, restarting, and that a rejected cleanup pass is logged rather than crashing the interval.
  • tests/unit/jobs/cleanup-notifications.test.ts (Add unit tests for cleanup jobs #609): moved from tests/unit/notifications/ to the path the issue asks for. While moving it, fixed a stale mock, see below.
  • tests/unit/jobs/process-webhook-retries.test.ts (Add unit tests for process webhook retries job #611): covers the job's actual current responsibility, scheduling a periodic call to webhook-dispatcher.js's processWebhookRetries(), recovering from a rejected pass, and the generation counter mechanism that prevents a tick already in flight from running again after stop().

Bugs fixed along the way (each confirmed against a fresh upstream/main, not something this PR introduced)

  • cleanup-notifications.test.ts's mock was stale. The real cleanupExpiredNotifications() chains .returning() after .where() to get a deletable row count, but the mock's delete chain only had a .where() terminal. 4 of its 5 cases were failing with returning is not a function, at the old path and the new one. Added .returning() to the mock chain.
  • process-webhook-retries.ts didn't parse. Two full, incompatible implementations of startWebhookRetryProcessor were concatenated together: one Redis-queue-based with its own enqueue/dequeue/shouldRetry/markForRetry exports, a stray import statement mid-file, and a broken stopWebhookRetryProcessor referencing variables from both halves. Nothing outside the file used the first implementation's exports; kept only the second, the one server.ts actually calls. No test file for this could even load before this fix.
  • webhook-dispatcher.ts's sendWebhook() had a ReferenceError in its finally block: clearTimeout(timer) where the variable holding the AbortController timeout handle is named timeout, not timer. This throws on every single webhook send attempt, success or failure. Add unit tests for process webhook retries job #611 is really asking for the retry job's behavior to be covered, and this is the function at the center of that behavior, so fixed it rather than write tests around a function that currently can't complete a call.
  • utils/logger.ts had a circular import with config/index.ts (logger.ts reads config.NODE_ENV; config/index.ts imports logger.ts to log its own validation errors), leaving config undefined partway through module evaluation and crashing any test that touches logger.ts, directly or via another module's import chain, with Cannot read properties of undefined (reading 'NODE_ENV'). Fixed by reading process.env.NODE_ENV directly instead of through config.

Disclosure

npm test still fails on this branch beyond the files above, from the scaffold-contamination issue already reported in full in #689 on this repo: several files (including course.service.ts) contain dead NestJS-style scaffold code bolted onto the real Fastify implementations, causing duplicate-export compile errors that crash every test file that transitively imports them. Not re-fixed here to avoid overlapping with that PR. All 4 test files this PR adds, plus the moved one, pass cleanly when run directly: 29/29.

…y job (ChainLearnOfficial#607, ChainLearnOfficial#609, ChainLearnOfficial#611)

tests/unit/config/redis.test.ts (ChainLearnOfficial#607): the ioredis client construction
from config.REDIS_URL, its retry strategy (linear backoff capped at
2000ms, gives up after 10 attempts), event handler registration, and
closeRedis().

tests/unit/jobs/cleanup-idempotency.test.ts (ChainLearnOfficial#609): the interval
scheduling wrapper around cleanupIdempotencyKeys(), the deletion logic
itself already has its own tests in
tests/unit/services/idempotency.test.ts, scheduling, stopping,
restarting, and that a rejected cleanup pass is logged rather than
crashing the interval.

tests/unit/jobs/cleanup-notifications.test.ts (ChainLearnOfficial#609): moved from
tests/unit/notifications/ to the path ChainLearnOfficial#609 asks for. While moving it,
fixed a stale mock: the real cleanupExpiredNotifications() chains
.returning() after .where() to get a deletable row count, but the
mock's delete chain only had a .where() terminal, so 4 of its 5 cases
were failing with 'returning is not a function' both before and after
the move, confirmed against upstream/main. Added .returning() to the
chain.

tests/unit/jobs/process-webhook-retries.test.ts (ChainLearnOfficial#611): covers the
job's actual current responsibility, scheduling a periodic call to
webhook-dispatcher.js's processWebhookRetries() and recovering from a
rejected pass, plus the generation counter mechanism that prevents a
tick already in flight from running again after stop().

Also, while reading process-webhook-retries.ts for ChainLearnOfficial#611: the file had
two full, incompatible implementations of startWebhookRetryProcessor
concatenated together, one Redis queue based with its own
enqueue/dequeue/shouldRetry/markForRetry exports, a stray import
mid-file, and a broken stopWebhookRetryProcessor referencing variables
from both halves. Nothing outside the file used the first
implementation's exports; kept only the second, the one server.ts
actually calls, otherwise this file doesn't even parse, so no test
file for it could load either.

Also fixed in services/webhook-dispatcher.ts, which the job wrapper
delegates to and which ChainLearnOfficial#611 is really asking to have its retry
behavior covered: sendWebhook()'s finally block called
clearTimeout(timer), but the variable holding the AbortController
timeout handle is named timeout, not timer, a ReferenceError on every
single webhook send attempt, success or failure, confirmed against
upstream/main.

Also fixed utils/logger.ts: it imported config/index.ts to read
NODE_ENV, while config/index.ts imports logger.ts to log its own
validation warnings/errors. That circular import left config
undefined partway through evaluation, crashing any test that touches
logger.ts, directly or via another module's import chain, with
'Cannot read properties of undefined (reading NODE_ENV)', confirmed
against upstream/main and reproducible via npm test today. Fixed by
reading process.env.NODE_ENV directly instead of through config.

Disclosure: npm test still fails on this branch beyond the files
listed above, from the same scaffold contamination issue already
reported in full in PR ChainLearnOfficial#689 on this repo, several files, including
course.service.ts, contain dead NestJS style scaffold code bolted
onto the real Fastify implementations, causing duplicate export
compile errors that crash every test file that transitively imports
them. Not re-fixed here to avoid overlapping with that PR; all 4 test
files this PR adds, plus the moved one, pass cleanly when run
directly (29/29), which is what this issue's scope covers.
@drips-wave

drips-wave Bot commented Oct 21, 2026

Copy link
Copy Markdown

@chigozirim007 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@DeFiVC
DeFiVC merged commit 9abb0b9 into ChainLearnOfficial:main Oct 21, 2026
@grantfox-oss grantfox-oss Bot mentioned this pull request Oct 21, 2026
4 tasks
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.

Add unit tests for process webhook retries job Add unit tests for cleanup jobs Add unit tests for Redis config

2 participants