@@ -9,29 +9,40 @@ import fs from 'fs-extra';
99import path from 'path' ;
1010
1111const TEST_HOST = 'localhost' ;
12+ import { createServer as createNetServer } from 'net' ;
13+
14+ /** Get an available port by briefly binding to port 0 */
15+ async function getAvailablePort ( ) {
16+ return new Promise ( ( resolve ) => {
17+ const srv = createNetServer ( ) ;
18+ srv . listen ( 0 , TEST_HOST , ( ) => {
19+ const port = srv . address ( ) . port ;
20+ srv . close ( ( ) => resolve ( port ) ) ;
21+ } ) ;
22+ } ) ;
23+ }
1224
1325describe ( 'Identity Provider' , ( ) => {
1426 let server ;
1527 let baseUrl ;
1628 const DATA_DIR = './test-data-idp' ;
1729
1830 before ( async ( ) => {
19- // Clean up any existing test data
2031 await fs . remove ( DATA_DIR ) ;
2132 await fs . ensureDir ( DATA_DIR ) ;
2233
23- // Create server with IdP enabled — use placeholder issuer, updated after listen
34+ const port = await getAvailablePort ( ) ;
35+ baseUrl = `http://${ TEST_HOST } :${ port } ` ;
36+
2437 server = createServer ( {
2538 logger : false ,
2639 root : DATA_DIR ,
2740 idp : true ,
28- idpIssuer : 'http://localhost' ,
41+ idpIssuer : baseUrl ,
2942 forceCloseConnections : true ,
3043 } ) ;
3144
32- await server . listen ( { port : 0 , host : TEST_HOST } ) ;
33- const address = server . server . address ( ) ;
34- baseUrl = `http://${ TEST_HOST } :${ address . port } ` ;
45+ await server . listen ( { port, host : TEST_HOST } ) ;
3546 } ) ;
3647
3748 after ( async ( ) => {
@@ -45,6 +56,8 @@ describe('Identity Provider', () => {
4556 assert . strictEqual ( res . status , 200 ) ;
4657
4758 const config = await res . json ( ) ;
59+ // Issuer has trailing slash for CTH compatibility
60+ assert . strictEqual ( config . issuer , baseUrl + '/' ) ;
4861 assert . ok ( config . authorization_endpoint ) ;
4962 assert . ok ( config . token_endpoint ) ;
5063 assert . ok ( config . jwks_uri ) ;
@@ -172,17 +185,18 @@ describe('Identity Provider - Accounts', () => {
172185 await fs . remove ( ACCOUNTS_DATA_DIR ) ;
173186 await fs . ensureDir ( ACCOUNTS_DATA_DIR ) ;
174187
188+ const port = await getAvailablePort ( ) ;
189+ accountsUrl = `http://${ TEST_HOST } :${ port } ` ;
190+
175191 server = createServer ( {
176192 logger : false ,
177193 root : ACCOUNTS_DATA_DIR ,
178194 idp : true ,
179- idpIssuer : 'http://localhost' ,
195+ idpIssuer : accountsUrl ,
180196 forceCloseConnections : true ,
181197 } ) ;
182198
183- await server . listen ( { port : 0 , host : TEST_HOST } ) ;
184- const address = server . server . address ( ) ;
185- accountsUrl = `http://${ TEST_HOST } :${ address . port } ` ;
199+ await server . listen ( { port, host : TEST_HOST } ) ;
186200 } ) ;
187201
188202 after ( async ( ) => {
@@ -253,16 +267,17 @@ describe('Identity Provider - Credentials Endpoint', () => {
253267 before ( async ( ) => {
254268 await fs . emptyDir ( CREDS_DATA_DIR ) ;
255269
270+ const port = await getAvailablePort ( ) ;
271+ credsUrl = `http://${ TEST_HOST } :${ port } ` ;
272+
256273 server = createServer ( {
257274 logger : false ,
258275 idp : true ,
259- idpIssuer : 'http://localhost' ,
276+ idpIssuer : credsUrl ,
260277 forceCloseConnections : true ,
261278 } ) ;
262279
263- await server . listen ( { port : 0 , host : TEST_HOST } ) ;
264- const address = server . server . address ( ) ;
265- credsUrl = `http://${ TEST_HOST } :${ address . port } ` ;
280+ await server . listen ( { port, host : TEST_HOST } ) ;
266281
267282 // Create a test user
268283 const res = await fetch ( `${ credsUrl } /.pods` , {
0 commit comments