fix(testing): wire publishers to router-registered subscribers - #87
Merged
Merged
Conversation
create_publisher_fake_subscriber scanned broker._subscribers, which omits every router's, so a router publisher never matched its real subscriber and got a fake built on the unprefixed topic. Behind a prefix that topic has no publisher, so publisher.mock recorded nothing. TimersBroker.subscribers narrows the base's return type, which also retires a cast in the fake producer. Closes #86
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #86.
The bug
TestTimersBroker.create_publisher_fake_subscriberscannedbroker._subscribersto find the real subscriber a publisher should be wired to. That list holds only endpoints registered directly on the broker — upstream'sRegistrator.subscribersis what includes routers':So anything declared on a
TimersRouterwas never matched,is_realcame backFalse, and the fallback ranbroker.subscriber(publisher.config.topic)— the unprefixed topic. Behind a prefix the fake landed on a topic nothing publishes to.is_real=Trueis what makes upstream mirror the real handler's calls into the publisher's recorder, so the user-visible failure was:on a publish that did happen. Anyone testing a prefixed router could not assert on their publisher.
The fix
Scan
broker.subscribers, and register the fallback underfull_topicrather than the rawtopic. Both halves are needed: the first finds the router's subscriber, the second puts the fake on the right topic when there genuinely isn't one.TimersBroker.subscribersnow narrows the base'slist[SubscriberUsecase[TimerMessage]]tolist[TimersSubscriber], which is what_subscribers: list[TimersSubscriber]already claimed one line above. Narrowing at the broker rather than casting at each call site also retired an existingtyping.castinFakeTimersProducer.publish, whichtythen flagged as redundant.Before / after
Same script, three declarations:
publisher.mock['reminders']→ unchanged['reminders', 'reminders']→['reminders']app:['reminders', 'app:reminders']→['app:reminders']The no-prefix row was wrong too — a duplicate subscriber on a topic that already had one — it just happened to keep working, because the fake carries no user handler and the topic still matched. Only the prefixed row failed visibly.
The stray channel this surfaced through in #85 is gone as well:
Previously a third
reminders:PublisherResponseSubscribersat alongside those.Tests
Written first, red before the change:
The existing coverage of this method was
test_create_publisher_fake_subscriber_is_instance_method, which checks the signature only. Every behavioural path through it went through a broker with no router, so the whole router branch was unexercised while the gate read 100%.Not a 0.7.6 regression
Pre-existing.
Registrator.subscribershas had the router-aware definition throughout 0.7; nothing in #85 touched this path.Verification
just lintclean (eof-fixer,ruff format,ruff check,ty). Full suite against Redis 8: 170 passed, 100% coverage.