@@ -51,8 +51,15 @@ function callTool(base: string, name: string, accessToken?: string): Promise<Htt
5151describe ( 'Lazy Auth example mount' , ( ) => {
5252 let server : http . Server ;
5353 let base : string ;
54+ let savedPublicUrl : string | undefined ;
5455
5556 beforeAll ( async ( ) => {
57+ // These tests rely on the package's per-request Host resolution (no baseUri
58+ // passed below), so an ambient PUBLIC_URL would pin advertised URLs and
59+ // break the assertions. Clear it for the duration and restore afterwards.
60+ savedPublicUrl = process . env . PUBLIC_URL ;
61+ delete process . env . PUBLIC_URL ;
62+
5663 const app = express ( ) ;
5764 // Mirror src/index.ts: the example mounts before the host's middleware
5865 // and routes.
@@ -75,6 +82,8 @@ describe('Lazy Auth example mount', () => {
7582
7683 afterAll ( async ( ) => {
7784 await new Promise ( ( resolve ) => server . close ( resolve ) ) ;
85+ if ( savedPublicUrl === undefined ) delete process . env . PUBLIC_URL ;
86+ else process . env . PUBLIC_URL = savedPublicUrl ;
7887 } ) ;
7988
8089 it ( 'serves public MCP requests without auth' , async ( ) => {
@@ -95,12 +104,24 @@ describe('Lazy Auth example mount', () => {
95104 expect ( res . body ) . toContain ( 'Lazy Auth' ) ;
96105 } ) ;
97106
107+ it ( 'serves a public tool call without auth' , async ( ) => {
108+ const res = await callTool ( base , 'show_auth_button' ) ;
109+ expect ( res . status ) . toBe ( 200 ) ;
110+ expect ( res . headers [ 'www-authenticate' ] ) . toBeUndefined ( ) ;
111+ } ) ;
112+
98113 it ( 'answers 401 with resource_metadata under the mount path for protected tools' , async ( ) => {
99114 const res = await callTool ( base , 'get_secret' ) ;
100115 expect ( res . status ) . toBe ( 401 ) ;
101116 expect ( res . headers [ 'www-authenticate' ] ) . toContain ( `resource_metadata="${ base } /lazy-auth/auth/prm"` ) ;
102117 } ) ;
103118
119+ it ( 'answers 401 with invalid_token for a bad bearer token' , async ( ) => {
120+ const res = await callTool ( base , 'get_secret' , 'not-a-real-token' ) ;
121+ expect ( res . status ) . toBe ( 401 ) ;
122+ expect ( res . headers [ 'www-authenticate' ] ) . toContain ( 'invalid_token' ) ;
123+ } ) ;
124+
104125 it ( 'advertises mount-prefixed URLs in PRM and AS metadata' , async ( ) => {
105126 const prm = JSON . parse ( ( await request ( `${ base } /lazy-auth/auth/prm` ) ) . body ) ;
106127 expect ( prm . resource ) . toBe ( `${ base } /lazy-auth/mcp` ) ;
@@ -172,3 +193,38 @@ describe('Lazy Auth example mount', () => {
172193 expect ( secretRes . body ) . toContain ( 'the-answer-is-42' ) ;
173194 } ) ;
174195} ) ;
196+
197+ describe ( 'mountLazyAuthExample PUBLIC_URL derivation' , ( ) => {
198+ let savedPublicUrl : string | undefined ;
199+
200+ beforeEach ( ( ) => {
201+ savedPublicUrl = process . env . PUBLIC_URL ;
202+ delete process . env . PUBLIC_URL ;
203+ } ) ;
204+
205+ afterEach ( ( ) => {
206+ if ( savedPublicUrl === undefined ) delete process . env . PUBLIC_URL ;
207+ else process . env . PUBLIC_URL = savedPublicUrl ;
208+ } ) ;
209+
210+ it ( 'derives PUBLIC_URL from baseUri, stripping trailing slashes and appending the mount path' , ( ) => {
211+ mountLazyAuthExample ( express ( ) , 'https://example.test/' ) ;
212+ expect ( process . env . PUBLIC_URL ) . toBe ( 'https://example.test/lazy-auth' ) ;
213+ } ) ;
214+
215+ it ( 'handles a baseUri with no trailing slash' , ( ) => {
216+ mountLazyAuthExample ( express ( ) , 'https://example.test' ) ;
217+ expect ( process . env . PUBLIC_URL ) . toBe ( 'https://example.test/lazy-auth' ) ;
218+ } ) ;
219+
220+ it ( 'does not override an explicitly set PUBLIC_URL' , ( ) => {
221+ process . env . PUBLIC_URL = 'https://tunnel.example/lazy-auth' ;
222+ mountLazyAuthExample ( express ( ) , 'https://example.test/' ) ;
223+ expect ( process . env . PUBLIC_URL ) . toBe ( 'https://tunnel.example/lazy-auth' ) ;
224+ } ) ;
225+
226+ it ( 'leaves PUBLIC_URL unset when no baseUri is provided' , ( ) => {
227+ mountLazyAuthExample ( express ( ) ) ;
228+ expect ( process . env . PUBLIC_URL ) . toBeUndefined ( ) ;
229+ } ) ;
230+ } ) ;
0 commit comments