@@ -67,15 +67,18 @@ void main() {
67
67
void checkNotifiedOnce () => checkNotified (count: 1 );
68
68
69
69
/// Initialize [model] and the rest of the test state.
70
- Future <void > prepare ({Narrow narrow = const CombinedFeedNarrow ()}) async {
70
+ Future <void > prepare ({
71
+ Narrow narrow = const CombinedFeedNarrow (),
72
+ Anchor anchor = AnchorCode .newest,
73
+ }) async {
71
74
final stream = eg.stream (streamId: eg.defaultStreamMessageStreamId);
72
75
subscription = eg.subscription (stream);
73
76
store = eg.store ();
74
77
await store.addStream (stream);
75
78
await store.addSubscription (subscription);
76
79
connection = store.connection as FakeApiConnection ;
77
80
notifiedCount = 0 ;
78
- model = MessageListView .init (store: store, narrow: narrow)
81
+ model = MessageListView .init (store: store, narrow: narrow, anchor : anchor )
79
82
..addListener (() {
80
83
checkInvariants (model);
81
84
notifiedCount++ ;
@@ -88,11 +91,18 @@ void main() {
88
91
///
89
92
/// The test case must have already called [prepare] to initialize the state.
90
93
Future <void > prepareMessages ({
91
- required bool foundOldest,
94
+ bool ? foundOldest,
95
+ bool ? foundNewest,
96
+ int ? anchorMessageId,
92
97
required List <Message > messages,
93
98
}) async {
94
- connection.prepare (json:
95
- newestResult (foundOldest: foundOldest, messages: messages).toJson ());
99
+ final result = eg.getMessagesResult (
100
+ anchor: model.anchor == AnchorCode .firstUnread
101
+ ? NumericAnchor (anchorMessageId! ) : model.anchor,
102
+ foundOldest: foundOldest,
103
+ foundNewest: foundNewest,
104
+ messages: messages);
105
+ connection.prepare (json: result.toJson ());
96
106
await model.fetchInitial ();
97
107
checkNotifiedOnce ();
98
108
}
@@ -187,11 +197,7 @@ void main() {
187
197
});
188
198
189
199
test ('early in history' , () async {
190
- // For now, this gets a response that isn't realistic for the
191
- // request it sends, to simulate when we start sending requests
192
- // that would make this response realistic.
193
- // TODO(#82): send appropriate fetch request
194
- await prepare ();
200
+ await prepare (anchor: NumericAnchor (1000 ));
195
201
connection.prepare (json: nearResult (
196
202
anchor: 1000 , foundOldest: true , foundNewest: false ,
197
203
messages: List .generate (111 , (i) => eg.streamMessage (id: 990 + i)),
@@ -219,6 +225,26 @@ void main() {
219
225
..haveNewest.isTrue ();
220
226
});
221
227
228
+ group ('sends proper anchor' , () {
229
+ Future <void > checkFetchWithAnchor (Anchor anchor) async {
230
+ await prepare (anchor: anchor);
231
+ // This prepared response isn't entirely realistic, depending on the anchor.
232
+ // That's OK; these particular tests don't use the details of the response.
233
+ connection.prepare (json:
234
+ newestResult (foundOldest: true , messages: []).toJson ());
235
+ await model.fetchInitial ();
236
+ checkNotifiedOnce ();
237
+ check (connection.lastRequest).isA< http.Request > ()
238
+ .url.queryParameters['anchor' ]
239
+ .equals (anchor.toJson ());
240
+ }
241
+
242
+ test ('oldest' , () => checkFetchWithAnchor (AnchorCode .oldest));
243
+ test ('firstUnread' , () => checkFetchWithAnchor (AnchorCode .firstUnread));
244
+ test ('newest' , () => checkFetchWithAnchor (AnchorCode .newest));
245
+ test ('numeric' , () => checkFetchWithAnchor (NumericAnchor (12345 )));
246
+ });
247
+
222
248
// TODO(#824): move this test
223
249
test ('recent senders track all the messages' , () async {
224
250
const narrow = CombinedFeedNarrow ();
@@ -441,13 +467,10 @@ void main() {
441
467
442
468
test ('while in mid-history' , () async {
443
469
final stream = eg.stream ();
444
- await prepare (narrow: ChannelNarrow (stream.streamId));
445
- connection.prepare (json: nearResult (
446
- anchor: 1000 , foundOldest: true , foundNewest: false ,
447
- messages: List .generate (30 ,
448
- (i) => eg.streamMessage (id: 1000 + i, stream: stream))).toJson ());
449
- await model.fetchInitial ();
450
- checkNotifiedOnce ();
470
+ await prepare (narrow: ChannelNarrow (stream.streamId),
471
+ anchor: NumericAnchor (1000 ));
472
+ await prepareMessages (foundOldest: true , foundNewest: false , messages:
473
+ List .generate (30 , (i) => eg.streamMessage (id: 1000 + i, stream: stream)));
451
474
452
475
check (model).messages.length.equals (30 );
453
476
await store.addMessage (eg.streamMessage (stream: stream));
@@ -1711,8 +1734,9 @@ void main() {
1711
1734
..middleMessage.equals (0 );
1712
1735
});
1713
1736
1714
- test ('on fetchInitial not empty' , () async {
1715
- await prepare (narrow: const CombinedFeedNarrow ());
1737
+ test ('on fetchInitial, anchor past end' , () async {
1738
+ await prepare (narrow: const CombinedFeedNarrow (),
1739
+ anchor: AnchorCode .newest);
1716
1740
final stream1 = eg.stream ();
1717
1741
final stream2 = eg.stream ();
1718
1742
await store.addStreams ([stream1, stream2]);
@@ -1735,6 +1759,34 @@ void main() {
1735
1759
.equals (messages[messages.length - 2 ].id);
1736
1760
});
1737
1761
1762
+ test ('on fetchInitial, anchor in middle' , () async {
1763
+ final s1 = eg.stream ();
1764
+ final s2 = eg.stream ();
1765
+ final messages = [
1766
+ eg.streamMessage (id: 1 , stream: s1), eg.streamMessage (id: 2 , stream: s2),
1767
+ eg.streamMessage (id: 3 , stream: s1), eg.streamMessage (id: 4 , stream: s2),
1768
+ eg.streamMessage (id: 5 , stream: s1), eg.streamMessage (id: 6 , stream: s2),
1769
+ eg.streamMessage (id: 7 , stream: s1), eg.streamMessage (id: 8 , stream: s2),
1770
+ ];
1771
+ final anchorId = 4 ;
1772
+
1773
+ await prepare (narrow: const CombinedFeedNarrow (),
1774
+ anchor: NumericAnchor (anchorId));
1775
+ await store.addStreams ([s1, s2]);
1776
+ await store.addSubscription (eg.subscription (s1));
1777
+ await store.addSubscription (eg.subscription (s2, isMuted: true ));
1778
+ await prepareMessages (foundOldest: true , foundNewest: true ,
1779
+ messages: messages);
1780
+ // The anchor message is the first visible message with ID at least anchorId…
1781
+ check (model)
1782
+ ..messages[model.middleMessage - 1 ].id.isLessThan (anchorId)
1783
+ ..messages[model.middleMessage].id.isGreaterOrEqual (anchorId);
1784
+ // … even though a non-visible message actually had anchorId itself.
1785
+ check (messages[3 ].id)
1786
+ ..equals (anchorId)
1787
+ ..isLessThan (model.messages[model.middleMessage].id);
1788
+ });
1789
+
1738
1790
/// Like [prepareMessages] , but arrange for the given top and bottom slices.
1739
1791
Future <void > prepareMessageSplit (List <Message > top, List <Message > bottom, {
1740
1792
bool foundOldest = true ,
0 commit comments