From f3f6005b7f158e16c0b00122cc3b96a0915b73bf Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Fri, 23 Oct 2026 19:45:08 +1100 Subject: [PATCH 1/2] fix port problem with test cases --- tests/setup.js | 22 ++++++++++++++++++++++ tests/tx/syndication-routes.test.js | 5 +++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/tests/setup.js b/tests/setup.js index a1aa7bab..4f39aad4 100644 --- a/tests/setup.js +++ b/tests/setup.js @@ -32,6 +32,28 @@ afterAll(async () => { await new Promise(resolve => setTimeout(resolve, 100)); }); +// supertest's request(app) starts the app on a random port with app.listen(0) - on every +// address, which is :: where there is IPv6 - and then connects to 127.0.0.1:port. On macOS +// another process can be listening on 127.0.0.1 at that same port (a specific address and the +// wildcard can share a port), and the specific binding gets the connection: now and then a +// request hangs, or fails with "Parse Error: Expected HTTP/". So connect to the loopback +// address of the family the server actually listens on: [::1] for ::, else 127.0.0.1. +// (Listening on 127.0.0.1 instead isn't possible here: with a host, listen() is asynchronous, +// and supertest needs the port at once.) +{ + const Test = require('supertest/lib/test.js'); + const { Server: TlsServer } = require('tls'); + Test.prototype.serverAddress = function (app, path) { + if (!app.address()) { + this._server = app.listen(0); + } + const { address, port } = app.address(); + const host = address === '::' ? '[::1]' : '127.0.0.1'; + const protocol = app instanceof TlsServer ? 'https' : 'http'; + return `${protocol}://${host}:${port}${path}`; + }; +} + // Increase timeout for integration tests jest.setTimeout(30000); diff --git a/tests/tx/syndication-routes.test.js b/tests/tx/syndication-routes.test.js index 0e0ed2a3..df2c9cb4 100644 --- a/tests/tx/syndication-routes.test.js +++ b/tests/tx/syndication-routes.test.js @@ -118,14 +118,15 @@ describe('syndication turned on', () => { }); test('the feed is Atom, with both entries', async () => { - const res = await request(app).get(`${BASE}/syndication`).set('Accept', 'application/atom+xml'); + // the Host is set: supertest's own is whichever loopback address the OS chose (127.0.0.1 or [::1]) + const res = await request(app).get(`${BASE}/syndication`).set('Accept', 'application/atom+xml').set('Host', 'localhost:8080'); expect(res.status).toBe(200); expect(res.headers['content-type']).toMatch(/^application\/atom\+xml/); expect(res.headers['cache-control']).toBe('no-cache'); const feed = parse(res.text); expect(feed.title).toBe('Test Server Syndication Feed (FHIR 5.0)'); expect(feed.entry).toHaveLength(2); - expect(feed.link.find(l => l['@rel'] === 'self')['@href']).toMatch(/^http:\/\/127\.0\.0\.1:\d+\/tx\/r5\/syndication$/); + expect(feed.link.find(l => l['@rel'] === 'self')['@href']).toBe('http://localhost:8080/tx/r5/syndication'); const cs = feed.entry.find(e => e.category['@term'] === 'FHIR_CodeSystem'); expect(cs.title).toBe('Syndication Test'); expect(cs.summary).toBe('A code system for the syndication feed tests'); From 113913069255096c28d1e8181e81e3d9eaf64079 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Fri, 23 Oct 2026 19:46:01 +1100 Subject: [PATCH 2/2] tx summary --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1236813f..5c11fbeb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -86,7 +86,7 @@ Note: We are heading towards a 1.0.0 release. ### Tx Conformance Statement -(paste) +FHIRsmith v0.18.0 passed all 3860 HL7 terminology service tests (modes tx.fhir.org+omop+general+snomed+mimetypes+icd-11+icf+closure, tests v1.9.6, runner v7.0.3) ## [0.17.0] - 2026-10-17