Skip to content

[WC-3452] Pusher module refine#2323

Open
r0b1n wants to merge 7 commits into
mainfrom
feat/pusher-module-refine
Open

[WC-3452] Pusher module refine#2323
r0b1n wants to merge 7 commits into
mainfrom
feat/pusher-module-refine

Conversation

@r0b1n

@r0b1n r0b1n commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

@r0b1n r0b1n requested a review from a team as a code owner July 14, 2026 09:49
@github-actions

This comment has been minimized.

@r0b1n r0b1n force-pushed the feat/pusher-module-refine branch from c87f303 to 8366a69 Compare July 14, 2026 14:57
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

r0b1n added 7 commits July 15, 2026 12:35
SubscriptionConfig.onError was never set by any caller after handleError
was removed from Pusher.tsx. Drop the interface field, private field,
call site, and cleanup assignment to avoid misleading future readers.
…herConfig

Cover the previously untested upper layers: widget subscription building
logic in Pusher.tsx, channel name derivation, and config fetch error paths.
@r0b1n r0b1n force-pushed the feat/pusher-module-refine branch from 15cc99d to 2b63b4b Compare July 15, 2026 10:35
@github-actions

Copy link
Copy Markdown
Contributor

AI Code Review

🔶 Changes requested — one or more medium-severity items must be addressed


What was reviewed

File Change
automation/utils/src/steps.ts Extracted insertWidgetsIntoMpk helper; new addTestProjectWidgetsToMpk export
packages/modules/pusher/scripts/release.ts Added addTestProjectWidgetsToMpk(["Pusher.mpk"]) step to bundle legacy widget
packages/pluggableWidgets/pusher-web/src/Pusher.tsx Removed onError from subscription, dropped useCallback wrapper
packages/pluggableWidgets/pusher-web/src/hooks/usePusherSubscribe.ts Refactored subscription effect — removed cleanup fn, renamed instance
packages/pluggableWidgets/pusher-web/src/utils/PusherListener.ts Removed onError from SubscriptionConfig, removed state_change handler
packages/pluggableWidgets/pusher-web/src/__tests__/Pusher.spec.tsx Replaced placeholder with real tests
packages/pluggableWidgets/pusher-web/src/__tests__/PusherListener.spec.ts New — full lifecycle tests
packages/pluggableWidgets/pusher-web/src/__tests__/fetchPusherConfig.spec.ts New — fetch/abort/validation coverage
packages/pluggableWidgets/pusher-web/src/__tests__/getChannelName.spec.ts New — channel name derivation tests
packages/pluggableWidgets/pusher-web/src/__tests__/usePusherSubscribe.spec.ts New — hook lifecycle tests

Skipped (out of scope): dist/, pnpm-lock.yaml

⚠️ CI check status could not be confirmed — gh pr checks was unavailable during this review.


Findings

🔶 Medium — Missing CHANGELOG entry in pusher module

File: packages/modules/pusher/CHANGELOG.md
Problem: The module now bundles the legacy Pusher.mpk widget alongside the new one (via the addTestProjectWidgetsToMpk release step). When users import the module, they receive both widgets — this is user-visible and warrants a changelog entry.
Fix:

## [Unreleased]

### Added

- Bundled legacy `Pusher.mpk` widget for easy migration alongside the new `com.mendix.widget.web.Pusher.mpk`.

⚠️ Low — getChannelName.spec.ts uses manual Symbol manipulation instead of test-utils builders

File: packages/pluggableWidgets/pusher-web/src/__tests__/getChannelName.spec.ts lines 8–16
Note: makeObjectItem constructs an ObjectItem by manually attaching a Symbol property to match getChannelName's internal lookup mechanism. This couples the test to the implementation detail of how entity names are extracted (whichever symbol key getChannelName reads first). If the extraction strategy changes, the test silently breaks instead of failing for the right reason.

If obj("MyModule.MyEntity") from @mendix/widget-plugin-test-utils produces an ObjectItem with the right structure, prefer:

import { obj } from "@mendix/widget-plugin-test-utils";
const item = obj("MyModule.MyEntity"); // check if this provides entity/guid as needed

If obj() doesn't support the required structure, at minimum add a comment explaining the Symbol dependency so future maintainers understand the coupling.


⚠️ Low — usePusherSubscribe.spec.ts missing test for subscription change

File: packages/pluggableWidgets/pusher-web/src/__tests__/usePusherSubscribe.spec.ts
Note: The three tests cover initial subscribe, subscribe with undefined, and unmount. The hook's core dynamic behaviour — subscription changing from one channel to another — is not covered. This is the scenario where PusherListener.subscribe() must unsubscribe from the old channel before subscribing to the new one. Consider adding:

it("re-subscribes when subscription changes", async () => {
    const { rerender } = renderHook(
        (props: { sub: typeof stubSubscription | undefined }) => usePusherSubscribe(props.sub),
        { initialProps: { sub: stubSubscription } }
    );
    await act(async () => {});

    const updated = { ...stubSubscription, channelName: "private-Entity.456" };
    rerender({ sub: updated });

    expect(mockListener.subscribe).toHaveBeenLastCalledWith(updated);
});

Positives

  • insertWidgetsIntoMpk extraction cleanly eliminates the duplication that would have existed between addWidgetsToMpk and the new addTestProjectWidgetsToMpk — well-scoped helper.
  • The subscription effect refactor in usePusherSubscribe.ts actually fixes a double-unsubscribe from the old code: the previous cleanup return () => { listener.unsubscribe(); } ran before every re-render, unsubscribing even on handler-only updates. The new code lets PusherListener.subscribe() decide whether a resubscribe is needed.
  • PusherListener.spec.ts "updates handler map so new handler fires without resubscribing" test directly validates the key design invariant (stable channel, swappable handlers) — exactly the right thing to pin down.
  • Full test coverage added for all previously untested utilities (fetchPusherConfig, getChannelName, PusherListener, usePusherSubscribe). All five spec files use jest.clearAllMocks() in beforeEach/afterEach — no mock pollution risk.
  • Removing onError from the public SubscriptionConfig interface is the right call: the only consumer was a console.error wrapper, and that's now done directly in PusherListener where the error originates.

@iobuhov iobuhov left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants