Skip to content

test(gateway): add coverage for hybrid LINE reply/push dispatch#623

Merged
thepagent merged 3 commits intomainfrom
test/gateway-line-dispatch
Apr 28, 2026
Merged

test(gateway): add coverage for hybrid LINE reply/push dispatch#623
thepagent merged 3 commits intomainfrom
test/gateway-line-dispatch

Conversation

@chaodu-agent
Copy link
Copy Markdown
Collaborator

What problem does this solve?

Issue #620 — the hybrid LINE reply/push strategy from PR #608 lacks focused test coverage for the dispatch decision logic. This is correctness-sensitive because it decides when to use the free Reply API, when to fall back to Push API, and when not to fall back to avoid duplicate delivery.

Closes #620

Proposed Solution

  1. Extract dispatch_line_reply() — pulled the LINE dispatch branch out of the WebSocket recv_task closure into a standalone async function with an api_base parameter for testability.

  2. 6 test cases using wiremock for HTTP mocking with scoped expectations (expect(N) auto-verified on drop):

Test Scenario Expected
cache_hit_uses_reply_api Valid cached token Reply API ✓, Push API ✗
cache_miss_uses_push_api No token in cache Reply API ✗, Push API ✓
expired_token_uses_push_api Token older than TTL Reply API ✗, Push API ✓
reply_400_invalid_token_falls_back_to_push Reply returns 400 "Invalid reply token" Reply API ✓, Push API ✓
reply_5xx_does_not_fallback Reply returns 500 Reply API ✓, Push API ✗
reply_network_error_does_not_fallback Connection refused Reply API attempted, Push API ✗

Why this approach?

  • Extracting the function with an api_base parameter is the minimal refactor needed to make the logic testable without changing behavior.
  • wiremock scoped mocks verify both positive (was called) and negative (was NOT called) expectations, which is critical for the "no fallback on 5xx/network error" safety invariant.

Test Plan

  • cargo build passes
  • cargo test passes — all 6 tests green
  • No new warnings introduced (existing warnings are pre-existing)

Supersedes #622 (which had unrelated diff noise from the base branch).

Extract dispatch_line_reply() into a testable function and add 6 tests
covering the full decision matrix:

- cache hit → Reply API only
- cache miss → Push API fallback
- expired token → Push API fallback
- Reply 400 invalid token → Push API fallback
- Reply 5xx → no fallback (duplicate risk)
- network error → no fallback (duplicate risk)

Uses wiremock for HTTP mocking with scoped expectations.

Closes #620
@github-actions
Copy link
Copy Markdown

⚠️ This PR is missing a Discord Discussion URL in the body.

All PRs must reference a prior Discord discussion to ensure community alignment before implementation.

Please edit the PR description to include a link like:

Discord Discussion URL: https://discord.com/channels/...

This PR will be automatically closed in 3 days if the link is not added.

@github-actions github-actions Bot added closing-soon PR missing Discord Discussion URL — will auto-close in 3 days pending-screening PR awaiting automated screening labels Apr 28, 2026
超渡法師 added 2 commits April 28, 2026 19:39
Address review feedback from 擺渡法師: wiremock mocks now verify
Authorization bearer token and request body (replyToken, to, messages)
in addition to method/path/count.

- cache_hit: verifies replyToken + bearer token + message payload
- cache_miss: verifies 'to' field + bearer token + message payload
- expired_token: verifies push body + bearer token
- 400 invalid token: verifies bearer token on both reply and push
- 5xx: verifies bearer token on reply
- network error: unchanged (no server to verify against)
@thepagent thepagent merged commit 867f552 into main Apr 28, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

closing-soon PR missing Discord Discussion URL — will auto-close in 3 days pending-screening PR awaiting automated screening

Projects

None yet

Development

Successfully merging this pull request may close these issues.

test(gateway): add coverage for hybrid LINE reply/push dispatch

2 participants