Skip to content

test: add E2E coverage for status sub-object fields - #1300

Open
3rabiii wants to merge 2 commits into
OneBusAway:mainfrom
3rabiii:fix-trips-for-route-gap14
Open

test: add E2E coverage for status sub-object fields#1300
3rabiii wants to merge 2 commits into
OneBusAway:mainfrom
3rabiii:fix-trips-for-route-gap14

Conversation

@3rabiii

@3rabiii 3rabiii commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Description

This PR addresses Issue #1299 by adding strict end-to-end test coverage for the status sub-object fields in the trips-for-route API response.

Changes Made

  • Strict Assertions: Added TestTripsForRouteHandler_StatusFields to verify:
    • blockTripSequence is a non-negative integer.
    • position.lat and position.lon are accurately populated (handling the GTFS-RT float32 to Go float64 conversion).
    • occupancyCount correctly returns the -1 sentinel constructor default value.
    • situationIds and vehicleFeatures are strictly non-nil empty slices ([]), differentiating them from null.
  • Testing Pattern Alignment: Uses the unified real-time mock injection approach to cleanly test the SCHEDULED vehicle tracking without race conditions.

Summary by CodeRabbit

Summary by CodeRabbit

  • Tests
    • Expanded coverage for trip status information returned by the API.
    • Validates vehicle positions, block sequencing, occupancy values, service status, and trip phase details.
    • Confirms that related status fields are returned consistently, including empty vehicle-feature and service-alert data.
    • Adds realistic scheduled-vehicle scenarios with GPS coordinates to improve confidence in trip and vehicle-status results.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a429601d-0792-43dd-a9b1-1b2d39243b60

📥 Commits

Reviewing files that changed from the base of the PR and between 9805ac4 and 40354fe.

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

Included review availability: Your plan includes up to 1 review per rolling hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The test suite adds a scheduled vehicle-position fixture for trips-for-route. It verifies coordinates, block sequence, occupancy defaults, non-nil empty slices, status, and phase.

Changes

Trips-for-route status coverage

Layer / File(s) Summary
Exercise realtime status fields
internal/restapi/trips_for_route_handler_test.go
The test adds deterministic coordinates, injects a scheduled vehicle with realtime data, and verifies status fields returned by the trips-for-route handler.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 40354

This PR adds focused end-to-end assertions for status fields without changing production behavior, so no actionable merge-blocking risk remains beyond normal checks and review.

Possibly related issues

  • Issue 1299: Directly requests the trips-for-route status-field coverage added here.
  • Issue 1292: Adds related status-field coverage in the same handler test file.
  • Issue 1297: Adds related realtime vehicle-data tests for trips-for-route.

Possibly related PRs

Suggested reviewers: arcoder181105, burma-shave

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the added end-to-end test coverage for status sub-object fields.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.
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.

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.

@aaronbrethorst

Copy link
Copy Markdown
Member

Code review

Found 1 issue:

  1. assert.GreaterOrEqual(t, entry.Status.BlockTripSequence, 0) cannot fail, so it provides no regression coverage for the field the PR is meant to pin down. BuildTripStatus computes the sequence via calculateBlockTripSequence, which returns 0 on any failure ("Returns 0 when the sequence is unavailable"), and then only assigns it with if blockTripSequence > 0 (internal/restapi/trips_helper.go:62-65) — the field is non-negative by construction on this path. The synthetic fixture also makes the value fully deterministic: tfr-trip is the only trip in block tfr-block, and GetBlockTripSequence is zero-based (ROW_NUMBER() ... - 1), so the expected value is exactly 0. If BuildTripStatus stopped computing blockTripSequence entirely, this assertion would still pass. assert.Equal(t, 0, entry.Status.BlockTripSequence) would actually pin the behavior. (The neighbouring position / occupancyCount / situationIds / vehicleFeatures assertions are load-bearing — only this one is vacuous.)

require.NotNil(t, entry.Status, "entry should carry a real-time status")
assert.GreaterOrEqual(t, entry.Status.BlockTripSequence, 0,
"blockTripSequence should be a non-negative integer")
// GTFS-RT stores coordinates as float32, so compare against the round-tripped value.
assert.Equal(t, float64(float32(tripsForRouteRealtimeLat)), entry.Status.Position.Lat)

🤖 Generated with Claude Code

- If this code review was useful, please react with 👍. Otherwise, react with 👎.

@aaronbrethorst aaronbrethorst left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Most of this test is load-bearing. Injecting a real GTFS-RT vehicle with a GPS fix and asserting on status.position.lat/lon, the -1 occupancyCount sentinel, and non-null-but-empty situationIds/vehicleFeatures would all catch real regressions — and the [] vs null checks in particular guard something easy to break and hard to notice. I confirmed none of it contradicts openapi.yml's TripStatus schema.

The one field the PR headlines first, though, asserts nothing.

assert.GreaterOrEqual(t, entry.Status.BlockTripSequence, 0) can never fail. calculateBlockTripSequence returns 0 on any failure, and BuildTripStatus only assigns the field under if blockTripSequence > 0 (trips_helper.go:62-65) — so it's non-negative by construction, whatever happens. The fixture is fully deterministic here (a single trip in tfr-block, and GetBlockTripSequence is zero-based), so the real assertion is assert.Equal(t, 0, ...). One-line change.

I know GreaterOrEqual(seq, 0) appears elsewhere in the suite, but those run over RABA data where the value genuinely isn't pinned. Over a controlled fixture — and in a PR whose stated goal is strict assertions — it's worth being exact.

The branch also conflicts with main, and more deeply than it looks: createTestApiWithTripsForRouteFixture, the helper this refactors, was removed in c905b6c8 and replaced by a generic createTestApiWithGTFSFixture(t, clock, zipName, files) plus per-scenario file maps. So the buildTripsForRouteFixtureZip extraction is now redundant, and createTestApiWithScheduledRealtimePosition needs rebuilding on top of the new builder. That landed while this sat in the queue — not your doing. TestTripsForRouteHandler_StatusFields itself should transplant cleanly once the fixture dependency is sorted.

One last thing: the helper doc and test comment both emphasize "a SCHEDULED vehicle", but the feed never sets ScheduleRelationship (it relies on the proto default) and the test never asserts Status/Phase. Either assert it or soften the comment.

Happy to re-review once it's rebased.

- Change blockTripSequence check to expect exactly 0 instead of >= 0
- Check that the vehicle status is SCHEDULED and the phase is in_progress
- Use the new createTestApiWithGTFSFixture setup after rebasing from main
@3rabiii
3rabiii force-pushed the fix-trips-for-route-gap14 branch from 9805ac4 to f727460 Compare August 11, 2026 22:35
@3rabiii
3rabiii requested a review from aaronbrethorst August 11, 2026 22:45
@aaronbrethorst

Copy link
Copy Markdown
Member

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

🤖 Generated with Claude Code

@burma-shave burma-shave 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.

merge main and fix conflicts

@aaronbrethorst aaronbrethorst left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Approving on the merits — this looks good, but it can't merge as-is. See below.

All three points from my last review are addressed: GreaterOrEqual(seq, 0) is now a real equality assertion, the redundant fixture-zip extraction is gone in favor of createTestApiWithGTFSFixture, and the "SCHEDULED vehicle" claim is asserted rather than narrated.

I checked the parts that could have made this test quietly meaningless and they're sound. InitGTFSManager does a synchronous first RT fetch before MarkReady(), so there's no race. The fixture has no shapes.txt, which means BuildTripStatus skips shape projection and status.Position stays the raw GPS fix — so the float64(float32(...)) expectation is correct rather than accidentally correct. And the situationIds/vehicleFeatures assertions are load-bearing, since decoding null into []string yields nil and require.NotNil distinguishes [] from null.

Two things blocking the merge, neither of them the code:

  1. The branch conflicts with main — that file gained ~198 lines after your 08-11 rebase, touching the import block and the fixture region you also edit. Mechanical to resolve, but it needs doing.
  2. burma-shave has a change request still open here. My approval doesn't dismiss it, so please square that before merging.

Two notes for the rebase:

  • createTestApiWithScheduledRealtimePosition takes a clock.Clock parameter but hardcodes tripsForRouteTestClock for the feed header and vehicle timestamps. A future caller passing a different clock more than 15 minutes away would silently trip StaleDetector and get default/scheduled instead of a clear failure. Deriving the timestamp from c.Now() removes the trap.
  • The occupancyCount assertion's message says "when the feed omits occupancy data," but NewTripStatus() sets -1 unconditionally and nothing on this path overwrites it — the assertion pins a constructor default, not feed-driven behavior.

One coordination note: #1298 adds a second real-time fixture builder to this same file using a different injection mechanism (SetRealTimeVehiclesForTest rather than an httptest feed). If both land we end up with two overlapping patterns — worth settling which one wins before the second merges.

- Resolve merge conflicts in trips_for_route_handler_test.go.
- Use dynamic timestamp (c.Now()) for injected vehicles to avoid StaleDetector traps.
- Fix occupancyCount assertion message to reflect the constructor default.
- Unify real-time mock pattern using MockAddVehicleWithOptions instead of httptest.
@sonarqubecloud

Copy link
Copy Markdown

@3rabiii
3rabiii requested a review from burma-shave August 17, 2026 19:49

@burma-shave burma-shave 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.

conflicts need to be resolved again

@burma-shave

Copy link
Copy Markdown
Collaborator

@3rabiii checking in on this older PR. It is still blocked on merge conflicts from the last review. Could you please merge main, resolve the conflicts, and let us know when it is ready for re-review?

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.

3 participants