11using System ;
22using System . Collections . Generic ;
33using System . Linq ;
4+ using System . Reactive ;
5+ using System . Reactive . Linq ;
6+ using System . Reactive . Subjects ;
7+ using System . Reactive . Threading . Tasks ;
48using System . Threading . Tasks ;
59using GitHub . Collections ;
610using GitHub . Models ;
@@ -57,14 +61,38 @@ public void IsLoading_Should_Be_Set_To_False_When_LoadPage_Throws()
5761 Assert . That ( target . IsLoading , Is . False ) ;
5862 }
5963
64+ [ Test ]
65+ public async Task Should_Not_Load_Duplicate_Pages ( )
66+ {
67+ var trigger = new Subject < Unit > ( ) ;
68+ var target = new TestSource ( loadTrigger : trigger ) ;
69+
70+ var task1 = target . GetPage ( 1 ) ;
71+ var task2 = target . GetPage ( 1 ) ;
72+
73+ Assert . That ( target . PagesLoaded , Is . Empty ) ;
74+
75+ trigger . OnNext ( Unit . Default ) ;
76+ trigger . OnNext ( Unit . Default ) ;
77+
78+ await task1 ;
79+ await task2 ;
80+
81+ Assert . That ( target . PagesLoaded , Is . EqualTo ( new [ ] { 0 , 1 } ) ) ;
82+ }
83+
6084 class TestSource : SequentialListSource < string , string >
6185 {
6286 const int PageCount = 10 ;
6387 readonly int ? throwAtPage ;
88+ readonly ISubject < Unit > loadTrigger ;
6489
65- public TestSource ( int ? throwAtPage = null )
90+ public TestSource (
91+ int ? throwAtPage = null ,
92+ ISubject < Unit > loadTrigger = null )
6693 {
6794 this . throwAtPage = throwAtPage ;
95+ this . loadTrigger = loadTrigger ;
6896 }
6997
7098 public override int PageSize => 10 ;
@@ -75,24 +103,29 @@ protected override string CreateViewModel(string model)
75103 return model + " loaded" ;
76104 }
77105
78- protected override Task < Page < string > > LoadPage ( string after )
106+ protected override async Task < Page < string > > LoadPage ( string after )
79107 {
80108 var page = after != null ? int . Parse ( after ) : 0 ;
81109
110+ if ( loadTrigger != null )
111+ {
112+ await loadTrigger . Take ( 1 ) . ToTask ( ) . ConfigureAwait ( false ) ;
113+ }
114+
82115 if ( page == throwAtPage )
83116 {
84117 throw new GitHubLogicException ( "Thrown." ) ;
85118 }
86119
87120 PagesLoaded . Add ( page ) ;
88121
89- return Task . FromResult ( new Page < string >
122+ return new Page < string >
90123 {
91124 EndCursor = ( page + 1 ) . ToString ( ) ,
92125 HasNextPage = page < PageCount ,
93126 Items = Enumerable . Range ( page * PageSize , PageSize ) . Select ( x => "Item " + x ) . ToList ( ) ,
94127 TotalCount = PageSize * PageCount ,
95- } ) ;
128+ } ;
96129 }
97130 }
98131 }
0 commit comments