Make the BMX TuneIn integration tests independent of the live TuneIn (radiotime.com) service, the same way Spotify/Amazon are already mocked. - pkg/service/bmx: the TuneIn upstream base URLs become configurable vars with a SetTuneInEndpoints(opmlBase, apiBase) setter that also registers the host in the outbound allowlist. Defaults are unchanged (real radiotime hosts), so production behaviour is identical; tests can redirect to a mock. - cmd/soundtouch-service: new --tunein-opml-url / --tunein-api-url flags (TUNEIN_OPML_URL / TUNEIN_API_URL) wired through to SetTuneInEndpoints. - cmd/mock-tunein + pkg/testutils/tunein: a mock TuneIn server serving Tune.ashx (stream URLs) and describe.ashx (name/logo) with RFC-5737 values; unmocked endpoints 404 so a test needing them fails loudly. - docker-compose.ci.yml: add the tunein-mock service and point the service at it. - tunein_playback_station.http now asserts the mock-served stream URL + name, proving the path is offline. tunein_favorite.http covers the local-only favorite add/remove (202). - TUNEIN-MOCK-MISSING.md lists the upstream captures still needed (episode / navigate / search) before those routes can be mocked + tested. make test-http-client: 61 requests, 0 failed. golangci-lint clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2.5 KiB
TuneIn mock: missing upstream fixtures
The mock-tunein service (cmd/mock-tunein, pkg/testutils/tunein) lets the
integration suite exercise the BMX TuneIn endpoints without hitting the live
TuneIn (radiotime.com) service. The service is pointed at it in CI via
TUNEIN_OPML_URL / TUNEIN_API_URL (see docker-compose.ci.yml).
Mocked today (hermetic)
GET /Tune.ashx?id=...&formats=...(station stream resolution)GET /describe.ashx?id=...(station name + logo)
These back GET /bmx/tunein/v1/playback/station/{stationID}
(tunein_playback_station.http), which is therefore fully offline.
Local-only BMX routes (no upstream at all, already hermetic):
/bmx/tunein/v1/favorite/{id} (POST/DELETE), /bmx/tunein/v1/token,
/bmx/tunein/v1/report.
NOT mocked yet — need real upstream captures
The following BMX TuneIn routes call api.radiotime.com / opml.radiotime.com
endpoints we do not have recorded upstream responses for. The mock returns 404
for these (so a test that needs them fails loudly). To cover them we need to
capture the raw radiotime responses (service -> TuneIn), not just the final
BMX responses the speaker received:
| BMX route (speaker-facing) | Upstream call the service makes | Needed capture |
|---|---|---|
GET /bmx/tunein/v1/playback/episode/{id} |
GET api.radiotime.com/profiles/{p<N>}/contents?version=1.3 then Tune.ashx?id=<episode> |
profiles/<id>/contents JSON |
GET /bmx/tunein/v1/playback/episodes/{id} |
same profile-contents JSON | profiles/<id>/contents JSON |
GET /bmx/tunein/v1/navigate |
GET opml.radiotime.com/?render=json (and Browse.ashx) |
OPML-as-JSON browse pages |
GET /bmx/tunein/v1/search |
GET api.radiotime.com/profiles?fulltextsearch=true&version=1.3&query=... |
search-results JSON |
GET /bmx/tunein/v1/search/next |
opaque cursor URL from a prior search | search next-page JSON |
How to collect
Run the service against live TuneIn with RECORD_INTERACTIONS on and the
proxy/recorder capturing the upstream category, drive the speaker (or the
/api/tunein/* UI) through podcast playback / browse / search, then copy the
sanitized radiotime responses here. Once captured, extend
pkg/testutils/tunein/handlers.go with the matching /profiles*, /?render=json
handlers and add the corresponding .http flows.
Keep captured fixtures sanitized (no real account ids/tokens); the radiotime station/program ids themselves are public catalog ids and are fine to keep.