@@ -220,6 +220,83 @@ describe('SnsSqsPermissionConsumer - startupResourcePollingConfig', () => {
220220 expect ( consumer . subscriptionProps . topicArn ) . toBe ( topicArn )
221221 expect ( consumer . subscriptionProps . queueName ) . toBe ( queueName )
222222 } )
223+
224+ it ( 'start() waits for resources and starts consumers (blocking mode)' , async ( ) => {
225+ // Create queue first, but not the topic
226+ await assertQueue ( sqsClient , { QueueName : queueName } )
227+
228+ const consumer = new TestStartupResourcePollingConsumer ( diContainer . cradle , {
229+ locatorConfig : {
230+ topicName,
231+ queueUrl,
232+ subscriptionArn :
233+ 'arn:aws:sns:eu-west-1:000000000000:dummy:bdf640a2-bedf-475a-98b8-758b88c87395' ,
234+ startupResourcePolling : {
235+ enabled : true ,
236+ pollingIntervalMs : 50 ,
237+ timeoutMs : 5000 ,
238+ } ,
239+ } ,
240+ creationConfig : {
241+ queue : { QueueName : queueName } ,
242+ } ,
243+ } )
244+
245+ // Consumer should not be running before start
246+ expect ( consumer . isRunning ) . toBe ( false )
247+
248+ // Start in background (blocking mode waits for resources)
249+ const startPromise = consumer . start ( )
250+
251+ // Wait a bit then create the topic
252+ await setTimeout ( 200 )
253+ const topicArn = await assertTopic ( snsClient , stsClient , { Name : topicName } )
254+
255+ // start() should complete successfully after topic appears
256+ await startPromise
257+
258+ expect ( consumer . subscriptionProps . topicArn ) . toBe ( topicArn )
259+ expect ( consumer . subscriptionProps . queueUrl ) . toBe ( queueUrl )
260+ // Consumer should be running after start completes
261+ expect ( consumer . isRunning ) . toBe ( true )
262+
263+ // Clean up
264+ await consumer . close ( )
265+ } )
266+
267+ it ( 'start() works immediately when resources already exist (blocking mode)' , async ( ) => {
268+ // Create both resources before starting
269+ await assertQueue ( sqsClient , { QueueName : queueName } )
270+ const topicArn = await assertTopic ( snsClient , stsClient , { Name : topicName } )
271+
272+ const consumer = new TestStartupResourcePollingConsumer ( diContainer . cradle , {
273+ locatorConfig : {
274+ topicArn,
275+ queueUrl,
276+ subscriptionArn :
277+ 'arn:aws:sns:eu-west-1:000000000000:dummy:bdf640a2-bedf-475a-98b8-758b88c87395' ,
278+ startupResourcePolling : {
279+ enabled : true ,
280+ pollingIntervalMs : 100 ,
281+ timeoutMs : 5000 ,
282+ } ,
283+ } ,
284+ } )
285+
286+ // Consumer should not be running before start
287+ expect ( consumer . isRunning ) . toBe ( false )
288+
289+ // start() should complete immediately since resources exist
290+ await consumer . start ( )
291+
292+ expect ( consumer . subscriptionProps . topicArn ) . toBe ( topicArn )
293+ expect ( consumer . subscriptionProps . queueUrl ) . toBe ( queueUrl )
294+ // Consumer should be running after start completes
295+ expect ( consumer . isRunning ) . toBe ( true )
296+
297+ // Clean up
298+ await consumer . close ( )
299+ } )
223300 } )
224301
225302 describe ( 'when nonBlocking mode is enabled' , ( ) => {
@@ -465,6 +542,91 @@ describe('SnsSqsPermissionConsumer - startupResourcePollingConfig', () => {
465542 expect ( callbackError ?. message ) . toContain ( 'Timeout' )
466543 expect ( callbackContext ) . toEqual ( { isFinal : true } )
467544 } )
545+
546+ it ( 'start() returns immediately when topic is not available and starts consumers when resources become ready' , async ( ) => {
547+ // Create queue but not topic
548+ await assertQueue ( sqsClient , { QueueName : queueName } )
549+
550+ const consumer = new TestStartupResourcePollingConsumer ( diContainer . cradle , {
551+ locatorConfig : {
552+ topicName,
553+ queueUrl,
554+ subscriptionArn :
555+ 'arn:aws:sns:eu-west-1:000000000000:dummy:bdf640a2-bedf-475a-98b8-758b88c87395' ,
556+ startupResourcePolling : {
557+ enabled : true ,
558+ pollingIntervalMs : 50 ,
559+ timeoutMs : 5000 ,
560+ nonBlocking : true ,
561+ } ,
562+ } ,
563+ creationConfig : {
564+ queue : { QueueName : queueName } ,
565+ } ,
566+ } )
567+
568+ // Consumer should not be running before start
569+ expect ( consumer . isRunning ) . toBe ( false )
570+
571+ // start() should return immediately even though topic doesn't exist
572+ await consumer . start ( )
573+
574+ // queueName should be set but consumer should NOT be running yet (resources not ready)
575+ expect ( consumer . subscriptionProps . queueName ) . toBe ( queueName )
576+ expect ( consumer . isRunning ) . toBe ( false )
577+
578+ // Create topic after start returns
579+ const topicArn = await assertTopic ( snsClient , stsClient , { Name : topicName } )
580+
581+ // Wait for consumer to start running (happens when resources become ready)
582+ await vi . waitFor (
583+ ( ) => {
584+ expect ( consumer . isRunning ) . toBe ( true )
585+ } ,
586+ { timeout : 3000 , interval : 50 } ,
587+ )
588+
589+ // Verify topicArn was updated
590+ expect ( consumer . subscriptionProps . topicArn ) . toBe ( topicArn )
591+
592+ // Clean up
593+ await consumer . close ( )
594+ } )
595+
596+ it ( 'start() works immediately when resources are already available' , async ( ) => {
597+ // Create both queue and topic before starting
598+ await assertQueue ( sqsClient , { QueueName : queueName } )
599+ const topicArn = await assertTopic ( snsClient , stsClient , { Name : topicName } )
600+
601+ const consumer = new TestStartupResourcePollingConsumer ( diContainer . cradle , {
602+ locatorConfig : {
603+ topicArn,
604+ queueUrl,
605+ subscriptionArn :
606+ 'arn:aws:sns:eu-west-1:000000000000:dummy:bdf640a2-bedf-475a-98b8-758b88c87395' ,
607+ startupResourcePolling : {
608+ enabled : true ,
609+ pollingIntervalMs : 100 ,
610+ timeoutMs : 5000 ,
611+ nonBlocking : true ,
612+ } ,
613+ } ,
614+ } )
615+
616+ // Consumer should not be running before start
617+ expect ( consumer . isRunning ) . toBe ( false )
618+
619+ // start() should work immediately since resources exist
620+ await consumer . start ( )
621+
622+ expect ( consumer . subscriptionProps . topicArn ) . toBe ( topicArn )
623+ expect ( consumer . subscriptionProps . queueUrl ) . toBe ( queueUrl )
624+ // Consumer should be running after start completes (resources were available)
625+ expect ( consumer . isRunning ) . toBe ( true )
626+
627+ // Clean up
628+ await consumer . close ( )
629+ } )
468630 } )
469631
470632 describe ( 'when subscriptionArn is not provided (subscription creation mode)' , ( ) => {
0 commit comments