2020import java .util .ArrayList ;
2121import java .util .Arrays ;
2222import java .util .HashMap ;
23+ import java .util .Iterator ;
2324import java .util .LinkedHashMap ;
2425import java .util .List ;
2526import java .util .Map ;
27+ import java .util .NoSuchElementException ;
2628
2729import static org .junit .Assert .*;
2830
@@ -47,6 +49,8 @@ public class TestingbotRestMockTest {
4749 // configurable response
4850 private volatile int responseStatus = 200 ;
4951 private volatile String responseBody = "{\" success\" :true}" ;
52+ private final java .util .concurrent .ConcurrentLinkedDeque <String > responseBodies = new java .util .concurrent .ConcurrentLinkedDeque <>();
53+ private final java .util .List <String > requestUrls = java .util .Collections .synchronizedList (new ArrayList <String >());
5054
5155 @ Before
5256 public void setUp () throws IOException {
@@ -60,8 +64,13 @@ public void handle(HttpExchange ex) throws IOException {
6064 lastAuth = ex .getRequestHeaders ().getFirst ("Authorization" );
6165 lastUserAgent = ex .getRequestHeaders ().getFirst ("User-Agent" );
6266 lastBody = read (ex .getRequestBody ());
67+ requestUrls .add (lastPath + (lastQuery != null ? "?" + lastQuery : "" ));
6368
64- byte [] out = responseBody == null ? new byte [0 ] : responseBody .getBytes (StandardCharsets .UTF_8 );
69+ String body = responseBodies .pollFirst ();
70+ if (body == null ) {
71+ body = responseBody ;
72+ }
73+ byte [] out = body == null ? new byte [0 ] : body .getBytes (StandardCharsets .UTF_8 );
6574 ex .sendResponseHeaders (responseStatus , out .length == 0 ? -1 : out .length );
6675 if (out .length > 0 ) {
6776 OutputStream os = ex .getResponseBody ();
@@ -716,4 +725,70 @@ public void triggerLabSuite() {
716725 api .triggerLabSuite (4 );
717726 assertRequest ("POST" , "/v1/labsuites/4/trigger" );
718727 }
728+
729+ // ------------------------------------------------------------------ pagination iterator
730+
731+ private static String pageJson (int from , int count ) {
732+ StringBuilder sb = new StringBuilder ("{\" data\" :[" );
733+ for (int i = 0 ; i < count ; i ++) {
734+ if (i > 0 ) {
735+ sb .append (',' );
736+ }
737+ sb .append ("{\" session_id\" :\" s" ).append (from + i ).append ("\" }" );
738+ }
739+ sb .append ("],\" meta\" :{}}" );
740+ return sb .toString ();
741+ }
742+
743+ @ Test
744+ public void iterateTestsWalksAllPages () {
745+ // 3 pages of 10, 10, 5 (last short page signals end-of-stream)
746+ responseBodies .add (pageJson (0 , 10 ));
747+ responseBodies .add (pageJson (10 , 10 ));
748+ responseBodies .add (pageJson (20 , 5 ));
749+
750+ int seen = 0 ;
751+ for (TestingbotTest t : api .iterateTests (10 )) {
752+ Assert .assertEquals ("s" + seen , t .getSessionId ());
753+ seen ++;
754+ }
755+ Assert .assertEquals (25 , seen );
756+ Assert .assertEquals (3 , requestUrls .size ());
757+ assertTrue (requestUrls .get (0 ).contains ("offset=0" ));
758+ assertTrue (requestUrls .get (1 ).contains ("offset=10" ));
759+ assertTrue (requestUrls .get (2 ).contains ("offset=20" ));
760+ }
761+
762+ @ Test
763+ public void iterateTestsStopsImmediatelyOnEmptyPage () {
764+ responseBodies .add ("{\" data\" :[],\" meta\" :{}}" );
765+ Iterator <TestingbotTest > it = api .iterateTests (10 ).iterator ();
766+ assertFalse (it .hasNext ());
767+ Assert .assertEquals (1 , requestUrls .size ());
768+ try {
769+ it .next ();
770+ Assert .fail ("expected NoSuchElementException" );
771+ } catch (NoSuchElementException expected ) {
772+ }
773+ }
774+
775+ @ Test
776+ public void iterateTestsForwardsFilters () {
777+ responseBodies .add (pageJson (0 , 1 )); // short page → stops after one request
778+ Map <String , String > filters = new HashMap <>();
779+ filters .put ("group" , "smoke" );
780+ int seen = 0 ;
781+ for (TestingbotTest ignored : api .iterateTests (10 , filters )) {
782+ seen ++;
783+ }
784+ Assert .assertEquals (1 , seen );
785+ Assert .assertEquals (1 , requestUrls .size ());
786+ assertTrue (requestUrls .get (0 ).contains ("group=smoke" ));
787+ assertTrue (requestUrls .get (0 ).contains ("offset=0" ));
788+ }
789+
790+ @ Test (expected = IllegalArgumentException .class )
791+ public void iterateTestsRejectsNonPositivePageSize () {
792+ api .iterateTests (0 );
793+ }
719794}
0 commit comments