diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9d4b188..6cfb429 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,6 +38,12 @@ jobs: uses: actions/checkout@v2 with: fetch-depth: 0 + - + name: Set up QEMU + uses: docker/setup-qemu-action@v1 + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 - name: Docker meta id: meta @@ -56,6 +62,7 @@ jobs: uses: docker/build-push-action@v2 with: context: . + platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 085423b..51b9b8f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,6 +16,8 @@ COPY yarn.lock . COPY .yarnrc.yml . COPY .yarn/releases ./.yarn/releases +ENV JEST_TIMEOUT=30000 + RUN apk add --no-cache --update --virtual .gyp \ vips-dev \ python3 \ diff --git a/src/server.ts b/src/server.ts index 3d80cfb..fc6bd65 100644 --- a/src/server.ts +++ b/src/server.ts @@ -169,7 +169,7 @@ function server( removeRegistrationRoute: bonobUrl .append({ pathname: REMOVE_REGISTRATION_ROUTE }) .pathname(), - version: opts.version, + version: serverOpts.version || DEFAULT_SERVER_OPTS.version, }); } ); diff --git a/tests/server.test.ts b/tests/server.test.ts index 5cead43..27dd4e7 100644 --- a/tests/server.test.ts +++ b/tests/server.test.ts @@ -13,7 +13,7 @@ import makeServer, { rangeFilterFor, } from "../src/server"; -import { SONOS_DISABLED, Sonos, Device } from "../src/sonos"; +import { Device, Sonos, SONOS_DISABLED } from "../src/sonos"; import { aDevice, aService } from "./builders"; import { InMemoryMusicService } from "./in_memory_music_service"; @@ -165,7 +165,10 @@ describe("RangeBytesFromFilter", () => { }); }); + describe("server", () => { + jest.setTimeout(Number.parseInt(process.env["JEST_TIMEOUT"] || "2000")); + beforeEach(() => { jest.clearAllMocks(); jest.resetAllMocks(); @@ -182,25 +185,46 @@ describe("server", () => { [bonobUrlWithNoContextPath, bonobUrlWithContextPath].forEach((bonobUrl) => { describe(`a bonobUrl of ${bonobUrl}`, () => { describe("/", () => { - describe("displaying of version", () => { - const server = makeServer( - SONOS_DISABLED, - aService(), - bonobUrl, - new InMemoryMusicService(), - { - version: "v123.456", - } - ); + describe("version", () => { + describe("when specified", () => { + const server = makeServer( + SONOS_DISABLED, + aService(), + bonobUrl, + new InMemoryMusicService(), + { + version: "v123.456", + } + ); + + it("should display it", async () => { + const res = await request(server) + .get(bonobUrl.append({ pathname: "/" }).pathname()) + .set("accept-language", acceptLanguage) + .send(); + + expect(res.status).toEqual(200); + expect(res.text).toContain('v123.456'); + }); + }); - it("should display it", async () => { - const res = await request(server) - .get(bonobUrl.append({ pathname: "/" }).pathname()) - .set("accept-language", acceptLanguage) - .send(); - - expect(res.status).toEqual(200); - expect(res.text).toMatch(/v123\.456/); + describe("when not specified", () => { + const server = makeServer( + SONOS_DISABLED, + aService(), + bonobUrl, + new InMemoryMusicService() + ); + + it("should display the default", async () => { + const res = await request(server) + .get(bonobUrl.append({ pathname: "/" }).pathname()) + .set("accept-language", acceptLanguage) + .send(); + + expect(res.status).toEqual(200); + expect(res.text).toContain("v?"); + }); }); }); diff --git a/tests/smapi_auth.test.ts b/tests/smapi_auth.test.ts index 027a442..d4db82c 100644 --- a/tests/smapi_auth.test.ts +++ b/tests/smapi_auth.test.ts @@ -63,24 +63,25 @@ describe("auth", () => { const expiresIn = "1h"; const secret = `secret-${uuid()}`; - const smapiLoginTokens = new JWTSmapiLoginTokens(clock, secret, expiresIn); + const key = uuid(); + const smapiLoginTokens = new JWTSmapiLoginTokens(clock, secret, expiresIn, () => key); describe("issuing a new token", () => { it("should issue a token that can then be verified", () => { - const serviceToken = uuid(); + const serviceToken = `service-token-${uuid()}`; const smapiToken = smapiLoginTokens.issue(serviceToken); - expect(smapiToken.token).toEqual( - jwt.sign( - { - serviceToken, - iat: Math.floor(clock.now().toDate().getDate() / 1000), - }, - secret + SMAPI_TOKEN_VERSION + smapiToken.key, - { expiresIn } - ) + const expected = jwt.sign( + { + serviceToken, + iat: clock.now().unix(), + }, + secret + SMAPI_TOKEN_VERSION + key, + { expiresIn } ); + + expect(smapiToken.token).toEqual(expected); expect(smapiToken.token).not.toContain(serviceToken); expect(smapiToken.token).not.toContain(secret); expect(smapiToken.token).not.toContain(":"); @@ -100,7 +101,7 @@ describe("auth", () => { clock, secret, expiresIn, - () => uuid(), + uuid, SMAPI_TOKEN_VERSION );