@@ -2223,6 +2223,32 @@ describe('URL Inspector Semrush BP integration', () => {
22232223 expect ( response . status ) . to . equal ( 200 ) ;
22242224 expect ( body . stats . totalCitations ) . to . equal ( 77 ) ;
22252225 } ) ;
2226+
2227+ it ( 're-throws 503 config errors without falling back' , async ( ) => {
2228+ const configError = Object . assign ( new Error ( 'missing element id' ) , { status : 503 } ) ;
2229+ queryBpCitationsByUrlStub . rejects ( configError ) ;
2230+ const { context, rpcStub } = createSemrushContext ( { brandId : BRAND_ID } ) ;
2231+ rpcStub . resolves ( { data : [ { week : null , value : 10 } ] , error : null } ) ;
2232+
2233+ const handler = Handlers . createUrlInspectorStatsHandler (
2234+ async ( ) => ( { organization : { getId : ( ) => ORG_ID } } ) ,
2235+ ) ;
2236+ await expect ( handler ( context ) ) . to . be . rejectedWith ( 'missing element id' ) ;
2237+ } ) ;
2238+
2239+ it ( 'passes hostname (not full URL) as domain to queryBpCitationsByUrl' , async ( ) => {
2240+ const { context, rpcStub } = createSemrushContext ( { brandId : BRAND_ID } , { siteId : 'https://www.example.com' } ) ;
2241+ rpcStub . resolves ( { data : [ { week : null , value : 0 } ] , error : null } ) ;
2242+
2243+ const handler = Handlers . createUrlInspectorStatsHandler (
2244+ async ( ) => ( { organization : { getId : ( ) => ORG_ID } } ) ,
2245+ ) ;
2246+ await handler ( context ) ;
2247+
2248+ const callArgs = queryBpCitationsByUrlStub . firstCall . args [ 5 ] ;
2249+ expect ( callArgs . domain ) . to . equal ( 'www.example.com' ) ;
2250+ expect ( callArgs . urlFragment ) . to . equal ( 'https://www.example.com' ) ;
2251+ } ) ;
22262252 } ) ;
22272253
22282254 describe ( 'createUrlInspectorOwnedUrlsHandler — Semrush path' , ( ) => {
@@ -2306,7 +2332,54 @@ describe('URL Inspector Semrush BP integration', () => {
23062332
23072333 expect ( response . status ) . to . equal ( 200 ) ;
23082334 expect ( body . urls [ 0 ] . citations ) . to . equal ( 5 ) ;
2309- expect ( context . log . error ) . to . have . been . calledWithMatch ( / S e m r u s h B P e r r o r / ) ;
2335+ expect ( context . log . warn ) . to . have . been . calledWithMatch ( / S e m r u s h B P e r r o r / ) ;
2336+ } ) ;
2337+
2338+ it ( 'preserves successful rows when one URL Semrush call fails' , async ( ) => {
2339+ queryBpCitationsByUrlStub . onFirstCall ( ) . resolves ( {
2340+ citations : 99 , promptsCited : 3 , prompts : [ ] ,
2341+ } ) ;
2342+ queryBpCitationsByUrlStub . onSecondCall ( ) . rejects ( new Error ( 'partial fail' ) ) ;
2343+ const row1 = { ...ownedRow ( ) , url : 'https://example.com/page1' , citations : 1 } ;
2344+ const row2 = { ...ownedRow ( ) , url : 'https://example.com/page2' , citations : 2 } ;
2345+ const { context, rpcStub } = createSemrushContext ( { brandId : BRAND_ID } ) ;
2346+ rpcStub . resolves ( { data : [ row1 , row2 ] , error : null } ) ;
2347+
2348+ const handler = Handlers . createUrlInspectorOwnedUrlsHandler (
2349+ async ( ) => ( { organization : { getId : ( ) => ORG_ID } } ) ,
2350+ ) ;
2351+ const response = await handler ( context ) ;
2352+ const body = await response . json ( ) ;
2353+
2354+ expect ( response . status ) . to . equal ( 200 ) ;
2355+ expect ( body . urls [ 0 ] . citations ) . to . equal ( 99 ) ;
2356+ expect ( body . urls [ 1 ] . citations ) . to . equal ( 2 ) ;
2357+ } ) ;
2358+
2359+ it ( 're-throws 503 config errors in owned-urls' , async ( ) => {
2360+ const configError = Object . assign ( new Error ( 'missing element id' ) , { status : 503 } ) ;
2361+ queryBpCitationsByUrlStub . rejects ( configError ) ;
2362+ const { context, rpcStub } = createSemrushContext ( { brandId : BRAND_ID } ) ;
2363+ rpcStub . resolves ( { data : [ ownedRow ( ) ] , error : null } ) ;
2364+
2365+ const handler = Handlers . createUrlInspectorOwnedUrlsHandler (
2366+ async ( ) => ( { organization : { getId : ( ) => ORG_ID } } ) ,
2367+ ) ;
2368+ await expect ( handler ( context ) ) . to . be . rejectedWith ( 'missing element id' ) ;
2369+ } ) ;
2370+
2371+ it ( 'passes hostname (not full URL) as domain in per-URL query' , async ( ) => {
2372+ const { context, rpcStub } = createSemrushContext ( { brandId : BRAND_ID } ) ;
2373+ rpcStub . resolves ( { data : [ ownedRow ( ) ] , error : null } ) ;
2374+
2375+ const handler = Handlers . createUrlInspectorOwnedUrlsHandler (
2376+ async ( ) => ( { organization : { getId : ( ) => ORG_ID } } ) ,
2377+ ) ;
2378+ await handler ( context ) ;
2379+
2380+ const callArgs = queryBpCitationsByUrlStub . firstCall . args [ 5 ] ;
2381+ expect ( callArgs . domain ) . to . equal ( 'example.com' ) ;
2382+ expect ( callArgs . urlFragment ) . to . equal ( 'https://example.com/page' ) ;
23102383 } ) ;
23112384 } ) ;
23122385
@@ -2370,5 +2443,30 @@ describe('URL Inspector Semrush BP integration', () => {
23702443 expect ( body . prompts [ 0 ] . prompt ) . to . equal ( 'fallback prompt' ) ;
23712444 expect ( context . log . error ) . to . have . been . calledWithMatch ( / S e m r u s h B P e r r o r / ) ;
23722445 } ) ;
2446+
2447+ it ( 're-throws 503 config errors in url-prompts' , async ( ) => {
2448+ const configError = Object . assign ( new Error ( 'missing element id' ) , { status : 503 } ) ;
2449+ queryBpCitationsByUrlStub . rejects ( configError ) ;
2450+ const { context } = createSemrushContext ( { brandId : BRAND_ID } ) ;
2451+
2452+ const handler = Handlers . createUrlInspectorUrlPromptsHandler (
2453+ async ( ) => ( { organization : { getId : ( ) => ORG_ID } } ) ,
2454+ ) ;
2455+ const ctxWithUrl = { ...context , data : { siteId : SITE_ID , urlId : 'https://example.com/page' } } ;
2456+ await expect ( handler ( ctxWithUrl ) ) . to . be . rejectedWith ( 'missing element id' ) ;
2457+ } ) ;
2458+
2459+ it ( 'passes hostname as domain for url-prompts when urlId is a URL' , async ( ) => {
2460+ const { context } = createSemrushContext ( { brandId : BRAND_ID } ) ;
2461+
2462+ const handler = Handlers . createUrlInspectorUrlPromptsHandler (
2463+ async ( ) => ( { organization : { getId : ( ) => ORG_ID } } ) ,
2464+ ) ;
2465+ const ctxWithUrl = { ...context , data : { siteId : SITE_ID , urlId : 'https://example.com/page' } } ;
2466+ await handler ( ctxWithUrl ) ;
2467+
2468+ const callArgs = queryBpCitationsByUrlStub . firstCall . args [ 5 ] ;
2469+ expect ( callArgs . domain ) . to . equal ( 'example.com' ) ;
2470+ } ) ;
23732471 } ) ;
23742472} ) ;
0 commit comments