diff --git a/Makefile b/Makefile index 9c4c038..ddbd2b4 100644 --- a/Makefile +++ b/Makefile @@ -169,6 +169,7 @@ test-http-client: /workdir/get_api_versions.http \ /workdir/post_musicprovider_is_eligible.http \ /workdir/get_full_account.http \ + /workdir/create_group.http \ /workdir/get_group.http \ /workdir/unregister_device.http \ --report; \ diff --git a/tests/integration/http-client/create_group.http b/tests/integration/http-client/create_group.http new file mode 100644 index 0000000..c69972e --- /dev/null +++ b/tests/integration/http-client/create_group.http @@ -0,0 +1,66 @@ +### POST /streaming/account/{{accountId}}/group/ (Create Stereo Pair via Marge) +### +### Replays the exact shape a SoundTouch 10 master sends when it forwards the +### addGroup payload to its configured Marge server while forming a stereo pair +### (issue #252). Notable properties of the wire contract this exercises: +### +### * URL has a trailing slash ("/group/", not "/group"). +### * elements have no . +### * No (this is the master-bound payload). +### * No numeric group attribute and no on the request. +### * Content-Type is the vendor-specific media type. +### +### The speaker retries this POST every 15 s while in AddingMaster state; if +### AfterTouch doesn't accept it, the group never completes and reverts to +### NoGroup after a timeout. +POST {{host}}/streaming/account/{{accountId}}/group/ +Content-Type: application/vnd.bose.streaming-v1.2+xml +Authorization: Bearer {{token}} +User-Agent: Bose_Lisa/27.0.6 +Accept: application/vnd.bose.streaming-v1.2+xml + + + + {{deviceId}} + TEST + + + {{deviceId}} + LEFT + + + {{macAddress2}} + RIGHT + + + + +> {% + client.test("Group created successfully", function() { + client.assert(response.status === 201, "Response status should be 201 Created, got " + response.status); + client.assert(response.contentType.mimeType === "application/vnd.bose.streaming-v1.2+xml", + "Response Content-Type should be application/vnd.bose.streaming-v1.2+xml, got '" + response.contentType.mimeType + "'"); + client.assert(response.headers.valueOf("Location") !== null, + "Response should include a Location header pointing to the new group"); + client.assert(response.headers.valueOf("Location").includes("/account/" + client.variables.environment.get("accountId") + "/group/"), + "Location header should reference the new group under the account, got '" + response.headers.valueOf("Location") + "'"); + }); + + client.test("Response body echoes the requested group", function() { + const doc = response.body; + const group = doc.getElementsByTagName("group")[0]; + client.assert(group !== undefined, "Response body should contain "); + + const master = group.getElementsByTagName("masterDeviceId")[0]; + client.assert(master !== undefined, "Response body should contain "); + client.assert(master.textContent === client.variables.environment.get("deviceId"), + "masterDeviceId should match the request, got '" + master.textContent + "'"); + + const name = group.getElementsByTagName("name")[0]; + client.assert(name !== undefined, "Response body should contain "); + client.assert(name.textContent === "TEST", "name should match the requested 'TEST', got '" + name.textContent + "'"); + + const roles = group.getElementsByTagName("groupRole"); + client.assert(roles.length === 2, "Response should contain exactly 2 entries, got " + roles.length); + }); +%} \ No newline at end of file