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>
This commit is contained in:
Tobias Gesellchen
2026-04-29 20:30:06 +02:00
co-authored by Claude Sonnet 4.6
parent 2ab98f2b6f
commit ca7f8d5453
6 changed files with 79 additions and 2 deletions
+2
View File
@@ -124,6 +124,7 @@ test-http-client:
--env-file /workdir/http-client.env.json \
--env ci \
/workdir/spotify_registration.http \
/workdir/amazon_registration.http \
/workdir/create_account.http \
/workdir/register_device.http \
/workdir/spotify_full_flow.http \
@@ -156,6 +157,7 @@ test-http-client:
EXIT_CODE=$$?; \
docker compose -f docker-compose.yml -f docker-compose.ci.yml logs soundtouch-service; \
docker compose -f docker-compose.yml -f docker-compose.ci.yml logs spotify-mock; \
docker compose -f docker-compose.yml -f docker-compose.ci.yml logs amazon-mock; \
docker compose -f docker-compose.yml -f docker-compose.ci.yml down; \
exit $$EXIT_CODE
+23
View File
@@ -0,0 +1,23 @@
// Package main provides a mock Amazon LWA server for testing purposes.
package main
import (
"flag"
"fmt"
"log"
"net/http"
"github.com/gesellix/bose-soundtouch/pkg/testutils/amazon"
)
func main() {
port := flag.Int("port", 8080, "Port to listen on")
flag.Parse()
log.Printf("Starting mock Amazon LWA server on port %d", *port)
if err := http.ListenAndServe(fmt.Sprintf(":%d", *port), amazon.NewAmazonHandler()); err != nil {
log.Fatal(err)
}
}
+4
View File
@@ -10,3 +10,7 @@ services:
- SPOTIFY_CLIENT_SECRET=mock-secret
- SPOTIFY_TOKEN_URL=http://spotify-mock:8080/api/token
- SPOTIFY_API_BASE=http://spotify-mock:8080
- AMAZON_CLIENT_ID=mock-amazon-id
- AMAZON_CLIENT_SECRET=mock-amazon-secret
- AMAZON_TOKEN_URL=http://amazon-mock:8080/auth/o2/token
- AMAZON_PROFILE_URL=http://amazon-mock:8080/user/profile
+12
View File
@@ -49,6 +49,18 @@ services:
networks:
- soundtouch-test-net
amazon-mock:
image: golang:1.26.2-alpine
container_name: amazon-mock
working_dir: /app
volumes:
- .:/app
command: go run ./cmd/mock-amazon/main.go -port 8080
ports:
- "8082:8080"
networks:
- soundtouch-test-net
networks:
soundtouch-test-net:
name: soundtouch-test-net
@@ -0,0 +1,36 @@
### Amazon Music Initial Registration Flow
# @name Init Amazon Flow
POST {{host}}/mgmt/amazon/init
Authorization: Basic admin change_me!
> {%
client.global.set("redirectUrl", response.body.redirectUrl);
%}
###
# @name Amazon Callback
# Simulates the user being redirected back from Amazon LWA with a code
GET {{host}}/mgmt/amazon/callback?code=mock-auth-code
###
# @name Verify Accounts
GET {{host}}/mgmt/amazon/accounts
Authorization: Basic admin change_me!
> {%
client.test("Account exists", function() {
client.assert(response.body.accounts.length > 0, "No accounts found");
var found = false;
for (var i = 0; i < response.body.accounts.length; i++) {
if (response.body.accounts[i].user_id === "amzn1.account.TESTUSER") {
found = true;
client.assert(response.body.accounts[i].display_name === "Amazon Test User", "Display name mismatch");
break;
}
}
client.assert(found, "Account 'amzn1.account.TESTUSER' not found in " + JSON.stringify(response.body.accounts));
});
%}
@@ -18,7 +18,7 @@
"spotifyRefreshToken": "example-spotify-refresh-token",
"spotifyDisplayName": "For Lovers, Not Killers",
"amazonProviderID": "20",
"amazonRefreshToken": "example-amazon-refresh-token",
"amazonRefreshToken": "Atzr|amazon-refresh-token",
"bmxApiKey": "bmx-api-key",
"qplayProviderID": "26"
},
@@ -41,7 +41,7 @@
"spotifyRefreshToken": "example-spotify-refresh-token",
"spotifyDisplayName": "For Lovers, Not Killers",
"amazonProviderID": "20",
"amazonRefreshToken": "example-amazon-refresh-token",
"amazonRefreshToken": "Atzr|amazon-refresh-token",
"bmxApiKey": "bmx-api-key",
"qplayProviderID": "26"
}