### GET /streaming/account/{accountId}/sources
GET {{host}}/streaming/account/{{accountId}}/sources
Accept: application/vnd.bose.streaming-v1.1+xml
Authorization: Bearer dummy-token

> {%
    client.test("Response is 200 OK", function() {
        client.assert(response.status === 200, "Response status is not 200");
    });

    client.test("Content-Type is correct", function() {
        client.assert(response.contentType.mimeType === "application/vnd.bose.streaming-v1.1+xml", "Wrong content type");
    });

    client.test("Response is XML and contains sources", function() {
        const doc = response.body;
        const sources = doc.documentElement;
        client.assert(sources.nodeName === "sources", "Root element is not 'sources'");

        const sourceList = sources.getElementsByTagName("source");
        client.assert(sourceList.length >= 3, "Expected at least 3 source elements, found " + sourceList.length);

        // AUX (id=10001, sourceproviderid=9) is intentionally excluded from
        // cloud responses — real Bose never emitted AUX in /full or /sources;
        // the speaker enumerates AUX from its own hardware via isLocal=true
        // in :8090/sources. See pkg/service/marge/marge.go getAccountSources
        // and commit 2b40481 (#195/#269).
        // INTERNET_RADIO (id=10002) is also excluded — it is a legacy stub
        // that AfterTouch no longer adds to new or existing devices. See
        // GetInitialSources() in pkg/service/datastore/datastore.go.
        const expectedIds = ["10003", "10004", "10005"];
        for (let i = 0; i < sourceList.length; i++) {
            const source = sourceList.item(i);
            const sourceId = source.getAttribute("id");
            client.assert(sourceId !== "10001", "Cloud /sources must not include AUX (id=10001)");
            if (i < expectedIds.length) {
                client.assert(sourceId === expectedIds[i], "Wrong source ID at index " + i + ": got " + sourceId + ", want " + expectedIds[i]);
            }
            client.assert(source.getAttribute("type") === "Audio", "Wrong source type for source " + sourceId);

            const credentials = source.getElementsByTagName("credential");
            client.assert(credentials.length > 0, "Missing credential for source " + sourceId);
            const credential = credentials.item(0);
            client.assert(credential.getAttribute("type").startsWith("token"), "Wrong credential type for source " + sourceId);

            const expectedChildren = ["createdOn", "updatedOn", "name", "sourceproviderid", "sourcename", "sourceSettings", "username"];
            expectedChildren.forEach(childName => {
                const children = source.getElementsByTagName(childName);
                client.assert(children.length > 0, "Missing " + childName + " for source " + sourceId);
            });
        }
    });
%}
