Skip to content

refactor: migrate block handler tests to typed response pattern#915

Open
Ahmedhossamdev wants to merge 3 commits into
mainfrom
refactor/typed-block-tests
Open

refactor: migrate block handler tests to typed response pattern#915
Ahmedhossamdev wants to merge 3 commits into
mainfrom
refactor/typed-block-tests

Conversation

@Ahmedhossamdev
Copy link
Copy Markdown
Member

@Ahmedhossamdev Ahmedhossamdev commented May 5, 2026

  • Migrates block_handler_test.go to the typed response pattern using callAPIHandler[BlockEntryResponse]
  • Removes 4 redundant tests and merges 2 overlapping ones into a single TestBlockHandlerEndToEnd
  • Fixes a duplicate-iteration bug in TestBlockHandlerVerifyBlockStopTimes

Summary by CodeRabbit

  • Tests
    • Refactored test suite to use strongly-typed API test flows with deeper structural and numeric validations (including non-empty/non-negative checks and sequence monotonicity).
    • Tightened error-path assertions to validate specific HTTP error codes and messages.
    • Simplified cancellation testing and updated benchmarks.
    • Removed several legacy/duplicate tests to streamline coverage.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 5, 2026

Warning

Rate limit exceeded

@Ahmedhossamdev has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 28 minutes and 29 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5be6b161-c7b0-48e6-ad87-7517b1b220fa

📥 Commits

Reviewing files that changed from the base of the PR and between 3b0d6b2 and 435175d.

📒 Files selected for processing (2)
  • internal/restapi/block_handler_test.go
  • internal/restapi/response_types.go
📝 Walkthrough

Walkthrough

Refactors block handler tests to use a typed generic test helper (callAPIHandler[BlockEntryResponse]) and adds a BlockEntryResponse alias. Converts assertions to use strong types, adds deeper structural and numeric validations, removes five legacy tests, and simplifies the context-cancellation test and benchmark.

Changes

Block Handler Test Refactor

Layer / File(s) Summary
Type Definition
internal/restapi/response_types.go
Adds BlockEntryResponse = EntryResponse[models.BlockEntry].
Test wiring / helper usage
internal/restapi/block_handler_test.go
Replaces untyped JSON/endpoint test helpers with callAPIHandler[BlockEntryResponse] calls across tests and benchmark.
Core assertions / validations
internal/restapi/block_handler_test.go
Rewrites end-to-end and verification tests to assert typed Code/Text/Version/CurrentTime and to validate ConfigurationsTripsBlockStopTimes IDs, reference consistency, non-empty/ non-negative distances, and monotonicity where applicable.
Error-paths / negative cases
internal/restapi/block_handler_test.go
Updates 404/400/401 tests to assert typed Code/Text (and in some cases only HTTP status) and drops prior Version/CurrentTime checks for those error cases.
Cleanup / removals
internal/restapi/block_handler_test.go
Removes five legacy tests: TestBlockHandlerResponseValidation, TestBlockHandlerDifferentBlockIDs, TestBlockHandlerAgencyIdExtraction, TestBlockHandlerResponseTime, TestBlockHandlerJSONSerialization.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • OneBusAway/maglev#897: Modifies internal/restapi/response_types.go and refactors tests to use typed generic response models and callAPIHandler.
  • OneBusAway/maglev#905: Adds an EntryResponse type alias and migrates handler tests to a typed callAPIHandler[...] pattern.
  • OneBusAway/maglev#910: Refactors endpoint tests to use the typed generic response helper and adds a corresponding EntryResponse[...] alias.

Suggested reviewers

  • fletcherw
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately summarizes the main change: migrating block handler tests to a typed response pattern, which aligns with the core modifications in block_handler_test.go and the addition of BlockEntryResponse type.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/typed-block-tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 5, 2026

Performance Smoke Test Results

Status: PASSED

Metric Value
p(95) latency 2.1 ms
Error rate 0.00%
Total requests 330
Req/sec 10.9

Smoke test config: 5 VUs x 30s. Thresholds: p(95) < 300ms, error rate < 1%.

Full results uploaded as workflow artifact: k6-smoke-summary.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
internal/restapi/block_handler_test.go (1)

212-215: ⚡ Quick win

Benchmark unnecessarily measures server creation overhead on each iteration.

callAPIHandler creates a new httptest.NewServer for every benchmark iteration. Extract server setup before b.ResetTimer() and reuse it in the loop to measure handler performance rather than server spin-up time.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/restapi/block_handler_test.go` around lines 212 - 215, The benchmark
is measuring server creation each iteration because callAPIHandler spins up an
httptest.NewServer inside the loop; refactor the benchmark to create the
httptest.Server (and the handler/api/endpoint) once before b.ResetTimer() and
then call the handler directly (or call a variant of callAPIHandler that accepts
the server URL or *httptest.Server) inside the loop so the loop measures only
handler execution; update references to callAPIHandler[BlockEntryResponse] to
use the reused server or a new helper that accepts the server to avoid
per-iteration NewServer creation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/restapi/block_handler_test.go`:
- Around line 55-57: The test in block_handler_test.go is making an
order-dependent assertion on refs.Agencies[0].ID == "25", which can be flaky;
change the test to search refs.Agencies for an entry with ID "25" (e.g., iterate
or use a helper find function), assert that such an agency is found, then assert
the matched agency's Name is not empty. Also ensure production code that builds
refs.Agencies (see functions that populate refs.Agencies in internal/restapi
package) uses a map to deduplicate IDs before converting to a slice so ordering
is not relied upon.

---

Nitpick comments:
In `@internal/restapi/block_handler_test.go`:
- Around line 212-215: The benchmark is measuring server creation each iteration
because callAPIHandler spins up an httptest.NewServer inside the loop; refactor
the benchmark to create the httptest.Server (and the handler/api/endpoint) once
before b.ResetTimer() and then call the handler directly (or call a variant of
callAPIHandler that accepts the server URL or *httptest.Server) inside the loop
so the loop measures only handler execution; update references to
callAPIHandler[BlockEntryResponse] to use the reused server or a new helper that
accepts the server to avoid per-iteration NewServer creation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 277ad54e-80fc-4c91-8329-8f1b02475228

📥 Commits

Reviewing files that changed from the base of the PR and between a7e624c and d25a1f8.

📒 Files selected for processing (2)
  • internal/restapi/block_handler_test.go
  • internal/restapi/response_types.go

Comment thread internal/restapi/block_handler_test.go Outdated
@Ahmedhossamdev Ahmedhossamdev requested a review from fletcherw May 5, 2026 09:39
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 5, 2026

Performance Smoke Test Results

Status: PASSED

Metric Value
p(95) latency 2.2 ms
Error rate 0.00%
Total requests 323
Req/sec 10.6

Smoke test config: 5 VUs x 30s. Thresholds: p(95) < 300ms, error rate < 1%.

Full results uploaded as workflow artifact: k6-smoke-summary.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
internal/restapi/block_handler_test.go (1)

156-170: ⚡ Quick win

Broaden reference-consistency validation to all stop IDs.

Right now this test validates only one StopID (Line 164), so reference mismatches in other block stop times can slip through. Consider asserting every StopID across configurations/trips exists in model.Data.References.Stops.

Proposed refactor
-	entry := model.Data.Entry
-	if len(entry.Configurations) == 0 || len(entry.Configurations[0].Trips) == 0 {
+	entry := model.Data.Entry
+	if len(entry.Configurations) == 0 {
 		t.Skip("no trips in block to verify")
 	}
-	blockStopTimes := entry.Configurations[0].Trips[0].BlockStopTimes
-	if len(blockStopTimes) == 0 {
-		t.Skip("no block stop times to verify")
-	}
-	stopID := blockStopTimes[0].StopTime.StopID
 
 	refStopIDs := make(map[string]bool, len(model.Data.References.Stops))
 	for _, s := range model.Data.References.Stops {
 		refStopIDs[s.ID] = true
 	}
-	assert.True(t, refStopIDs[stopID], "Stop %s should be in references", stopID)
+
+	foundAnyStopTimes := false
+	for _, cfg := range entry.Configurations {
+		for _, trip := range cfg.Trips {
+			for _, st := range trip.BlockStopTimes {
+				foundAnyStopTimes = true
+				assert.True(t, refStopIDs[st.StopTime.StopID], "Stop %s should be in references", st.StopTime.StopID)
+			}
+		}
+	}
+	if !foundAnyStopTimes {
+		t.Skip("no block stop times to verify")
+	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/restapi/block_handler_test.go` around lines 156 - 170, The test only
asserts a single stop ID; instead iterate all configurations -> trips ->
BlockStopTimes in the entry (use entry.Configurations, .Trips, .BlockStopTimes)
and for each StopTime.StopID verify it exists in the reference map (refStopIDs)
built from model.Data.References.Stops; keep the existing early t.Skip checks
for empty configurations/trips/blockStopTimes, and replace the single assert on
stopID with an assertion inside the loop that each stopID is present (include
the stopID in the assertion message for easier debugging).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@internal/restapi/block_handler_test.go`:
- Around line 156-170: The test only asserts a single stop ID; instead iterate
all configurations -> trips -> BlockStopTimes in the entry (use
entry.Configurations, .Trips, .BlockStopTimes) and for each StopTime.StopID
verify it exists in the reference map (refStopIDs) built from
model.Data.References.Stops; keep the existing early t.Skip checks for empty
configurations/trips/blockStopTimes, and replace the single assert on stopID
with an assertion inside the loop that each stopID is present (include the
stopID in the assertion message for easier debugging).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: eb368c4f-2106-4fde-b188-b9229da0dd4c

📥 Commits

Reviewing files that changed from the base of the PR and between d25a1f8 and 3b0d6b2.

📒 Files selected for processing (1)
  • internal/restapi/block_handler_test.go

- Add BlockEntryResponse alias for EntryResponse[models.BlockEntry]
- Replace serveApiAndRetrieveEndpoint + map[string]any casts with callAPIHandler[BlockEntryResponse]
- Drop redundant tests: DifferentBlockIDs, AgencyIdExtraction, JSONSerialization, ResponseTime
- Merge ResponseValidation into EndToEnd (detailed [0] checks + iterate-all coverage)
- Fix duplicate-iteration bug in VerifyBlockStopTimes when len==1
- Trim non-specific assertions (Version/CurrentTime) from error-path tests
@Ahmedhossamdev Ahmedhossamdev force-pushed the refactor/typed-block-tests branch from 3b0d6b2 to 435175d Compare May 14, 2026 15:43
@sonarqubecloud
Copy link
Copy Markdown

@github-actions
Copy link
Copy Markdown

Performance Smoke Test Results

Status: PASSED

Metric Value
p(95) latency 2.0 ms
Error rate 0.00%
Total requests 342
Req/sec 11.3

Smoke test config: 5 VUs x 30s. Thresholds: p(95) < 300ms, error rate < 1%.

Full results uploaded as workflow artifact: k6-smoke-summary.

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.

1 participant