Commit Graph
28 Commits
Author SHA1 Message Date
Tobias GesellchenandClaude Opus 4.7 30456d7ff8 test(integration): update http-client assertions for cloud-side AUX exclusion
Two HTTP client tests asserted AUX (id=10001 / sourceproviderid=9) was
present in /streaming/account/{a}/full and /streaming/account/{a}/sources.
After 2b40481 drops AUX from those cloud responses (matching real Bose
behaviour; see pkg/service/marge/marge.go getAccountSources), both
tests fail. Updates them to:

  - Expect 5 sources in /full (down from 6) — INTERNET_RADIO,
    LOCAL_INTERNET_RADIO, TUNEIN, RADIO_BROWSER, Spotify.
  - Expect ids 10002/10003/10004 (not 10001/...) in /sources.
  - Add explicit negative assertions that sourceproviderid=9 / id=10001
    is *not* present, so a regression that re-introduces AUX in cloud
    responses fails loud.

Verified via `make test-http-client`: 49 requests, 0 failures.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 12:14:18 +02:00
Tobias GesellchenandClaude Opus 4.7 979374b501 test(integration): pin #285 rename PUT behaviour at the HTTP layer
Adds rename_device.http between get_group.http and unregister_device.http
in the make test-http-client sequence. The new test fires the PUT
the speaker emits after a rename and asserts:

  - 200 OK, content type vnd.bose.streaming-v1.2+xml
  - the response carries the renamed value
  - createdOn matches the value captured during register_device.http
    (cross-request global), locking in the "first-paired" semantics
  - ipaddress is preserved from the prior power_on, not reset by the
    rename body's empty IP field
  - a mismatched body deviceid is rejected with 400

register_device.http captures the initial createdOn into a global so
the rename test can assert equality rather than a flakier
updatedOn != createdOn heuristic. The variant POST's stale
updatedOn === createdOn assertion is replaced with an upsert-aware
equality against the same captured global.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 19:04:41 +02:00
Tobias GesellchenandClaude Opus 4.7 ef2b775ce0 test(integration): add http-client test for stereo-pair Marge POST
Add an end-to-end IntelliJ HTTP Client test that replays the exact
request shape a SoundTouch 10 master sends to its configured Marge
server during stereo-pair formation (captured live in issue #252):

  POST /streaming/account/{accountId}/group/
  Authorization: Bearer <token>
  Content-Type:  application/vnd.bose.streaming-v1.2+xml

  <group>
    <masterDeviceId>...</masterDeviceId>
    <name>TEST</name>
    <roles>
      <groupRole><deviceId>...</deviceId><role>LEFT</role></groupRole>
      <groupRole><deviceId>...</deviceId><role>RIGHT</role></groupRole>
    </roles>
  </group>

Assertions cover the wire contract that fails loudly if regressed:
trailing-slash URL is matched, response is 201 Created with the vendor
media type, Location header references the new group under the
account, and the body echoes masterDeviceId, name, and both groupRole
entries.

Wired into the make test-http-client target, sequenced before
get_group.http so the GET runs against the post-create state.
get_group.http's assertion only checks for the presence of a <group>
element, so adding a populated group beforehand is compatible.

Refs #252

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 09:05:14 +02:00
Tobias GesellchenandClaude Sonnet 4.6 ca7f8d5453 feat: wire Amazon mock into http-client integration tests
- Add cmd/mock-amazon/main.go (mirrors mock-spotify, uses testutils/amazon)
- Add amazon-mock service to docker-compose.yml (port 8082)
- Add AMAZON_CLIENT_ID/SECRET/TOKEN_URL/PROFILE_URL to docker-compose.ci.yml
- Add amazon_registration.http: registers account via /mgmt/amazon/callback
  before the token-refresh test runs (mirrors spotify_registration.http)
- Update {{amazonRefreshToken}} in env to match mock response (Atzr|amazon-refresh-token)
- Log amazon-mock output on test failure in Makefile

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 20:30:06 +02:00
Tobias GesellchenandClaude Sonnet 4.6 f1c2b7a53f feat: implement HandleBoseAmazonToken and wire amazonService into Server
- Add GetAccountByRefreshToken to amazon.Service — the speaker sends
  the bare Atzr| refresh token (extracted from AmazonSecret JSON), not
  a surrogate, so lookup must match against Account.RefreshToken
- Add amazonService field, SetAmazonService and IsAmazonConfigured to
  Server (step 5 essentials required by the handler)
- Replace HandleBoseAmazonToken 501 stub with full implementation:
  lookup by refresh token → RefreshAccessToken; fallback to
  GetFreshToken; fallback to HandleBoseProxy if no service configured;
  scope intentionally omitted from response
- Add handler tests covering the by-refresh-token path (mock LWA
  server), the default-account path, and the no-service fallback
- Unlock assertions in post_oauth_token_amazon.http integration test

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 20:30:06 +02:00
Tobias Gesellchen 406180e4ce Prepare http-client test for Amazon 2026-04-29 20:30:06 +02:00
Tobias GesellchenandClaude Sonnet 4.6 5fbad7d315 feat: add Amazon Music source classification and fix ETag caching
- Recognize Amazon Music in learned sources (classifyAsAmazon) and
  AddSource dispatch, using CredentialTypeToken (cs1) not cs3
- Exclude Amazon from default sources: an empty-credential Amazon entry
  triggers the speaker's AmazonController to fail JSON parsing with
  MUSIC_SERVICE_ACCOUNT_LOGIN_FAILED; Amazon must only appear once a
  real OAuth token is present
- Merge missing defaults into stored sources at request time so devices
  with older Sources.xml still receive all current defaults
- Fix source providers ETag: was time.Now().UnixMilli() (always new),
  now a content hash so If-None-Match/304 works correctly
- Include default sources fingerprint in GetETagForAccount so adding a
  new default invalidates cached /full responses on speakers
- Refactor createLearnedSource into classifyLearnedSource +
  classifyAsX helpers to reduce cyclomatic complexity below linter limit
- Add regression test for two-device scenario matching production setup

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 20:30:06 +02:00
Tobias GesellchenandGitHub 9704e2d8ac Make the get_full_account test more comprehensive (#171)
https://github.com/gesellix/Bose-SoundTouch/issues/135
2026-04-17 23:15:52 +02:00
Tobias GesellchenandGitHub 68f8efce4e Improve parity with upstream (#155)
See https://github.com/gesellix/Bose-SoundTouch/issues/135
2026-04-07 14:44:05 +02:00
Tobias Gesellchen 153d387aaf Fix a complete flow for Spotify registration, preset 2026-04-06 21:15:15 +02:00
Tobias Gesellchen 740cf54b9d Cleanup Spotify tests 2026-04-06 15:22:06 +02:00
Tobias Gesellchen c4cf078d2a Add Spotify mock server and integration tests 2026-04-06 15:05:44 +02:00
Tobias GesellchenandGitHub 382567d67d Add .../api_versions.xml and .../musicprovider/{providerID}/is_eligible (#150) 2026-04-05 23:25:30 +02:00
Tobias GesellchenandGitHub de96b1f119 Add /streaming/account/{account}/presets/all (#149) 2026-04-05 23:10:53 +02:00
Tobias GesellchenandGitHub d22dc99c9e Add /streaming/account/{account}/devices (#148) 2026-04-05 10:16:22 +02:00
Tobias GesellchenandGitHub bd0e3d64a3 Add /streaming/account/{account}/sources (#147) 2026-04-05 01:09:02 +02:00
Tobias GesellchenandGitHub 50e45ab5f2 Add/improve e2e test cases (#144)
https://github.com/gesellix/Bose-SoundTouch/issues/135
2026-04-04 21:05:34 +02:00
Tobias Gesellchen c1e7d513b4 Add/improve e2e test cases 2026-04-04 18:53:59 +02:00
Tobias GesellchenandGitHub 7c92a785a4 Add/improve e2e tests (#142)
https://github.com/gesellix/Bose-SoundTouch/issues/135
2026-04-04 13:10:13 +02:00
Tobias GesellchenandGitHub b79a168084 Add/improve e2e test cases (#141)
https://github.com/gesellix/Bose-SoundTouch/issues/135
2026-04-04 12:22:58 +02:00
65f1a2565c feat: add spotify source registration and environment config for set_preset_5 integration test (#139)
Co-authored-by: Junie <junie@jetbrains.com>
2026-04-01 22:12:30 +02:00
aa7b2c28ab feat: improve Bose SoundTouch parity, Spotify integration, and data reliability (#138)
feat: improve Bose SoundTouch parity, Spotify integration, and data
reliability

- Update XML marshaling for ServicePreset and ServiceRecent to match
Bose parity requirements.
- Add support for adding music sources via
`/streaming/account/{account}/source`.
- Implement HandleBoseAccountToken for Spotify OAuth code exchange and
token persistence.
- Implement atomic file writes in the datastore to prevent data
corruption.
- Add startup logic to initialize default sources for existing devices.
- Expand test coverage with new parity regression and Spotify
integration tests.

---------

Co-authored-by: Junie <junie@jetbrains.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2026-04-01 21:55:52 +02:00
Tobias Gesellchen 71e3260823 Extend TuneIn support, add e2e tests 2026-03-30 00:52:00 +02:00
Tobias Gesellchen a8140ad4fd Fix AddDeviceToAccount 2026-03-29 19:14:48 +02:00
Tobias Gesellchen a06657f3f5 Add more e2e tests 2026-03-29 19:14:48 +02:00
Tobias Gesellchen 1478d97886 Cleanup .http client tests 2026-03-29 19:14:48 +02:00
Tobias GesellchenandGitHub e0a84d5904 Split register and unregister device tests (#133) 2026-03-27 22:03:21 +01:00
Tobias GesellchenandGitHub b04b0bcc32 Add account registration/login (#129) 2026-03-27 08:37:50 +01:00