@@ -84,6 +84,39 @@ function createHarness(params?: {
8484 } ;
8585}
8686
87+ async function deliverFinalAnswer ( harness : ReturnType < typeof createHarness > , text : string ) {
88+ return harness . deliverLaneText ( {
89+ laneName : "answer" ,
90+ text,
91+ payload : { text } ,
92+ infoKind : "final" ,
93+ } ) ;
94+ }
95+
96+ function seedArchivedAnswerPreview ( harness : ReturnType < typeof createHarness > ) {
97+ harness . archivedAnswerPreviews . push ( {
98+ messageId : 5555 ,
99+ textSnapshot : "Partial streaming..." ,
100+ deleteIfUnused : true ,
101+ } ) ;
102+ }
103+
104+ async function expectFinalEditFallbackToSend ( params : {
105+ harness : ReturnType < typeof createHarness > ;
106+ text : string ;
107+ expectedLogSnippet : string ;
108+ } ) {
109+ const result = await deliverFinalAnswer ( params . harness , params . text ) ;
110+ expect ( result ) . toBe ( "sent" ) ;
111+ expect ( params . harness . editPreview ) . toHaveBeenCalledTimes ( 1 ) ;
112+ expect ( params . harness . sendPayload ) . toHaveBeenCalledWith (
113+ expect . objectContaining ( { text : params . text } ) ,
114+ ) ;
115+ expect ( params . harness . log ) . toHaveBeenCalledWith (
116+ expect . stringContaining ( params . expectedLogSnippet ) ,
117+ ) ;
118+ }
119+
87120describe ( "createLaneTextDeliverer" , ( ) => {
88121 it ( "finalizes text-only replies by editing an existing preview message" , async ( ) => {
89122 const harness = createHarness ( { answerMessageId : 999 } ) ;
@@ -198,21 +231,11 @@ describe("createLaneTextDeliverer", () => {
198231 const harness = createHarness ( { answerMessageId : 999 } ) ;
199232 harness . editPreview . mockRejectedValue ( new Error ( "400: Bad Request: message to edit not found" ) ) ;
200233
201- const result = await harness . deliverLaneText ( {
202- laneName : "answer" ,
234+ await expectFinalEditFallbackToSend ( {
235+ harness ,
203236 text : "Hello final" ,
204- payload : { text : "Hello final" } ,
205- infoKind : "final" ,
237+ expectedLogSnippet : "edit target missing with no alternate preview; falling back" ,
206238 } ) ;
207-
208- expect ( result ) . toBe ( "sent" ) ;
209- expect ( harness . editPreview ) . toHaveBeenCalledTimes ( 1 ) ;
210- expect ( harness . sendPayload ) . toHaveBeenCalledWith (
211- expect . objectContaining ( { text : "Hello final" } ) ,
212- ) ;
213- expect ( harness . log ) . toHaveBeenCalledWith (
214- expect . stringContaining ( "edit target missing with no alternate preview; falling back" ) ,
215- ) ;
216239 } ) ;
217240
218241 it ( "falls back to sendPayload when the final edit fails before reaching Telegram" , async ( ) => {
@@ -451,19 +474,10 @@ describe("createLaneTextDeliverer", () => {
451474
452475 it ( "falls back when an archived preview edit target is missing and no alternate preview exists" , async ( ) => {
453476 const harness = createHarness ( ) ;
454- harness . archivedAnswerPreviews . push ( {
455- messageId : 5555 ,
456- textSnapshot : "Partial streaming..." ,
457- deleteIfUnused : true ,
458- } ) ;
477+ seedArchivedAnswerPreview ( harness ) ;
459478 harness . editPreview . mockRejectedValue ( new Error ( "400: Bad Request: message to edit not found" ) ) ;
460479
461- const result = await harness . deliverLaneText ( {
462- laneName : "answer" ,
463- text : "Complete final answer" ,
464- payload : { text : "Complete final answer" } ,
465- infoKind : "final" ,
466- } ) ;
480+ const result = await deliverFinalAnswer ( harness , "Complete final answer" ) ;
467481
468482 expect ( harness . editPreview ) . toHaveBeenCalledTimes ( 1 ) ;
469483 expect ( harness . sendPayload ) . toHaveBeenCalledWith (
@@ -475,19 +489,10 @@ describe("createLaneTextDeliverer", () => {
475489
476490 it ( "keeps the active preview when an archived final edit target is missing" , async ( ) => {
477491 const harness = createHarness ( { answerMessageId : 999 } ) ;
478- harness . archivedAnswerPreviews . push ( {
479- messageId : 5555 ,
480- textSnapshot : "Partial streaming..." ,
481- deleteIfUnused : true ,
482- } ) ;
492+ seedArchivedAnswerPreview ( harness ) ;
483493 harness . editPreview . mockRejectedValue ( new Error ( "400: Bad Request: message to edit not found" ) ) ;
484494
485- const result = await harness . deliverLaneText ( {
486- laneName : "answer" ,
487- text : "Complete final answer" ,
488- payload : { text : "Complete final answer" } ,
489- infoKind : "final" ,
490- } ) ;
495+ const result = await deliverFinalAnswer ( harness , "Complete final answer" ) ;
491496
492497 expect ( harness . editPreview ) . toHaveBeenCalledTimes ( 1 ) ;
493498 expect ( harness . sendPayload ) . not . toHaveBeenCalled ( ) ;
@@ -502,21 +507,11 @@ describe("createLaneTextDeliverer", () => {
502507 const err = Object . assign ( new Error ( "403: Forbidden" ) , { error_code : 403 } ) ;
503508 harness . editPreview . mockRejectedValue ( err ) ;
504509
505- const result = await harness . deliverLaneText ( {
506- laneName : "answer" ,
510+ await expectFinalEditFallbackToSend ( {
511+ harness ,
507512 text : "Hello final" ,
508- payload : { text : "Hello final" } ,
509- infoKind : "final" ,
513+ expectedLogSnippet : "rejected by Telegram (client error); falling back" ,
510514 } ) ;
511-
512- expect ( result ) . toBe ( "sent" ) ;
513- expect ( harness . editPreview ) . toHaveBeenCalledTimes ( 1 ) ;
514- expect ( harness . sendPayload ) . toHaveBeenCalledWith (
515- expect . objectContaining ( { text : "Hello final" } ) ,
516- ) ;
517- expect ( harness . log ) . toHaveBeenCalledWith (
518- expect . stringContaining ( "rejected by Telegram (client error); falling back" ) ,
519- ) ;
520515 } ) ;
521516
522517 it ( "retains preview on 502 with error_code during final (ambiguous server error)" , async ( ) => {
0 commit comments