@@ -94,6 +94,19 @@ test('a canonical naming another document skips the settle phase', async () => {
9494 assert . equal ( result . isIndexable , false ) ;
9595 assert . equal ( result . reason , 'canonical-mismatch' ) ;
9696 assert . equal ( result . timings . settle , undefined ) ;
97+ assert . equal ( result . declaredCanonical , `${ base } /other` , 'the bail still says where the page points' ) ;
98+ } ) ;
99+
100+ test ( 'the post-settle verdict reports the declared canonical too, and an indexable page reports none' , async ( ) => {
101+ const settled = await render ( '/canonical-elsewhere' , { navigation : { skipSettleWhenNonIndexable : false } } ) ;
102+ await settled . close ( ) ;
103+ assert . notEqual ( settled . timings . settle , undefined , 'this one reached its verdict after the settle' ) ;
104+ assert . equal ( settled . reason , 'canonical-mismatch' ) ;
105+ assert . equal ( settled . declaredCanonical , `${ base } /other` ) ;
106+
107+ const fine = await render ( '/fine' ) ;
108+ await fine . close ( ) ;
109+ assert . equal ( fine . declaredCanonical , undefined ) ;
97110} ) ;
98111
99112// A 404's settle is skipped BY THE BAIL, not by the `status >= 400` abort: that abort only stops
@@ -178,11 +191,13 @@ test('indexVerdict: the shared verdict both paths use', () => {
178191 assert . deepEqual ( indexVerdict ( { canonicalHref : 'https://x.test/other' , noindex : false } , page , false ) , {
179192 isIndexable : false ,
180193 reason : 'canonical-mismatch' ,
194+ declaredCanonical : 'https://x.test/other' ,
181195 } ) ;
182196 // noindex outranks a canonical verdict when both fire, so the reason stays the stronger signal.
183197 assert . deepEqual ( indexVerdict ( { canonicalHref : 'https://x.test/other' , noindex : true } , page , false ) , {
184198 isIndexable : false ,
185199 reason : 'noindex' ,
200+ declaredCanonical : 'https://x.test/other' ,
186201 } ) ;
187202} ) ;
188203
@@ -209,3 +224,32 @@ test('with the flag on, a client-side redirect to an INDEXABLE page still render
209224 assert . equal ( new URL ( result . redirectedTo ! ) . pathname , '/fine' ) ;
210225 assert . notEqual ( result . timings . settle , undefined , 'and it must still settle' ) ;
211226} ) ;
227+
228+ test ( 'indexVerdict: a canonical naming another URL is reported, resolved against the page and without its fragment' , ( ) => {
229+ const page = 'https://x.test/product/prd-1/old-slug.jsp?color=red' ;
230+ assert . equal (
231+ indexVerdict ( { canonicalHref : 'https://x.test/product/prd-1/new-slug.jsp' , noindex : false } , page , false )
232+ . declaredCanonical ,
233+ 'https://x.test/product/prd-1/new-slug.jsp'
234+ ) ;
235+ // Resolved exactly as the verdict resolved it, so a path-absolute href names the page's own origin.
236+ assert . equal (
237+ indexVerdict ( { canonicalHref : '/product/prd-1/new-slug.jsp#top' , noindex : false } , page , false ) . declaredCanonical ,
238+ 'https://x.test/product/prd-1/new-slug.jsp'
239+ ) ;
240+ // A noindex page that also names another canonical still says where it points.
241+ assert . equal (
242+ indexVerdict ( { canonicalHref : 'https://x.test/other' , noindex : true } , page , false ) . declaredCanonical ,
243+ 'https://x.test/other'
244+ ) ;
245+ // A strict variant names this document re-spelled: reported too, it is still the origin's spelling.
246+ assert . equal (
247+ indexVerdict ( { canonicalHref : 'https://x.test/p%20q' , noindex : false } , 'https://x.test/p+q' , true )
248+ . declaredCanonical ,
249+ 'https://x.test/p%20q'
250+ ) ;
251+ // Nothing to report: indexable, no canonical, or a noindex page whose canonical is itself.
252+ assert . equal ( 'declaredCanonical' in indexVerdict ( { canonicalHref : page , noindex : false } , page , false ) , false ) ;
253+ assert . equal ( 'declaredCanonical' in indexVerdict ( { canonicalHref : null , noindex : true } , page , false ) , false ) ;
254+ assert . equal ( 'declaredCanonical' in indexVerdict ( { canonicalHref : page , noindex : true } , page , false ) , false ) ;
255+ } ) ;
0 commit comments