Skip to main content

xmtp_db/encrypted_store/
readd_status.rs

1use std::collections::HashSet;
2
3use diesel::prelude::*;
4
5use super::{
6    DbConnection,
7    schema::readd_status::{self},
8};
9use crate::{ConnectionExt, impl_store};
10
11use xmtp_proto::types::GroupId;
12#[derive(Identifiable, Queryable, Selectable, Insertable, Debug, Clone, PartialEq, Eq)]
13#[diesel(table_name = readd_status)]
14#[diesel(primary_key(group_id, installation_id))]
15pub struct ReaddStatus {
16    pub group_id: GroupId,
17    pub installation_id: Vec<u8>,
18    pub requested_at_sequence_id: Option<i64>,
19    pub responded_at_sequence_id: Option<i64>,
20}
21
22impl_store!(ReaddStatus, readd_status);
23
24pub trait QueryReaddStatus {
25    fn get_readd_status(
26        &self,
27        group_id: &GroupId,
28        installation_id: &[u8],
29    ) -> Result<Option<ReaddStatus>, crate::ConnectionError>;
30
31    fn is_awaiting_readd(
32        &self,
33        group_id: &GroupId,
34        installation_id: &[u8],
35    ) -> Result<bool, crate::ConnectionError>;
36
37    /// Update the requested_at_sequence_id for a given group_id and installation_id,
38    /// provided it is higher than the current value.
39    /// Inserts the row if it doesn't exist.
40    fn update_requested_at_sequence_id(
41        &self,
42        group_id: &GroupId,
43        installation_id: &[u8],
44        sequence_id: i64,
45    ) -> Result<(), crate::ConnectionError>;
46
47    /// Update the responded_at_sequence_id for a given group_id and installation_id,
48    /// provided it is higher than the current value.
49    /// Inserts the row if it doesn't exist.
50    fn update_responded_at_sequence_id(
51        &self,
52        group_id: &GroupId,
53        installation_id: &[u8],
54        sequence_id: i64,
55    ) -> Result<(), crate::ConnectionError>;
56
57    fn delete_other_readd_statuses(
58        &self,
59        group_id: &GroupId,
60        self_installation_id: &[u8],
61    ) -> Result<(), crate::ConnectionError>;
62
63    fn delete_readd_statuses(
64        &self,
65        group_id: &GroupId,
66        installation_ids: HashSet<Vec<u8>>,
67    ) -> Result<(), crate::ConnectionError>;
68
69    fn get_readds_awaiting_response(
70        &self,
71        group_id: &GroupId,
72        self_installation_id: &[u8],
73    ) -> Result<Vec<ReaddStatus>, crate::ConnectionError>;
74}
75
76impl<C: ConnectionExt> QueryReaddStatus for DbConnection<C> {
77    fn get_readd_status(
78        &self,
79        group_id: &GroupId,
80        installation_id: &[u8],
81    ) -> Result<Option<ReaddStatus>, crate::ConnectionError> {
82        use super::schema::readd_status::dsl as readd_dsl;
83        use diesel::QueryDsl;
84
85        self.raw_query(|conn| {
86            readd_dsl::readd_status
87                .filter(readd_dsl::group_id.eq(group_id))
88                .filter(readd_dsl::installation_id.eq(installation_id))
89                .first::<ReaddStatus>(conn)
90                .optional()
91        })
92    }
93
94    fn is_awaiting_readd(
95        &self,
96        group_id: &GroupId,
97        installation_id: &[u8],
98    ) -> Result<bool, crate::ConnectionError> {
99        let readd_status = self.get_readd_status(group_id, installation_id)?;
100        if let Some(readd_status) = readd_status
101            && let Some(requested_at) = readd_status.requested_at_sequence_id
102            && requested_at >= readd_status.responded_at_sequence_id.unwrap_or(0)
103        {
104            return Ok(true);
105        }
106        Ok(false)
107    }
108
109    fn update_requested_at_sequence_id(
110        &self,
111        group_id: &GroupId,
112        installation_id: &[u8],
113        sequence_id: i64,
114    ) -> Result<(), crate::ConnectionError> {
115        use super::schema::readd_status::dsl as readd_dsl;
116        use diesel::query_dsl::methods::FilterDsl;
117
118        let new_status = super::readd_status::ReaddStatus {
119            group_id: *group_id,
120            installation_id: installation_id.to_vec(),
121            requested_at_sequence_id: Some(sequence_id),
122            responded_at_sequence_id: None,
123        };
124
125        self.raw_query(|conn| {
126            diesel::insert_into(readd_dsl::readd_status)
127                .values(&new_status)
128                .on_conflict((readd_dsl::group_id, readd_dsl::installation_id))
129                .do_update()
130                .set(readd_dsl::requested_at_sequence_id.eq(sequence_id))
131                .filter(
132                    readd_dsl::requested_at_sequence_id
133                        .is_null()
134                        .or(readd_dsl::requested_at_sequence_id.lt(sequence_id)),
135                )
136                .execute(conn)
137        })?;
138
139        Ok(())
140    }
141
142    fn update_responded_at_sequence_id(
143        &self,
144        group_id: &GroupId,
145        installation_id: &[u8],
146        sequence_id: i64,
147    ) -> Result<(), crate::ConnectionError> {
148        use super::schema::readd_status::dsl as readd_dsl;
149        use diesel::query_dsl::methods::FilterDsl;
150
151        let new_status = super::readd_status::ReaddStatus {
152            group_id: *group_id,
153            installation_id: installation_id.to_vec(),
154            requested_at_sequence_id: None,
155            responded_at_sequence_id: Some(sequence_id),
156        };
157
158        self.raw_query(|conn| {
159            diesel::insert_into(readd_dsl::readd_status)
160                .values(&new_status)
161                .on_conflict((readd_dsl::group_id, readd_dsl::installation_id))
162                .do_update()
163                .set(readd_dsl::responded_at_sequence_id.eq(sequence_id))
164                .filter(
165                    readd_dsl::responded_at_sequence_id
166                        .is_null()
167                        .or(readd_dsl::responded_at_sequence_id.lt(sequence_id)),
168                )
169                .execute(conn)
170        })?;
171
172        Ok(())
173    }
174
175    fn delete_other_readd_statuses(
176        &self,
177        group_id: &GroupId,
178        self_installation_id: &[u8],
179    ) -> Result<(), crate::ConnectionError> {
180        use super::schema::readd_status::dsl as readd_dsl;
181        use diesel::{ExpressionMethods, QueryDsl};
182
183        self.raw_query(|conn| {
184            diesel::delete(
185                readd_dsl::readd_status
186                    .filter(readd_dsl::group_id.eq(group_id))
187                    .filter(readd_dsl::installation_id.ne(self_installation_id)),
188            )
189            .execute(conn)?;
190            Ok(())
191        })
192    }
193
194    fn delete_readd_statuses(
195        &self,
196        group_id: &GroupId,
197        installation_ids: HashSet<Vec<u8>>,
198    ) -> Result<(), crate::ConnectionError> {
199        use super::schema::readd_status::dsl as readd_dsl;
200        use diesel::{ExpressionMethods, QueryDsl};
201
202        self.raw_query(|conn| {
203            diesel::delete(
204                readd_dsl::readd_status
205                    .filter(readd_dsl::group_id.eq(group_id))
206                    .filter(readd_dsl::installation_id.eq_any(installation_ids)),
207            )
208            .execute(conn)?;
209            Ok(())
210        })
211    }
212
213    fn get_readds_awaiting_response(
214        &self,
215        group_id: &GroupId,
216        self_installation_id: &[u8],
217    ) -> Result<Vec<ReaddStatus>, crate::ConnectionError> {
218        use super::schema::readd_status::dsl as readd_dsl;
219        use diesel::{ExpressionMethods, QueryDsl};
220
221        self.raw_query(|conn| {
222            readd_dsl::readd_status
223                .filter(readd_dsl::group_id.eq(group_id))
224                .filter(readd_dsl::installation_id.ne(self_installation_id))
225                .filter(readd_dsl::requested_at_sequence_id.is_not_null())
226                .filter(
227                    readd_dsl::requested_at_sequence_id
228                        .ge(readd_dsl::responded_at_sequence_id)
229                        .or(readd_dsl::responded_at_sequence_id.is_null()),
230                )
231                .load::<ReaddStatus>(conn)
232        })
233    }
234}
235
236impl<T> QueryReaddStatus for &T
237where
238    T: QueryReaddStatus,
239{
240    fn get_readd_status(
241        &self,
242        group_id: &GroupId,
243        installation_id: &[u8],
244    ) -> Result<Option<ReaddStatus>, crate::ConnectionError> {
245        (**self).get_readd_status(group_id, installation_id)
246    }
247
248    fn is_awaiting_readd(
249        &self,
250        group_id: &GroupId,
251        installation_id: &[u8],
252    ) -> Result<bool, crate::ConnectionError> {
253        (**self).is_awaiting_readd(group_id, installation_id)
254    }
255
256    fn update_requested_at_sequence_id(
257        &self,
258        group_id: &GroupId,
259        installation_id: &[u8],
260        sequence_id: i64,
261    ) -> Result<(), crate::ConnectionError> {
262        (**self).update_requested_at_sequence_id(group_id, installation_id, sequence_id)
263    }
264
265    fn update_responded_at_sequence_id(
266        &self,
267        group_id: &GroupId,
268        installation_id: &[u8],
269        sequence_id: i64,
270    ) -> Result<(), crate::ConnectionError> {
271        (**self).update_responded_at_sequence_id(group_id, installation_id, sequence_id)
272    }
273
274    fn delete_other_readd_statuses(
275        &self,
276        group_id: &GroupId,
277        self_installation_id: &[u8],
278    ) -> Result<(), crate::ConnectionError> {
279        (**self).delete_other_readd_statuses(group_id, self_installation_id)
280    }
281
282    fn delete_readd_statuses(
283        &self,
284        group_id: &GroupId,
285        installation_ids: HashSet<Vec<u8>>,
286    ) -> Result<(), crate::ConnectionError> {
287        (**self).delete_readd_statuses(group_id, installation_ids)
288    }
289
290    fn get_readds_awaiting_response(
291        &self,
292        group_id: &GroupId,
293        self_installation_id: &[u8],
294    ) -> Result<Vec<ReaddStatus>, crate::ConnectionError> {
295        (**self).get_readds_awaiting_response(group_id, self_installation_id)
296    }
297}
298
299#[cfg(test)]
300mod tests {
301    use super::*;
302    use crate::{Store, test_utils::with_connection};
303
304    #[xmtp_common::test]
305    fn test_get_readd_status_not_found() {
306        with_connection(|conn| {
307            let group_id = GroupId::ONE;
308            let installation_id = vec![4, 5, 6];
309
310            let result = conn.get_readd_status(&group_id, &installation_id).unwrap();
311            assert!(result.is_none());
312        })
313    }
314
315    #[xmtp_common::test]
316    fn test_store_and_get_readd_status() {
317        with_connection(|conn| {
318            let group_id = GroupId::ONE;
319            let installation_id = vec![4, 5, 6];
320
321            let status = ReaddStatus {
322                group_id,
323                installation_id: installation_id.clone(),
324                requested_at_sequence_id: Some(100),
325                responded_at_sequence_id: Some(50),
326            };
327
328            // Store the status
329            status.store(conn).unwrap();
330
331            // Retrieve it
332            let retrieved = conn.get_readd_status(&group_id, &installation_id).unwrap();
333            assert!(retrieved.is_some());
334            let retrieved_status = retrieved.unwrap();
335            assert_eq!(retrieved_status.requested_at_sequence_id, Some(100));
336            assert_eq!(retrieved_status.responded_at_sequence_id, Some(50));
337        })
338    }
339
340    #[xmtp_common::test]
341    fn test_update_requested_at_sequence_id_creates_new() {
342        with_connection(|conn| {
343            let group_id = GroupId::ONE;
344            let installation_id = vec![4, 5, 6];
345            let sequence_id = 100;
346
347            // Update on non-existing record should create it
348            conn.update_requested_at_sequence_id(&group_id, &installation_id, sequence_id)
349                .unwrap();
350
351            // Verify it was created
352            let status = conn.get_readd_status(&group_id, &installation_id).unwrap();
353            assert!(status.is_some());
354            let status = status.unwrap();
355            assert_eq!(status.requested_at_sequence_id, Some(sequence_id));
356            assert_eq!(status.responded_at_sequence_id, None);
357        })
358    }
359
360    #[xmtp_common::test]
361    fn test_update_requested_at_sequence_id_updates_existing() {
362        with_connection(|conn| {
363            let group_id = GroupId::ONE;
364            let installation_id = vec![4, 5, 6];
365
366            // Create initial status
367            let initial_status = ReaddStatus {
368                group_id,
369                installation_id: installation_id.clone(),
370                requested_at_sequence_id: Some(50),
371                responded_at_sequence_id: Some(25),
372            };
373            initial_status.store(conn).unwrap();
374
375            // Update with higher sequence_id
376            conn.update_requested_at_sequence_id(&group_id, &installation_id, 100)
377                .unwrap();
378
379            // Verify it was updated
380            let status = conn.get_readd_status(&group_id, &installation_id).unwrap();
381            assert!(status.is_some());
382            let status = status.unwrap();
383            assert_eq!(status.requested_at_sequence_id, Some(100));
384            assert_eq!(status.responded_at_sequence_id, Some(25)); // This is preserved by the UPDATE
385        })
386    }
387
388    #[xmtp_common::test]
389    fn test_update_requested_at_sequence_id_only_updates_if_higher() {
390        with_connection(|conn| {
391            let group_id = GroupId::ONE;
392            let installation_id = vec![4, 5, 6];
393
394            // Create initial status with high sequence_id
395            let initial_status = ReaddStatus {
396                group_id,
397                installation_id: installation_id.clone(),
398                requested_at_sequence_id: Some(100),
399                responded_at_sequence_id: Some(50),
400            };
401            initial_status.store(conn).unwrap();
402
403            // Try to update with lower sequence_id - this should be ignored
404            conn.update_requested_at_sequence_id(&group_id, &installation_id, 75)
405                .unwrap();
406
407            // Verify it was NOT updated (lower sequence_id should be ignored due to filter)
408            let status = conn.get_readd_status(&group_id, &installation_id).unwrap();
409            assert!(status.is_some());
410            let status = status.unwrap();
411            assert_eq!(status.requested_at_sequence_id, Some(100)); // Should remain unchanged
412            assert_eq!(status.responded_at_sequence_id, Some(50)); // Should remain unchanged
413        })
414    }
415
416    #[xmtp_common::test]
417    fn test_update_requested_at_sequence_id_updates_from_null() {
418        with_connection(|conn| {
419            let group_id = GroupId::ONE;
420            let installation_id = vec![4, 5, 6];
421
422            // Create initial status with null requested_at_sequence_id
423            let initial_status = ReaddStatus {
424                group_id,
425                installation_id: installation_id.clone(),
426                requested_at_sequence_id: None,
427                responded_at_sequence_id: Some(25),
428            };
429            initial_status.store(conn).unwrap();
430
431            // Update with any sequence_id (should work since current is null)
432            conn.update_requested_at_sequence_id(&group_id, &installation_id, 50)
433                .unwrap();
434
435            // Verify it was updated
436            let status = conn.get_readd_status(&group_id, &installation_id).unwrap();
437            assert!(status.is_some());
438            let status = status.unwrap();
439            assert_eq!(status.requested_at_sequence_id, Some(50));
440            assert_eq!(status.responded_at_sequence_id, Some(25)); // This is preserved by the UPDATE
441        })
442    }
443
444    #[xmtp_common::test]
445    async fn test_update_responded_at_sequence_id_creates_new() {
446        with_connection(|conn| {
447            let group_id = GroupId::ONE;
448            let installation_id = vec![4, 5, 6];
449            let sequence_id = 100;
450
451            // Update on non-existing record should create it
452            conn.update_responded_at_sequence_id(&group_id, &installation_id, sequence_id)
453                .unwrap();
454
455            // Verify it was created
456            let status = conn.get_readd_status(&group_id, &installation_id).unwrap();
457            assert!(status.is_some());
458            let status = status.unwrap();
459            assert_eq!(status.responded_at_sequence_id, Some(sequence_id));
460            assert_eq!(status.requested_at_sequence_id, None);
461        })
462    }
463
464    #[xmtp_common::test]
465    fn test_update_responded_at_sequence_id_only_updates_if_higher() {
466        with_connection(|conn| {
467            let group_id = GroupId::ONE;
468            let installation_id = vec![4, 5, 6];
469
470            // Create initial status with high responded_at_sequence_id
471            let initial_status = ReaddStatus {
472                group_id,
473                installation_id: installation_id.clone(),
474                requested_at_sequence_id: Some(50),
475                responded_at_sequence_id: Some(100),
476            };
477            initial_status.store(conn).unwrap();
478
479            // Try to update with lower sequence_id - this should be ignored
480            conn.update_responded_at_sequence_id(&group_id, &installation_id, 75)
481                .unwrap();
482
483            // Verify it was NOT updated (lower sequence_id should be ignored due to filter)
484            let status = conn.get_readd_status(&group_id, &installation_id).unwrap();
485            assert!(status.is_some());
486            let status = status.unwrap();
487            assert_eq!(status.responded_at_sequence_id, Some(100)); // Should remain unchanged
488            assert_eq!(status.requested_at_sequence_id, Some(50)); // Should remain unchanged
489
490            // Now update with a higher sequence_id - this should work
491            conn.update_responded_at_sequence_id(&group_id, &installation_id, 125)
492                .unwrap();
493
494            // Verify it was updated
495            let status = conn.get_readd_status(&group_id, &installation_id).unwrap();
496            assert!(status.is_some());
497            let status = status.unwrap();
498            assert_eq!(status.responded_at_sequence_id, Some(125)); // Should be updated
499            assert_eq!(status.requested_at_sequence_id, Some(50)); // Should remain unchanged
500        })
501    }
502
503    #[xmtp_common::test]
504    fn test_is_awaiting_readd_no_status() {
505        with_connection(|conn| {
506            let group_id = GroupId::ONE;
507            let installation_id = vec![4, 5, 6];
508
509            // Should return false when no readd status exists
510            let result = conn.is_awaiting_readd(&group_id, &installation_id).unwrap();
511            assert!(!result);
512        })
513    }
514
515    #[xmtp_common::test]
516    fn test_is_awaiting_readd_no_request() {
517        with_connection(|conn| {
518            let group_id = GroupId::ONE;
519            let installation_id = vec![4, 5, 6];
520
521            // Create a readd status without a requested_at_sequence_id
522            ReaddStatus {
523                group_id,
524                installation_id: installation_id.clone(),
525                requested_at_sequence_id: None,
526                responded_at_sequence_id: Some(5),
527            }
528            .store(conn)
529            .unwrap();
530
531            // Should return false when no request has been made
532            let result = conn.is_awaiting_readd(&group_id, &installation_id).unwrap();
533            assert!(!result);
534        })
535    }
536
537    #[xmtp_common::test]
538    fn test_is_awaiting_readd_request_pending() {
539        with_connection(|conn| {
540            let group_id = GroupId::ONE;
541            let installation_id = vec![4, 5, 6];
542
543            // Create a readd status with requested_at > responded_at
544            ReaddStatus {
545                group_id,
546                installation_id: installation_id.clone(),
547                requested_at_sequence_id: Some(10),
548                responded_at_sequence_id: Some(5),
549            }
550            .store(conn)
551            .unwrap();
552
553            // Should return true when request is pending
554            let result = conn.is_awaiting_readd(&group_id, &installation_id).unwrap();
555            assert!(result);
556        })
557    }
558
559    #[xmtp_common::test]
560    fn test_is_awaiting_readd_request_fulfilled() {
561        with_connection(|conn| {
562            let group_id = GroupId::ONE;
563            let installation_id = vec![4, 5, 6];
564
565            // Create a readd status with requested_at <= responded_at
566            ReaddStatus {
567                group_id,
568                installation_id: installation_id.clone(),
569                requested_at_sequence_id: Some(5),
570                responded_at_sequence_id: Some(10),
571            }
572            .store(conn)
573            .unwrap();
574
575            // Should return false when request has been fulfilled
576            let result = conn.is_awaiting_readd(&group_id, &installation_id).unwrap();
577            assert!(!result);
578        })
579    }
580
581    #[xmtp_common::test]
582    fn test_is_awaiting_readd_equal_sequence_ids() {
583        with_connection(|conn| {
584            let group_id = GroupId::ONE;
585            let installation_id = vec![4, 5, 6];
586
587            // Create a readd status with requested_at == responded_at
588            ReaddStatus {
589                group_id,
590                installation_id: installation_id.clone(),
591                requested_at_sequence_id: Some(10),
592                responded_at_sequence_id: Some(10),
593            }
594            .store(conn)
595            .unwrap();
596
597            // Should return true when sequence IDs are equal.
598            // The response to a readd request will always add a commit, which increases the sequence ID.
599            // It is possible that a readd request is subsequently issued at the same sequence ID.
600            let result = conn.is_awaiting_readd(&group_id, &installation_id).unwrap();
601            assert!(result);
602        })
603    }
604
605    #[xmtp_common::test]
606    fn test_is_awaiting_readd_no_responded_at() {
607        with_connection(|conn| {
608            let group_id = GroupId::ONE;
609            let installation_id = vec![4, 5, 6];
610
611            // Create a readd status with requested_at but no responded_at (defaults to 0)
612            ReaddStatus {
613                group_id,
614                installation_id: installation_id.clone(),
615                requested_at_sequence_id: Some(5),
616                responded_at_sequence_id: None,
617            }
618            .store(conn)
619            .unwrap();
620
621            // Should return true when requested_at > 0 (default responded_at)
622            let result = conn.is_awaiting_readd(&group_id, &installation_id).unwrap();
623            assert!(result);
624        })
625    }
626
627    #[xmtp_common::test]
628    fn test_delete_other_readd_statuses() {
629        with_connection(|conn| {
630            let group_id = GroupId::ONE;
631            let keep_installation_id = vec![10, 11, 12];
632            let delete_installation_id_1 = vec![20, 21, 22];
633            let delete_installation_id_2 = vec![30, 31, 32];
634
635            // Create readd statuses for the same group with different installation IDs
636            let status_to_keep = ReaddStatus {
637                group_id,
638                installation_id: keep_installation_id.clone(),
639                requested_at_sequence_id: Some(10),
640                responded_at_sequence_id: Some(5),
641            };
642            status_to_keep.store(conn).unwrap();
643
644            let status_to_delete_1 = ReaddStatus {
645                group_id,
646                installation_id: delete_installation_id_1.clone(),
647                requested_at_sequence_id: Some(15),
648                responded_at_sequence_id: Some(8),
649            };
650            status_to_delete_1.store(conn).unwrap();
651
652            let status_to_delete_2 = ReaddStatus {
653                group_id,
654                installation_id: delete_installation_id_2.clone(),
655                requested_at_sequence_id: Some(20),
656                responded_at_sequence_id: None,
657            };
658            status_to_delete_2.store(conn).unwrap();
659
660            // Create a status for a different group (should not be affected)
661            let different_group_status = ReaddStatus {
662                group_id: GroupId::FOUR,
663                installation_id: vec![40, 41, 42],
664                requested_at_sequence_id: Some(25),
665                responded_at_sequence_id: Some(12),
666            };
667            different_group_status.store(conn).unwrap();
668
669            // Delete other readd statuses for the group
670            conn.delete_other_readd_statuses(&group_id, &keep_installation_id)
671                .unwrap();
672
673            // Verify the status we wanted to keep is still there
674            let kept_status = conn
675                .get_readd_status(&group_id, &keep_installation_id)
676                .unwrap();
677            assert!(kept_status.is_some());
678
679            // Verify the other statuses in the same group were deleted
680            let deleted_status_1 = conn
681                .get_readd_status(&group_id, &delete_installation_id_1)
682                .unwrap();
683            assert!(deleted_status_1.is_none());
684
685            let deleted_status_2 = conn
686                .get_readd_status(&group_id, &delete_installation_id_2)
687                .unwrap();
688            assert!(deleted_status_2.is_none());
689
690            // Verify the status in the different group was not affected
691            let different_group_check = conn
692                .get_readd_status(&GroupId::FOUR, &[40, 41, 42])
693                .unwrap();
694            assert!(different_group_check.is_some());
695        })
696    }
697
698    #[xmtp_common::test]
699    fn test_get_readds_awaiting_response() {
700        with_connection(|conn| {
701            let group_id = GroupId::ONE;
702            let self_installation_id = vec![10, 11, 12];
703            let other_installation_id_1 = vec![20, 21, 22];
704            let other_installation_id_2 = vec![30, 31, 32];
705
706            // Create readd statuses with various states
707
708            // Case 1: Pending readd from other installation (should be included)
709            let pending_status_1 = ReaddStatus {
710                group_id,
711                installation_id: other_installation_id_1.clone(),
712                requested_at_sequence_id: Some(10),
713                responded_at_sequence_id: Some(5),
714            };
715            pending_status_1.store(conn).unwrap();
716
717            // Case 2: Pending readd from other installation with null responded_at (should be included)
718            let pending_status_2 = ReaddStatus {
719                group_id,
720                installation_id: other_installation_id_2.clone(),
721                requested_at_sequence_id: Some(15),
722                responded_at_sequence_id: None,
723            };
724            pending_status_2.store(conn).unwrap();
725
726            // Case 3: Not pending readd from other installation (should be excluded)
727            let fulfilled_status = ReaddStatus {
728                group_id,
729                installation_id: vec![40, 41, 42],
730                requested_at_sequence_id: Some(8),
731                responded_at_sequence_id: Some(12),
732            };
733            fulfilled_status.store(conn).unwrap();
734
735            // Case 4: Pending readd from self installation (should be excluded)
736            let self_status = ReaddStatus {
737                group_id,
738                installation_id: self_installation_id.clone(),
739                requested_at_sequence_id: Some(20),
740                responded_at_sequence_id: Some(10),
741            };
742            self_status.store(conn).unwrap();
743
744            // Case 5: No requested_at_sequence_id (should be excluded)
745            let no_request_status = ReaddStatus {
746                group_id,
747                installation_id: vec![50, 51, 52],
748                requested_at_sequence_id: None,
749                responded_at_sequence_id: Some(5),
750            };
751            no_request_status.store(conn).unwrap();
752
753            // Case 6: Different group (should be excluded)
754            let different_group_status = ReaddStatus {
755                group_id: GroupId::FOUR,
756                installation_id: vec![60, 61, 62],
757                requested_at_sequence_id: Some(25),
758                responded_at_sequence_id: Some(15),
759            };
760            different_group_status.store(conn).unwrap();
761
762            // Call the method under test
763            let result = conn
764                .get_readds_awaiting_response(&group_id, &self_installation_id)
765                .unwrap();
766
767            // Should return 2 pending readds from other installations
768            assert_eq!(result.len(), 2);
769
770            // Verify the correct statuses are returned
771            let returned_installations: Vec<Vec<u8>> =
772                result.iter().map(|r| r.installation_id.clone()).collect();
773            assert!(returned_installations.contains(&other_installation_id_1));
774            assert!(returned_installations.contains(&other_installation_id_2));
775
776            // Verify the details of the returned statuses
777            for status in result {
778                assert_eq!(status.group_id.as_slice(), group_id.as_slice());
779                assert_ne!(status.installation_id, self_installation_id);
780                assert!(status.requested_at_sequence_id.is_some());
781
782                // Check that the awaiting response condition is met
783                let requested_at = status.requested_at_sequence_id.unwrap();
784                let responded_at = status.responded_at_sequence_id.unwrap_or(0);
785                assert!(requested_at >= responded_at);
786            }
787        })
788    }
789}