1515 */
1616package org .springframework .data .mongodb .core ;
1717
18+ import static org .assertj .core .api .Assertions .*;
1819import static org .springframework .data .mongodb .core .query .Criteria .*;
19- import static org .springframework .data .mongodb .test .util .Assertions .*;
2020
2121import lombok .Data ;
2222import lombok .NoArgsConstructor ;
3737import org .springframework .data .annotation .PersistenceCreator ;
3838import org .springframework .data .auditing .IsNewAwareAuditingHandler ;
3939import org .springframework .data .domain .KeysetScrollPosition ;
40+ import org .springframework .data .domain .KeysetScrollPosition .Direction ;
4041import org .springframework .data .domain .OffsetScrollPosition ;
4142import org .springframework .data .domain .ScrollPosition ;
4243import org .springframework .data .domain .Sort ;
@@ -118,7 +119,7 @@ void shouldUseKeysetScrollingWithNestedSort() {
118119 assertThat (scroll ).hasSize (2 );
119120 assertThat (scroll ).containsOnly (john20 , john40 );
120121
121- scroll = template .scroll (q .with (scroll .positionAt (scroll .size ()- 1 )), WithNestedDocument .class );
122+ scroll = template .scroll (q .with (scroll .positionAt (scroll .size () - 1 )), WithNestedDocument .class );
122123
123124 assertThat (scroll .hasNext ()).isFalse ();
124125 assertThat (scroll .isLast ()).isTrue ();
@@ -143,6 +144,19 @@ void shouldErrorOnNullValueForQuery() {
143144 new Document ("name" , "foo" ));
144145
145146 template .insertAll (Arrays .asList (john20 , john40 , john41 , john42 , john43 , john44 ));
147+ }
148+
149+ @ Test // GH-4308
150+ void shouldAllowReverseSort () {
151+
152+ WithNestedDocument john20 = new WithNestedDocument (null , "John" , 120 , new WithNestedDocument ("John" , 20 ),
153+ new Document ("name" , "bar" ));
154+ WithNestedDocument john40 = new WithNestedDocument (null , "John" , 140 , new WithNestedDocument ("John" , 40 ),
155+ new Document ("name" , "baz" ));
156+ WithNestedDocument john41 = new WithNestedDocument (null , "John" , 141 , new WithNestedDocument ("John" , 41 ),
157+ new Document ("name" , "foo" ));
158+
159+ template .insertAll (Arrays .asList (john20 , john40 , john41 ));
146160
147161 Query q = new Query (where ("name" ).regex ("J.*" )).with (Sort .by ("nested.name" , "nested.age" , "document.name" ))
148162 .limit (2 );
@@ -155,11 +169,22 @@ void shouldErrorOnNullValueForQuery() {
155169 assertThat (scroll ).hasSize (2 );
156170 assertThat (scroll ).containsOnly (john20 , john40 );
157171
158- ScrollPosition startAfter = scroll . positionAt (scroll .size ()- 1 );
172+ scroll = template . scroll ( q . with ( scroll . positionAt (scroll .size () - 1 )), WithNestedDocument . class );
159173
160- assertThatExceptionOfType (IllegalStateException .class )
161- .isThrownBy (() -> template .scroll (q .with (startAfter ), WithNestedDocument .class ))
162- .withMessageContaining ("document.name" );
174+ assertThat (scroll .hasNext ()).isFalse ();
175+ assertThat (scroll .isLast ()).isTrue ();
176+ assertThat (scroll ).hasSize (1 );
177+ assertThat (scroll ).containsOnly (john41 );
178+
179+ KeysetScrollPosition scrollPosition = (KeysetScrollPosition ) scroll .positionAt (0 );
180+ KeysetScrollPosition reversePosition = KeysetScrollPosition .of (scrollPosition .getKeys (), Direction .Backward );
181+
182+ scroll = template .scroll (q .with (reversePosition ), WithNestedDocument .class );
183+
184+ assertThat (scroll .hasNext ()).isTrue ();
185+ assertThat (scroll .isLast ()).isFalse ();
186+ assertThat (scroll ).hasSize (2 );
187+ assertThat (scroll ).containsOnly (john20 , john40 );
163188 }
164189
165190 @ ParameterizedTest // GH-4308
@@ -185,15 +210,15 @@ public <T> void shouldApplyCursoringCorrectly(ScrollPosition scrollPosition, Cla
185210 assertThat (scroll ).hasSize (2 );
186211 assertThat (scroll ).containsOnly (assertionConverter .apply (jane_20 ), assertionConverter .apply (jane_40 ));
187212
188- scroll = template .scroll (q .with (scroll .positionAt (scroll .size ()- 1 )).limit (3 ), resultType , "person" );
213+ scroll = template .scroll (q .with (scroll .positionAt (scroll .size () - 1 )).limit (3 ), resultType , "person" );
189214
190215 assertThat (scroll .hasNext ()).isTrue ();
191216 assertThat (scroll .isLast ()).isFalse ();
192217 assertThat (scroll ).hasSize (3 );
193218 assertThat (scroll ).contains (assertionConverter .apply (jane_42 ), assertionConverter .apply (john20 ));
194219 assertThat (scroll ).containsAnyOf (assertionConverter .apply (john40_1 ), assertionConverter .apply (john40_2 ));
195220
196- scroll = template .scroll (q .with (scroll .positionAt (scroll .size ()- 1 )).limit (1 ), resultType , "person" );
221+ scroll = template .scroll (q .with (scroll .positionAt (scroll .size () - 1 )).limit (1 ), resultType , "person" );
197222
198223 assertThat (scroll .hasNext ()).isFalse ();
199224 assertThat (scroll .isLast ()).isTrue ();
0 commit comments