11package com .openelements .hiero .base .test ;
22
33import com .hedera .hashgraph .sdk .PrivateKey ;
4+ import com .hedera .hashgraph .sdk .SubscriptionHandle ;
45import com .hedera .hashgraph .sdk .TopicId ;
6+ import com .hedera .hashgraph .sdk .TopicMessage ;
57import com .openelements .hiero .base .HieroException ;
68import com .openelements .hiero .base .data .Account ;
79import com .openelements .hiero .base .implementation .TopicClientImpl ;
1416import com .openelements .hiero .base .protocol .data .TopicDeleteResult ;
1517import com .openelements .hiero .base .protocol .data .TopicSubmitMessageRequest ;
1618import com .openelements .hiero .base .protocol .data .TopicSubmitMessageResult ;
19+ import com .openelements .hiero .base .protocol .data .TopicMessageRequest ;
20+ import com .openelements .hiero .base .protocol .data .TopicMessageResult ;
1721import org .junit .jupiter .api .Assertions ;
1822import org .junit .jupiter .api .BeforeEach ;
1923import org .junit .jupiter .api .Test ;
2024import org .mockito .ArgumentCaptor ;
2125import org .mockito .Mockito ;
2226
27+ import java .time .Instant ;
28+ import java .util .function .Consumer ;
29+
2330import static org .mockito .ArgumentMatchers .any ;
2431import static org .mockito .Mockito .*;
2532
@@ -33,6 +40,7 @@ public class TopicClientImplTest {
3340 ArgumentCaptor <TopicUpdateRequest > topicUpdateCaptor = ArgumentCaptor .forClass (TopicUpdateRequest .class );
3441 ArgumentCaptor <TopicDeleteRequest > topicDeleteCaptor = ArgumentCaptor .forClass (TopicDeleteRequest .class );
3542 ArgumentCaptor <TopicSubmitMessageRequest > topicSubmitCaptor = ArgumentCaptor .forClass (TopicSubmitMessageRequest .class );
43+ ArgumentCaptor <TopicMessageRequest > topicSubscribeCaptor = ArgumentCaptor .forClass (TopicMessageRequest .class );
3644
3745 @ BeforeEach
3846 void setup () {
@@ -587,4 +595,180 @@ void shouldThrowExceptionForNullParamOnSubmitMessage() {
587595 Assertions .assertThrows (NullPointerException .class , () -> topicClient .submitMessage ((TopicId ) null , (String )null ));
588596 Assertions .assertThrows (NullPointerException .class , () -> topicClient .submitMessage ((TopicId ) null , null , (String )null ));
589597 }
598+
599+ @ Test
600+ void shouldSubscribeTopic () throws HieroException {
601+ final TopicMessageResult topicMessageResult = Mockito .mock (TopicMessageResult .class );
602+ final SubscriptionHandle subscriptionHandle = Mockito .mock (SubscriptionHandle .class );
603+
604+ // given
605+ final TopicId topicId = TopicId .fromString ("1.2.3" );
606+ final Consumer <TopicMessage > subscription = (message ) -> {};
607+
608+ when (protocolLayerClient .executeTopicMessageQuery (any (TopicMessageRequest .class )))
609+ .thenReturn (topicMessageResult );
610+ when (topicMessageResult .subscriptionHandle ()).thenReturn (subscriptionHandle );
611+
612+ final SubscriptionHandle handler = topicClient .subscribeTopic (topicId , subscription );
613+
614+ verify (protocolLayerClient , times (1 ))
615+ .executeTopicMessageQuery (topicSubscribeCaptor .capture ());
616+ final TopicMessageRequest capture = topicSubscribeCaptor .getValue ();
617+ Assertions .assertEquals (topicId , capture .topicId ());
618+ Assertions .assertEquals (subscription , capture .subscription ());
619+ Assertions .assertEquals (-1 , capture .limit ()); // default limit infinite(-1)
620+ Assertions .assertNull (capture .startTime ());
621+ Assertions .assertNull (capture .endTime ());
622+
623+ verify (topicMessageResult , times (1 )).subscriptionHandle ();
624+
625+ Assertions .assertNotNull (handler );
626+ Assertions .assertEquals (subscriptionHandle , handler );
627+ }
628+
629+ @ Test
630+ void shouldSubscribeTopicWithLimit () throws HieroException {
631+ final TopicMessageResult topicMessageResult = Mockito .mock (TopicMessageResult .class );
632+ final SubscriptionHandle subscriptionHandle = Mockito .mock (SubscriptionHandle .class );
633+
634+ // given
635+ final TopicId topicId = TopicId .fromString ("1.2.3" );
636+ final int limit = 2 ;
637+ final Consumer <TopicMessage > subscription = (message ) -> {};
638+
639+ when (protocolLayerClient .executeTopicMessageQuery (any (TopicMessageRequest .class )))
640+ .thenReturn (topicMessageResult );
641+ when (topicMessageResult .subscriptionHandle ()).thenReturn (subscriptionHandle );
642+
643+ final SubscriptionHandle handler = topicClient .subscribeTopic (topicId , subscription , limit );
644+
645+ verify (protocolLayerClient , times (1 ))
646+ .executeTopicMessageQuery (topicSubscribeCaptor .capture ());
647+ final TopicMessageRequest capture = topicSubscribeCaptor .getValue ();
648+ Assertions .assertEquals (topicId , capture .topicId ());
649+ Assertions .assertEquals (subscription , capture .subscription ());
650+ Assertions .assertEquals (limit , capture .limit ());
651+ Assertions .assertNull (capture .startTime ());
652+ Assertions .assertNull (capture .endTime ());
653+
654+ verify (topicMessageResult , times (1 )).subscriptionHandle ();
655+
656+ Assertions .assertNotNull (handler );
657+ Assertions .assertEquals (subscriptionHandle , handler );
658+ }
659+
660+ @ Test
661+ void shouldSubscribeTopicWithStartAndEndTime () throws HieroException {
662+ final TopicMessageResult topicMessageResult = Mockito .mock (TopicMessageResult .class );
663+ final SubscriptionHandle subscriptionHandle = Mockito .mock (SubscriptionHandle .class );
664+
665+ // given
666+ final TopicId topicId = TopicId .fromString ("1.2.3" );
667+ final Consumer <TopicMessage > subscription = (message ) -> {};
668+ final Instant startTime = Instant .now ().plusSeconds (120 );
669+ final Instant endTime = Instant .now ().plusSeconds (1800 );
670+
671+ when (protocolLayerClient .executeTopicMessageQuery (any (TopicMessageRequest .class )))
672+ .thenReturn (topicMessageResult );
673+ when (topicMessageResult .subscriptionHandle ()).thenReturn (subscriptionHandle );
674+
675+ final SubscriptionHandle handler = topicClient .subscribeTopic (topicId , subscription , startTime , endTime );
676+
677+ verify (protocolLayerClient , times (1 ))
678+ .executeTopicMessageQuery (topicSubscribeCaptor .capture ());
679+ final TopicMessageRequest capture = topicSubscribeCaptor .getValue ();
680+ Assertions .assertEquals (topicId , capture .topicId ());
681+ Assertions .assertEquals (subscription , capture .subscription ());
682+ Assertions .assertEquals (-1 , capture .limit ()); // default limit
683+ Assertions .assertEquals (startTime , capture .startTime ());
684+ Assertions .assertEquals (endTime , capture .endTime ());
685+
686+ verify (topicMessageResult , times (1 )).subscriptionHandle ();
687+
688+ Assertions .assertNotNull (handler );
689+ Assertions .assertEquals (subscriptionHandle , handler );
690+ }
691+
692+ @ Test
693+ void shouldSubscribeTopicWithAllParams () throws HieroException {
694+ final TopicMessageResult topicMessageResult = Mockito .mock (TopicMessageResult .class );
695+ final SubscriptionHandle subscriptionHandle = Mockito .mock (SubscriptionHandle .class );
696+
697+ // given
698+ final TopicId topicId = TopicId .fromString ("1.2.3" );
699+ final Consumer <TopicMessage > subscription = (message ) -> {};
700+ final Instant startTime = Instant .now ().plusSeconds (120 );
701+ final Instant endTime = Instant .now ().plusSeconds (1800 );
702+ final int limit = 1 ;
703+
704+ when (protocolLayerClient .executeTopicMessageQuery (any (TopicMessageRequest .class )))
705+ .thenReturn (topicMessageResult );
706+ when (topicMessageResult .subscriptionHandle ()).thenReturn (subscriptionHandle );
707+
708+ final SubscriptionHandle handler = topicClient .subscribeTopic (topicId , subscription , startTime , endTime , limit );
709+
710+ verify (protocolLayerClient , times (1 ))
711+ .executeTopicMessageQuery (topicSubscribeCaptor .capture ());
712+ final TopicMessageRequest capture = topicSubscribeCaptor .getValue ();
713+ Assertions .assertEquals (topicId , capture .topicId ());
714+ Assertions .assertEquals (subscription , capture .subscription ());
715+ Assertions .assertEquals (limit , capture .limit ());
716+ Assertions .assertEquals (startTime , capture .startTime ());
717+ Assertions .assertEquals (endTime , capture .endTime ());
718+
719+ verify (topicMessageResult , times (1 )).subscriptionHandle ();
720+
721+ Assertions .assertNotNull (handler );
722+ Assertions .assertEquals (subscriptionHandle , handler );
723+ }
724+
725+ @ Test
726+ void shouldThrowExceptionOnSubscribeTopicWithInvalidStartAndEndTime () {
727+ // given
728+ final TopicId topicId = TopicId .fromString ("1.2.3" );
729+ final Consumer <TopicMessage > subscription = (message ) -> {};
730+
731+ final Instant startTime1 = Instant .now ().plusSeconds (120 );
732+ final Instant endTime1 = startTime1 .minusSeconds (60 );
733+ final Instant startTime2 = Instant .now ().minusSeconds (60 );
734+ final Instant endTime2 = Instant .now ().plusSeconds (120 );
735+ final int limit = 1 ;
736+
737+ //End time before start time
738+ final IllegalArgumentException e1 = Assertions .assertThrows (IllegalArgumentException .class ,
739+ () -> topicClient .subscribeTopic (topicId , subscription , startTime1 , endTime1 ));
740+ final IllegalArgumentException e2 = Assertions .assertThrows (IllegalArgumentException .class ,
741+ () -> topicClient .subscribeTopic (topicId , subscription , startTime1 , endTime1 , limit ));
742+
743+ Assertions .assertEquals ("endTime must be greater than starTime" , e1 .getMessage ());
744+ Assertions .assertEquals ("endTime must be greater than starTime" , e2 .getMessage ());
745+
746+ //Start time before current time
747+ final IllegalArgumentException e3 = Assertions .assertThrows (IllegalArgumentException .class ,
748+ () -> topicClient .subscribeTopic (topicId , subscription , startTime2 , endTime2 ));
749+ final IllegalArgumentException e4 = Assertions .assertThrows (IllegalArgumentException .class ,
750+ () -> topicClient .subscribeTopic (topicId , subscription , startTime2 , endTime2 , limit ));
751+
752+ Assertions .assertEquals ("startTime must be greater than currentTime" , e3 .getMessage ());
753+ Assertions .assertEquals ("startTime must be greater than currentTime" , e4 .getMessage ());
754+ }
755+
756+ @ Test
757+ void shouldThrowExceptionOnSubscribeTopicWithLimitEqualsZero () {
758+ final String msg = "limit must be greater than 0" ;
759+ // given
760+ final TopicId topicId = TopicId .fromString ("1.2.3" );
761+ final Consumer <TopicMessage > subscription = (message ) -> {};
762+ final Instant startTime = Instant .now ().plusSeconds (120 );
763+ final Instant endTime = startTime .plusSeconds (120 );
764+ final int limit = 0 ;
765+
766+ final IllegalArgumentException e1 = Assertions .assertThrows (IllegalArgumentException .class ,
767+ () -> topicClient .subscribeTopic (topicId , subscription , limit ));
768+ final IllegalArgumentException e2 = Assertions .assertThrows (IllegalArgumentException .class ,
769+ () -> topicClient .subscribeTopic (topicId , subscription , startTime , endTime , limit ));
770+
771+ Assertions .assertEquals (msg , e1 .getMessage ());
772+ Assertions .assertEquals (msg , e2 .getMessage ());
773+ }
590774}
0 commit comments