@@ -172,7 +172,13 @@ describe('useFeedConversion', () => {
172172
173173 const { result } = renderHook ( ( ) => useFeedConversion ( ) ) ;
174174 let thrownError :
175- | ( Error & { manualRetryStrategy ?: string ; retryAction ?: string ; kind ?: string ; code ?: string ; status ?: number } )
175+ | ( Error & {
176+ manualRetryStrategy ?: string ;
177+ retryAction ?: string ;
178+ kind ?: string ;
179+ code ?: string ;
180+ status ?: number ;
181+ } )
176182 | undefined ;
177183
178184 await act ( async ( ) => {
@@ -509,6 +515,119 @@ describe('useFeedConversion', () => {
509515 } ) ;
510516 } ) ;
511517
518+ it ( 'marks preview_unavailable for 422 extraction-warning responses' , async ( ) => {
519+ const createdFeed = {
520+ id : 'test-id' ,
521+ name : 'Test Feed' ,
522+ url : 'https://example.com' ,
523+ strategy : 'faraday' ,
524+ feed_token : 'test-token' ,
525+ public_url : 'https://example.com/feed' ,
526+ json_public_url : 'https://example.com/feed.json' ,
527+ created_at : '2024-01-01T00:00:00Z' ,
528+ updated_at : '2024-01-01T00:00:00Z' ,
529+ } ;
530+
531+ fetchMock
532+ . mockResolvedValueOnce (
533+ new Response (
534+ JSON . stringify ( {
535+ success : true ,
536+ data : { feed : createdFeed } ,
537+ } ) ,
538+ {
539+ status : 201 ,
540+ headers : { 'Content-Type' : 'application/json' } ,
541+ }
542+ )
543+ )
544+ . mockResolvedValueOnce (
545+ new Response (
546+ JSON . stringify ( {
547+ version : 'https://jsonfeed.org/version/1.1' ,
548+ title : 'Content Extraction Issue' ,
549+ items : [ ] ,
550+ } ) ,
551+ {
552+ status : 422 ,
553+ headers : { 'Content-Type' : 'application/feed+json' } ,
554+ }
555+ )
556+ ) ;
557+
558+ const { result } = renderHook ( ( ) => useFeedConversion ( ) ) ;
559+
560+ await act ( async ( ) => {
561+ await result . current . convertFeed ( 'https://example.com' , 'faraday' , 'testtoken' ) ;
562+ } ) ;
563+
564+ await waitFor ( ( ) => {
565+ expect ( result . current . result ?. readinessPhase ) . toBe ( 'preview_unavailable' ) ;
566+ expect ( result . current . result ?. preview . error ) . toBe ( 'Preview unavailable right now.' ) ;
567+ } ) ;
568+ } ) ;
569+
570+ it ( 'does not classify extraction warning payloads as feed_ready even on 200 responses' , async ( ) => {
571+ const createdFeed = {
572+ id : 'test-id' ,
573+ name : 'Test Feed' ,
574+ url : 'https://example.com' ,
575+ strategy : 'faraday' ,
576+ feed_token : 'test-token' ,
577+ public_url : 'https://example.com/feed' ,
578+ json_public_url : 'https://example.com/feed.json' ,
579+ created_at : '2024-01-01T00:00:00Z' ,
580+ updated_at : '2024-01-01T00:00:00Z' ,
581+ } ;
582+
583+ fetchMock
584+ . mockResolvedValueOnce (
585+ new Response (
586+ JSON . stringify ( {
587+ success : true ,
588+ data : { feed : createdFeed } ,
589+ } ) ,
590+ {
591+ status : 201 ,
592+ headers : { 'Content-Type' : 'application/json' } ,
593+ }
594+ )
595+ )
596+ . mockResolvedValueOnce (
597+ new Response (
598+ JSON . stringify ( {
599+ version : 'https://jsonfeed.org/version/1.1' ,
600+ title : 'Content Extraction Issue' ,
601+ description : 'We could not extract entries from https://example.com right now.' ,
602+ items : [
603+ {
604+ title : 'Preview unavailable for this source' ,
605+ content_text : 'No entries were extracted from https://example.com.' ,
606+ } ,
607+ ] ,
608+ } ) ,
609+ {
610+ status : 200 ,
611+ headers : { 'Content-Type' : 'application/feed+json' } ,
612+ }
613+ )
614+ ) ;
615+
616+ const { result } = renderHook ( ( ) => useFeedConversion ( ) ) ;
617+
618+ await act ( async ( ) => {
619+ await result . current . convertFeed ( 'https://example.com' , 'faraday' , 'testtoken' ) ;
620+ } ) ;
621+
622+ await waitFor ( ( ) => {
623+ expect ( result . current . result ?. readinessPhase ) . toBe ( 'preview_unavailable' ) ;
624+ expect ( result . current . result ?. preview . error ) . toBe (
625+ 'No entries could be extracted from this source right now.'
626+ ) ;
627+ expect ( result . current . result ?. preview . items ) . toEqual ( [ ] ) ;
628+ } ) ;
629+ } ) ;
630+
512631 it ( 'normalizes hostname-only input before creating a feed' , async ( ) => {
513632 const createdFeed = {
514633 id : 'test-id' ,
@@ -643,7 +762,13 @@ describe('useFeedConversion', () => {
643762
644763 const { result } = renderHook ( ( ) => useFeedConversion ( ) ) ;
645764 let thrownError :
646- | ( Error & { manualRetryStrategy ?: string ; retryAction ?: string ; kind ?: string ; code ?: string ; status ?: number } )
765+ | ( Error & {
766+ manualRetryStrategy ?: string ;
767+ retryAction ?: string ;
768+ kind ?: string ;
769+ code ?: string ;
770+ status ?: number ;
771+ } )
647772 | undefined ;
648773
649774 await act ( async ( ) => {
@@ -687,7 +812,13 @@ describe('useFeedConversion', () => {
687812
688813 const { result } = renderHook ( ( ) => useFeedConversion ( ) ) ;
689814 let thrownError :
690- | ( Error & { manualRetryStrategy ?: string ; retryAction ?: string ; kind ?: string ; code ?: string ; status ?: number } )
815+ | ( Error & {
816+ manualRetryStrategy ?: string ;
817+ retryAction ?: string ;
818+ kind ?: string ;
819+ code ?: string ;
820+ status ?: number ;
821+ } )
691822 | undefined ;
692823
693824 await act ( async ( ) => {
@@ -813,7 +944,13 @@ describe('useFeedConversion', () => {
813944 const { result } = renderHook ( ( ) => useFeedConversion ( ) ) ;
814945
815946 let thrownError :
816- | ( Error & { manualRetryStrategy ?: string ; retryAction ?: string ; kind ?: string ; code ?: string ; status ?: number } )
947+ | ( Error & {
948+ manualRetryStrategy ?: string ;
949+ retryAction ?: string ;
950+ kind ?: string ;
951+ code ?: string ;
952+ status ?: number ;
953+ } )
817954 | undefined ;
818955 await act ( async ( ) => {
819956 try {
0 commit comments