@@ -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 ();
@@ -1695,8 +1721,9 @@ void main() {
1695
1721
..middleMessage.equals (0 );
1696
1722
});
1697
1723
1698
- test ('on fetchInitial not empty' , () async {
1699
- await prepare (narrow: const CombinedFeedNarrow ());
1724
+ test ('on fetchInitial, anchor past end' , () async {
1725
+ await prepare (narrow: const CombinedFeedNarrow (),
1726
+ anchor: AnchorCode .newest);
1700
1727
final stream1 = eg.stream ();
1701
1728
final stream2 = eg.stream ();
1702
1729
await store.addStreams ([stream1, stream2]);
@@ -1719,6 +1746,34 @@ void main() {
1719
1746
.equals (messages[messages.length - 2 ].id);
1720
1747
});
1721
1748
1749
+ test ('on fetchInitial, anchor in middle' , () async {
1750
+ final s1 = eg.stream ();
1751
+ final s2 = eg.stream ();
1752
+ final messages = [
1753
+ eg.streamMessage (id: 1 , stream: s1), eg.streamMessage (id: 2 , stream: s2),
1754
+ eg.streamMessage (id: 3 , stream: s1), eg.streamMessage (id: 4 , stream: s2),
1755
+ eg.streamMessage (id: 5 , stream: s1), eg.streamMessage (id: 6 , stream: s2),
1756
+ eg.streamMessage (id: 7 , stream: s1), eg.streamMessage (id: 8 , stream: s2),
1757
+ ];
1758
+ final anchorId = 4 ;
1759
+
1760
+ await prepare (narrow: const CombinedFeedNarrow (),
1761
+ anchor: NumericAnchor (anchorId));
1762
+ await store.addStreams ([s1, s2]);
1763
+ await store.addSubscription (eg.subscription (s1));
1764
+ await store.addSubscription (eg.subscription (s2, isMuted: true ));
1765
+ await prepareMessages (foundOldest: true , foundNewest: true ,
1766
+ messages: messages);
1767
+ // The anchor message is the first visible message with ID at least anchorId…
1768
+ check (model)
1769
+ ..messages[model.middleMessage - 1 ].id.isLessThan (anchorId)
1770
+ ..messages[model.middleMessage].id.isGreaterOrEqual (anchorId);
1771
+ // … even though a non-visible message actually had anchorId itself.
1772
+ check (messages[3 ].id)
1773
+ ..equals (anchorId)
1774
+ ..isLessThan (model.messages[model.middleMessage].id);
1775
+ });
1776
+
1722
1777
/// Like [prepareMessages] , but arrange for the given top and bottom slices.
1723
1778
Future <void > prepareMessageSplit (List <Message > top, List <Message > bottom, {
1724
1779
bool foundOldest = true ,
0 commit comments