@@ -1610,8 +1610,62 @@ await CreateDataAsync(d =>
16101610 }
16111611
16121612 [ Fact ]
1613- public async Task CanEventsWithStablePagingAsync ( )
1613+ public async Task GetEvents_WithPartialLastCursorPage_DoesNotReturnNextLinkAsync ( )
16141614 {
1615+ // Arrange
1616+ await CreateDataAsync ( d =>
1617+ {
1618+ d . Event ( ) . TestProject ( ) . Type ( Event . KnownTypes . Log ) ;
1619+ d . Event ( ) . TestProject ( ) . Type ( Event . KnownTypes . Log ) ;
1620+ d . Event ( ) . TestProject ( ) . Type ( Event . KnownTypes . Log ) ;
1621+ } ) ;
1622+
1623+ // Act
1624+ var response = await SendRequestAsync ( r => r
1625+ . AsGlobalAdminUser ( )
1626+ . AppendPath ( "events" )
1627+ . QueryString ( "limit" , "2" )
1628+ . QueryString ( "include" , "total" )
1629+ . StatusCodeShouldBeOk ( )
1630+ ) ;
1631+
1632+ // Assert
1633+ Assert . Equal ( "3" , response . Headers . GetValues ( Headers . ResultCount ) . Single ( ) ) ;
1634+
1635+ var links = ParseLinkHeaderValue ( response . Headers . GetValues ( HeaderNames . Link ) . ToArray ( ) ) ;
1636+ Assert . True ( links . TryGetValue ( "next" , out var nextLink ) ) ;
1637+
1638+ string ? after = GetQueryStringValue ( nextLink , "after" ) ;
1639+ Assert . NotNull ( after ) ;
1640+
1641+ var result = await response . Content . ReadFromJsonAsync < IReadOnlyCollection < PersistentEvent > > ( TestCancellationToken ) ;
1642+ Assert . NotNull ( result ) ;
1643+ Assert . Equal ( 2 , result . Count ) ;
1644+
1645+ // Act
1646+ response = await SendRequestAsync ( r => r
1647+ . AsGlobalAdminUser ( )
1648+ . AppendPath ( "events" )
1649+ . QueryString ( "limit" , "2" )
1650+ . QueryString ( "after" , after )
1651+ . StatusCodeShouldBeOk ( )
1652+ ) ;
1653+
1654+ // Assert
1655+ links = ParseLinkHeaderValue ( response . Headers . GetValues ( HeaderNames . Link ) . ToArray ( ) ) ;
1656+ Assert . Single ( links ) ;
1657+ Assert . True ( links . ContainsKey ( "previous" ) ) ;
1658+ Assert . False ( links . ContainsKey ( "next" ) ) ;
1659+
1660+ result = await response . Content . ReadFromJsonAsync < IReadOnlyCollection < PersistentEvent > > ( TestCancellationToken ) ;
1661+ Assert . NotNull ( result ) ;
1662+ Assert . Single ( result ) ;
1663+ }
1664+
1665+ [ Fact ]
1666+ public async Task GetEvents_WithStableCursorPaging_ReturnsExpectedDirectionalLinksAsync ( )
1667+ {
1668+ // Arrange
16151669 await CreateDataAsync ( d =>
16161670 {
16171671 d . Event ( ) . TestProject ( ) . Type ( Event . KnownTypes . Log ) ;
@@ -1623,6 +1677,7 @@ await CreateDataAsync(d =>
16231677 Log . SetLogLevel < StackRepository > ( LogLevel . Trace ) ;
16241678 Log . SetLogLevel < EventStackFilterQueryBuilder > ( LogLevel . Trace ) ;
16251679
1680+ // Act
16261681 var response = await SendRequestAsync ( r => r
16271682 . AsGlobalAdminUser ( )
16281683 . AppendPath ( "events" )
@@ -1631,6 +1686,7 @@ await CreateDataAsync(d =>
16311686 . StatusCodeShouldBeOk ( )
16321687 ) ;
16331688
1689+ // Assert
16341690 Assert . Equal ( "3" , response . Headers . GetValues ( Headers . ResultCount ) . Single ( ) ) ;
16351691
16361692 var links = ParseLinkHeaderValue ( response . Headers . GetValues ( HeaderNames . Link ) . ToArray ( ) ) ;
@@ -1647,7 +1703,7 @@ await CreateDataAsync(d =>
16471703 Assert . NotNull ( result ) ;
16481704 string firstEventId = result . Single ( ) . Id ;
16491705
1650- // Go to second page
1706+ // Act
16511707 response = await SendRequestAsync ( r => r
16521708 . AsGlobalAdminUser ( )
16531709 . AppendPath ( "events" )
@@ -1657,6 +1713,7 @@ await CreateDataAsync(d =>
16571713 . StatusCodeShouldBeOk ( )
16581714 ) ;
16591715
1716+ // Assert
16601717 Assert . Equal ( "3" , response . Headers . GetValues ( Headers . ResultCount ) . Single ( ) ) ;
16611718 links = ParseLinkHeaderValue ( response . Headers . GetValues ( HeaderNames . Link ) . ToArray ( ) ) ;
16621719 Assert . Equal ( 2 , links . Count ) ;
@@ -1673,7 +1730,7 @@ await CreateDataAsync(d =>
16731730 string secondEventId = result . Single ( ) . Id ;
16741731 Assert . NotEqual ( firstEventId , secondEventId ) ;
16751732
1676- // Go to last page
1733+ // Act
16771734 response = await SendRequestAsync ( r => r
16781735 . AsGlobalAdminUser ( )
16791736 . AppendPath ( "events" )
@@ -1683,23 +1740,21 @@ await CreateDataAsync(d =>
16831740 . StatusCodeShouldBeOk ( )
16841741 ) ;
16851742
1743+ // Assert
16861744 Assert . Equal ( "3" , response . Headers . GetValues ( Headers . ResultCount ) . Single ( ) ) ;
16871745 links = ParseLinkHeaderValue ( response . Headers . GetValues ( HeaderNames . Link ) . ToArray ( ) ) ;
1688- Assert . Equal ( 2 , links . Count ) ;
1746+ Assert . Single ( links ) ;
16891747
16901748 before = GetQueryStringValue ( links [ "previous" ] , "before" ) ;
16911749 Assert . NotNull ( before ) ;
1692-
1693- after = GetQueryStringValue ( links [ "next" ] , "after" ) ;
1694- Assert . NotNull ( after ) ;
1695- Assert . Equal ( before , after ) ;
1750+ Assert . False ( links . ContainsKey ( "next" ) ) ;
16961751
16971752 result = await response . Content . ReadFromJsonAsync < IReadOnlyCollection < PersistentEvent > > ( TestCancellationToken ) ;
16981753 Assert . NotNull ( result ) ;
16991754 string thirdEventId = result . Single ( ) . Id ;
17001755 Assert . NotEqual ( secondEventId , thirdEventId ) ;
17011756
1702- // go to previous page
1757+ // Act
17031758 response = await SendRequestAsync ( r => r
17041759 . AsGlobalAdminUser ( )
17051760 . AppendPath ( "events" )
@@ -1709,6 +1764,7 @@ await CreateDataAsync(d =>
17091764 . StatusCodeShouldBeOk ( )
17101765 ) ;
17111766
1767+ // Assert
17121768 Assert . Equal ( "3" , response . Headers . GetValues ( Headers . ResultCount ) . Single ( ) ) ;
17131769 links = ParseLinkHeaderValue ( response . Headers . GetValues ( HeaderNames . Link ) . ToArray ( ) ) ;
17141770 Assert . Equal ( 2 , links . Count ) ;
0 commit comments