mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-18 13:40:55 -04:00
test(indexeddb): add IndexedDB-specific integration tests
Signed-off-by: Michael Goldenberg <m@mgoldenberg.net>
This commit is contained in:
committed by
Ivan Enderlin
parent
2e7721b36c
commit
c5436ed73e
@@ -0,0 +1,552 @@
|
||||
// Copyright 2025 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License
|
||||
|
||||
use assert_matches::assert_matches;
|
||||
use matrix_sdk_base::{
|
||||
event_cache::{
|
||||
store::{
|
||||
integration_tests::{check_test_event, make_test_event},
|
||||
EventCacheStore,
|
||||
},
|
||||
Gap,
|
||||
},
|
||||
linked_chunk::{ChunkContent, ChunkIdentifier, LinkedChunkId, Position, Update},
|
||||
};
|
||||
use matrix_sdk_test::DEFAULT_TEST_ROOM_ID;
|
||||
use ruma::room_id;
|
||||
|
||||
use crate::event_cache_store::{
|
||||
transaction::IndexeddbEventCacheStoreTransactionError, IndexeddbEventCacheStore,
|
||||
IndexeddbEventCacheStoreError,
|
||||
};
|
||||
|
||||
pub async fn test_linked_chunk_new_items_chunk(store: IndexeddbEventCacheStore) {
|
||||
let room_id = &DEFAULT_TEST_ROOM_ID;
|
||||
let linked_chunk_id = LinkedChunkId::Room(room_id);
|
||||
let updates = vec![
|
||||
Update::NewItemsChunk {
|
||||
previous: None,
|
||||
new: ChunkIdentifier::new(42),
|
||||
next: None, // Note: the store must link the next entry itself.
|
||||
},
|
||||
Update::NewItemsChunk {
|
||||
previous: Some(ChunkIdentifier::new(42)),
|
||||
new: ChunkIdentifier::new(13),
|
||||
next: Some(ChunkIdentifier::new(37)), /* But it's fine to explicitly pass
|
||||
* the next link ahead of time. */
|
||||
},
|
||||
Update::NewItemsChunk {
|
||||
previous: Some(ChunkIdentifier::new(13)),
|
||||
new: ChunkIdentifier::new(37),
|
||||
next: None,
|
||||
},
|
||||
];
|
||||
store.handle_linked_chunk_updates(linked_chunk_id, updates).await.unwrap();
|
||||
|
||||
let mut chunks = store.load_all_chunks(linked_chunk_id).await.unwrap();
|
||||
assert_eq!(chunks.len(), 3);
|
||||
|
||||
// Chunks are ordered from smaller to bigger IDs.
|
||||
let c = chunks.remove(0);
|
||||
assert_eq!(c.identifier, ChunkIdentifier::new(13));
|
||||
assert_eq!(c.previous, Some(ChunkIdentifier::new(42)));
|
||||
assert_eq!(c.next, Some(ChunkIdentifier::new(37)));
|
||||
assert_matches!(c.content, ChunkContent::Items(events) => {
|
||||
assert!(events.is_empty());
|
||||
});
|
||||
|
||||
let c = chunks.remove(0);
|
||||
assert_eq!(c.identifier, ChunkIdentifier::new(37));
|
||||
assert_eq!(c.previous, Some(ChunkIdentifier::new(13)));
|
||||
assert_eq!(c.next, None);
|
||||
assert_matches!(c.content, ChunkContent::Items(events) => {
|
||||
assert!(events.is_empty());
|
||||
});
|
||||
|
||||
let c = chunks.remove(0);
|
||||
assert_eq!(c.identifier, ChunkIdentifier::new(42));
|
||||
assert_eq!(c.previous, None);
|
||||
assert_eq!(c.next, Some(ChunkIdentifier::new(13)));
|
||||
assert_matches!(c.content, ChunkContent::Items(events) => {
|
||||
assert!(events.is_empty());
|
||||
});
|
||||
}
|
||||
|
||||
pub async fn test_add_gap_chunk_and_delete_it_immediately(store: IndexeddbEventCacheStore) {
|
||||
let room_id = &DEFAULT_TEST_ROOM_ID;
|
||||
let linked_chunk_id = LinkedChunkId::Room(room_id);
|
||||
let updates = vec![Update::NewGapChunk {
|
||||
previous: None,
|
||||
new: ChunkIdentifier::new(1),
|
||||
next: None,
|
||||
gap: Gap { prev_token: "cheese".to_owned() },
|
||||
}];
|
||||
store.handle_linked_chunk_updates(linked_chunk_id, updates).await.unwrap();
|
||||
|
||||
let updates = vec![
|
||||
Update::NewGapChunk {
|
||||
previous: Some(ChunkIdentifier::new(1)),
|
||||
new: ChunkIdentifier::new(3),
|
||||
next: None,
|
||||
gap: Gap { prev_token: "milk".to_owned() },
|
||||
},
|
||||
Update::RemoveChunk(ChunkIdentifier::new(3)),
|
||||
];
|
||||
store.handle_linked_chunk_updates(linked_chunk_id, updates).await.unwrap();
|
||||
|
||||
let chunks = store.load_all_chunks(linked_chunk_id).await.unwrap();
|
||||
assert_eq!(chunks.len(), 1);
|
||||
}
|
||||
|
||||
pub async fn test_linked_chunk_new_gap_chunk(store: IndexeddbEventCacheStore) {
|
||||
let room_id = &DEFAULT_TEST_ROOM_ID;
|
||||
let linked_chunk_id = LinkedChunkId::Room(room_id);
|
||||
let updates = vec![Update::NewGapChunk {
|
||||
previous: None,
|
||||
new: ChunkIdentifier::new(42),
|
||||
next: None,
|
||||
gap: Gap { prev_token: "raclette".to_owned() },
|
||||
}];
|
||||
store.handle_linked_chunk_updates(linked_chunk_id, updates).await.unwrap();
|
||||
|
||||
let mut chunks = store.load_all_chunks(linked_chunk_id).await.unwrap();
|
||||
assert_eq!(chunks.len(), 1);
|
||||
|
||||
// Chunks are ordered from smaller to bigger IDs.
|
||||
let c = chunks.remove(0);
|
||||
assert_eq!(c.identifier, ChunkIdentifier::new(42));
|
||||
assert_eq!(c.previous, None);
|
||||
assert_eq!(c.next, None);
|
||||
assert_matches!(c.content, ChunkContent::Gap(gap) => {
|
||||
assert_eq!(gap.prev_token, "raclette");
|
||||
});
|
||||
}
|
||||
|
||||
pub async fn test_linked_chunk_replace_item(store: IndexeddbEventCacheStore) {
|
||||
let room_id = &DEFAULT_TEST_ROOM_ID;
|
||||
let linked_chunk_id = LinkedChunkId::Room(room_id);
|
||||
let updates = vec![
|
||||
Update::NewItemsChunk { previous: None, new: ChunkIdentifier::new(42), next: None },
|
||||
Update::PushItems {
|
||||
at: Position::new(ChunkIdentifier::new(42), 0),
|
||||
items: vec![make_test_event(room_id, "hello"), make_test_event(room_id, "world")],
|
||||
},
|
||||
Update::ReplaceItem {
|
||||
at: Position::new(ChunkIdentifier::new(42), 1),
|
||||
item: make_test_event(room_id, "yolo"),
|
||||
},
|
||||
];
|
||||
store.handle_linked_chunk_updates(linked_chunk_id, updates).await.unwrap();
|
||||
|
||||
let mut chunks = store.load_all_chunks(linked_chunk_id).await.unwrap();
|
||||
assert_eq!(chunks.len(), 1);
|
||||
|
||||
let c = chunks.remove(0);
|
||||
assert_eq!(c.identifier, ChunkIdentifier::new(42));
|
||||
assert_eq!(c.previous, None);
|
||||
assert_eq!(c.next, None);
|
||||
assert_matches!(c.content, ChunkContent::Items(events) => {
|
||||
assert_eq!(events.len(), 2);
|
||||
check_test_event(&events[0], "hello");
|
||||
check_test_event(&events[1], "yolo");
|
||||
});
|
||||
}
|
||||
|
||||
pub async fn test_linked_chunk_remove_chunk(store: IndexeddbEventCacheStore) {
|
||||
let room_id = &DEFAULT_TEST_ROOM_ID;
|
||||
let linked_chunk_id = LinkedChunkId::Room(room_id);
|
||||
let updates = vec![
|
||||
Update::NewGapChunk {
|
||||
previous: None,
|
||||
new: ChunkIdentifier::new(42),
|
||||
next: None,
|
||||
gap: Gap { prev_token: "raclette".to_owned() },
|
||||
},
|
||||
Update::NewGapChunk {
|
||||
previous: Some(ChunkIdentifier::new(42)),
|
||||
new: ChunkIdentifier::new(43),
|
||||
next: None,
|
||||
gap: Gap { prev_token: "fondue".to_owned() },
|
||||
},
|
||||
Update::NewGapChunk {
|
||||
previous: Some(ChunkIdentifier::new(43)),
|
||||
new: ChunkIdentifier::new(44),
|
||||
next: None,
|
||||
gap: Gap { prev_token: "tartiflette".to_owned() },
|
||||
},
|
||||
Update::RemoveChunk(ChunkIdentifier::new(43)),
|
||||
];
|
||||
store.handle_linked_chunk_updates(linked_chunk_id, updates).await.unwrap();
|
||||
|
||||
let mut chunks = store.load_all_chunks(linked_chunk_id).await.unwrap();
|
||||
assert_eq!(chunks.len(), 2);
|
||||
|
||||
// Chunks are ordered from smaller to bigger IDs.
|
||||
let c = chunks.remove(0);
|
||||
assert_eq!(c.identifier, ChunkIdentifier::new(42));
|
||||
assert_eq!(c.previous, None);
|
||||
assert_eq!(c.next, Some(ChunkIdentifier::new(44)));
|
||||
assert_matches!(c.content, ChunkContent::Gap(gap) => {
|
||||
assert_eq!(gap.prev_token, "raclette");
|
||||
});
|
||||
|
||||
let c = chunks.remove(0);
|
||||
assert_eq!(c.identifier, ChunkIdentifier::new(44));
|
||||
assert_eq!(c.previous, Some(ChunkIdentifier::new(42)));
|
||||
assert_eq!(c.next, None);
|
||||
assert_matches!(c.content, ChunkContent::Gap(gap) => {
|
||||
assert_eq!(gap.prev_token, "tartiflette");
|
||||
});
|
||||
}
|
||||
|
||||
pub async fn test_linked_chunk_push_items(store: IndexeddbEventCacheStore) {
|
||||
let room_id = &DEFAULT_TEST_ROOM_ID;
|
||||
let linked_chunk_id = LinkedChunkId::Room(room_id);
|
||||
let updates = vec![
|
||||
Update::NewItemsChunk { previous: None, new: ChunkIdentifier::new(42), next: None },
|
||||
Update::PushItems {
|
||||
at: Position::new(ChunkIdentifier::new(42), 0),
|
||||
items: vec![make_test_event(room_id, "hello"), make_test_event(room_id, "world")],
|
||||
},
|
||||
Update::PushItems {
|
||||
at: Position::new(ChunkIdentifier::new(42), 2),
|
||||
items: vec![make_test_event(room_id, "who?")],
|
||||
},
|
||||
];
|
||||
store.handle_linked_chunk_updates(linked_chunk_id, updates).await.unwrap();
|
||||
|
||||
let mut chunks = store.load_all_chunks(linked_chunk_id).await.unwrap();
|
||||
assert_eq!(chunks.len(), 1);
|
||||
|
||||
let c = chunks.remove(0);
|
||||
assert_eq!(c.identifier, ChunkIdentifier::new(42));
|
||||
assert_eq!(c.previous, None);
|
||||
assert_eq!(c.next, None);
|
||||
assert_matches!(c.content, ChunkContent::Items(events) => {
|
||||
assert_eq!(events.len(), 3);
|
||||
check_test_event(&events[0], "hello");
|
||||
check_test_event(&events[1], "world");
|
||||
check_test_event(&events[2], "who?");
|
||||
});
|
||||
}
|
||||
|
||||
pub async fn test_linked_chunk_remove_item(store: IndexeddbEventCacheStore) {
|
||||
let room_id = &DEFAULT_TEST_ROOM_ID;
|
||||
let linked_chunk_id = LinkedChunkId::Room(room_id);
|
||||
let updates = vec![
|
||||
Update::NewItemsChunk { previous: None, new: ChunkIdentifier::new(42), next: None },
|
||||
Update::PushItems {
|
||||
at: Position::new(ChunkIdentifier::new(42), 0),
|
||||
items: vec![make_test_event(room_id, "hello"), make_test_event(room_id, "world")],
|
||||
},
|
||||
Update::RemoveItem { at: Position::new(ChunkIdentifier::new(42), 0) },
|
||||
];
|
||||
store.handle_linked_chunk_updates(linked_chunk_id, updates).await.unwrap();
|
||||
|
||||
let mut chunks = store.load_all_chunks(linked_chunk_id).await.unwrap();
|
||||
assert_eq!(chunks.len(), 1);
|
||||
|
||||
let c = chunks.remove(0);
|
||||
assert_eq!(c.identifier, ChunkIdentifier::new(42));
|
||||
assert_eq!(c.previous, None);
|
||||
assert_eq!(c.next, None);
|
||||
assert_matches!(c.content, ChunkContent::Items(events) => {
|
||||
assert_eq!(events.len(), 1);
|
||||
check_test_event(&events[0], "world");
|
||||
});
|
||||
}
|
||||
|
||||
pub async fn test_linked_chunk_detach_last_items(store: IndexeddbEventCacheStore) {
|
||||
let room_id = &DEFAULT_TEST_ROOM_ID;
|
||||
let linked_chunk_id = LinkedChunkId::Room(room_id);
|
||||
let updates = vec![
|
||||
Update::NewItemsChunk { previous: None, new: ChunkIdentifier::new(42), next: None },
|
||||
Update::PushItems {
|
||||
at: Position::new(ChunkIdentifier::new(42), 0),
|
||||
items: vec![
|
||||
make_test_event(room_id, "hello"),
|
||||
make_test_event(room_id, "world"),
|
||||
make_test_event(room_id, "howdy"),
|
||||
],
|
||||
},
|
||||
Update::DetachLastItems { at: Position::new(ChunkIdentifier::new(42), 1) },
|
||||
];
|
||||
store.handle_linked_chunk_updates(linked_chunk_id, updates).await.unwrap();
|
||||
|
||||
let mut chunks = store.load_all_chunks(linked_chunk_id).await.unwrap();
|
||||
assert_eq!(chunks.len(), 1);
|
||||
|
||||
let c = chunks.remove(0);
|
||||
assert_eq!(c.identifier, ChunkIdentifier::new(42));
|
||||
assert_eq!(c.previous, None);
|
||||
assert_eq!(c.next, None);
|
||||
assert_matches!(c.content, ChunkContent::Items(events) => {
|
||||
assert_eq!(events.len(), 1);
|
||||
check_test_event(&events[0], "hello");
|
||||
});
|
||||
}
|
||||
|
||||
pub async fn test_linked_chunk_start_end_reattach_items(store: IndexeddbEventCacheStore) {
|
||||
let room_id = &DEFAULT_TEST_ROOM_ID;
|
||||
let linked_chunk_id = LinkedChunkId::Room(room_id);
|
||||
// Same updates and checks as test_linked_chunk_push_items, but with extra
|
||||
// `StartReattachItems` and `EndReattachItems` updates, which must have no
|
||||
// effects.
|
||||
let updates = vec![
|
||||
Update::NewItemsChunk { previous: None, new: ChunkIdentifier::new(42), next: None },
|
||||
Update::PushItems {
|
||||
at: Position::new(ChunkIdentifier::new(42), 0),
|
||||
items: vec![
|
||||
make_test_event(room_id, "hello"),
|
||||
make_test_event(room_id, "world"),
|
||||
make_test_event(room_id, "howdy"),
|
||||
],
|
||||
},
|
||||
Update::StartReattachItems,
|
||||
Update::EndReattachItems,
|
||||
];
|
||||
store.handle_linked_chunk_updates(linked_chunk_id, updates).await.unwrap();
|
||||
|
||||
let mut chunks = store.load_all_chunks(linked_chunk_id).await.unwrap();
|
||||
assert_eq!(chunks.len(), 1);
|
||||
|
||||
let c = chunks.remove(0);
|
||||
assert_eq!(c.identifier, ChunkIdentifier::new(42));
|
||||
assert_eq!(c.previous, None);
|
||||
assert_eq!(c.next, None);
|
||||
assert_matches!(c.content, ChunkContent::Items(events) => {
|
||||
assert_eq!(events.len(), 3);
|
||||
check_test_event(&events[0], "hello");
|
||||
check_test_event(&events[1], "world");
|
||||
check_test_event(&events[2], "howdy");
|
||||
});
|
||||
}
|
||||
|
||||
pub async fn test_linked_chunk_clear(store: IndexeddbEventCacheStore) {
|
||||
let room_id = &DEFAULT_TEST_ROOM_ID;
|
||||
let linked_chunk_id = LinkedChunkId::Room(room_id);
|
||||
let updates = vec![
|
||||
Update::NewItemsChunk { previous: None, new: ChunkIdentifier::new(42), next: None },
|
||||
Update::NewGapChunk {
|
||||
previous: Some(ChunkIdentifier::new(42)),
|
||||
new: ChunkIdentifier::new(54),
|
||||
next: None,
|
||||
gap: Gap { prev_token: "fondue".to_owned() },
|
||||
},
|
||||
Update::PushItems {
|
||||
at: Position::new(ChunkIdentifier::new(42), 0),
|
||||
items: vec![
|
||||
make_test_event(room_id, "hello"),
|
||||
make_test_event(room_id, "world"),
|
||||
make_test_event(room_id, "howdy"),
|
||||
],
|
||||
},
|
||||
Update::Clear,
|
||||
];
|
||||
store.handle_linked_chunk_updates(linked_chunk_id, updates).await.unwrap();
|
||||
|
||||
let chunks = store.load_all_chunks(linked_chunk_id).await.unwrap();
|
||||
assert!(chunks.is_empty());
|
||||
}
|
||||
|
||||
pub async fn test_linked_chunk_multiple_rooms(store: IndexeddbEventCacheStore) {
|
||||
// Check that applying updates to one room doesn't affect the others.
|
||||
// Use the same chunk identifier in both rooms to battle-test search.
|
||||
let room_id1 = room_id!("!realcheeselovers:raclette.fr");
|
||||
let linked_chunk_id1 = LinkedChunkId::Room(room_id1);
|
||||
let updates1 = vec![
|
||||
Update::NewItemsChunk { previous: None, new: ChunkIdentifier::new(42), next: None },
|
||||
Update::PushItems {
|
||||
at: Position::new(ChunkIdentifier::new(42), 0),
|
||||
items: vec![
|
||||
make_test_event(room_id1, "best cheese is raclette"),
|
||||
make_test_event(room_id1, "obviously"),
|
||||
],
|
||||
},
|
||||
];
|
||||
store.handle_linked_chunk_updates(linked_chunk_id1, updates1).await.unwrap();
|
||||
|
||||
let room_id2 = room_id!("!realcheeselovers:fondue.ch");
|
||||
let linked_chunk_id2 = LinkedChunkId::Room(room_id2);
|
||||
let updates2 = vec![
|
||||
Update::NewItemsChunk { previous: None, new: ChunkIdentifier::new(42), next: None },
|
||||
Update::PushItems {
|
||||
at: Position::new(ChunkIdentifier::new(42), 0),
|
||||
items: vec![make_test_event(room_id2, "beaufort is the best")],
|
||||
},
|
||||
];
|
||||
store.handle_linked_chunk_updates(linked_chunk_id2, updates2).await.unwrap();
|
||||
|
||||
// Check chunks from room 1.
|
||||
let mut chunks1 = store.load_all_chunks(linked_chunk_id1).await.unwrap();
|
||||
assert_eq!(chunks1.len(), 1);
|
||||
|
||||
let c = chunks1.remove(0);
|
||||
assert_matches!(c.content, ChunkContent::Items(events) => {
|
||||
assert_eq!(events.len(), 2);
|
||||
check_test_event(&events[0], "best cheese is raclette");
|
||||
check_test_event(&events[1], "obviously");
|
||||
});
|
||||
|
||||
// Check chunks from room 2.
|
||||
let mut chunks2 = store.load_all_chunks(linked_chunk_id2).await.unwrap();
|
||||
assert_eq!(chunks2.len(), 1);
|
||||
|
||||
let c = chunks2.remove(0);
|
||||
assert_matches!(c.content, ChunkContent::Items(events) => {
|
||||
assert_eq!(events.len(), 1);
|
||||
check_test_event(&events[0], "beaufort is the best");
|
||||
});
|
||||
}
|
||||
|
||||
pub async fn test_linked_chunk_update_is_a_transaction(store: IndexeddbEventCacheStore) {
|
||||
let linked_chunk_id = LinkedChunkId::Room(*DEFAULT_TEST_ROOM_ID);
|
||||
// Trigger a violation of the unique constraint on the (room id, chunk id)
|
||||
// couple.
|
||||
let updates = vec![
|
||||
Update::NewItemsChunk { previous: None, new: ChunkIdentifier::new(42), next: None },
|
||||
Update::NewItemsChunk { previous: None, new: ChunkIdentifier::new(42), next: None },
|
||||
];
|
||||
let err = store.handle_linked_chunk_updates(linked_chunk_id, updates).await.unwrap_err();
|
||||
|
||||
// The operation fails with a constraint violation error.
|
||||
assert_matches!(
|
||||
err,
|
||||
IndexeddbEventCacheStoreError::Transaction(
|
||||
IndexeddbEventCacheStoreTransactionError::DomException { .. }
|
||||
)
|
||||
);
|
||||
|
||||
// If the updates have been handled transactionally, then no new chunks should
|
||||
// have been added; failure of the second update leads to the first one being
|
||||
// rolled back.
|
||||
let chunks = store.load_all_chunks(linked_chunk_id).await.unwrap();
|
||||
assert!(chunks.is_empty());
|
||||
}
|
||||
|
||||
/// Macro for generating tests for IndexedDB implementation of
|
||||
/// [`EventCacheStore`]
|
||||
///
|
||||
/// The enclosing module must provide a function for constructing an
|
||||
/// [`EventCacheStore`] which will be used in the generated tests. The function
|
||||
/// must have the signature shown in the example below.
|
||||
///
|
||||
///
|
||||
/// ## Usage Example:
|
||||
/// ```no_run
|
||||
/// # use matrix_sdk_base::event_cache::store::{
|
||||
/// # EventCacheStore,
|
||||
/// # EventCacheStoreError,
|
||||
/// # MemoryStore as MyStore,
|
||||
/// # };
|
||||
///
|
||||
/// #[cfg(test)]
|
||||
/// mod tests {
|
||||
/// use super::{EventCacheStore, EventCacheStoreResult, MyStore};
|
||||
///
|
||||
/// async fn get_event_cache_store(
|
||||
/// ) -> Result<impl EventCacheStore, EventCacheStoreError> {
|
||||
/// Ok(MyStore::new())
|
||||
/// }
|
||||
///
|
||||
/// event_cache_store_integration_tests!();
|
||||
/// }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! indexeddb_event_cache_store_integration_tests {
|
||||
() => {
|
||||
mod indexeddb_event_cache_store_integration_tests {
|
||||
use matrix_sdk_test::async_test;
|
||||
|
||||
use super::get_event_cache_store;
|
||||
|
||||
#[async_test]
|
||||
async fn test_linked_chunk_new_items_chunk() {
|
||||
let store = get_event_cache_store().await.expect("Failed to get event cache store");
|
||||
$crate::event_cache_store::integration_tests::test_linked_chunk_new_items_chunk(store).await
|
||||
}
|
||||
|
||||
#[async_test]
|
||||
async fn test_add_gap_chunk_and_delete_it_immediately() {
|
||||
let store = get_event_cache_store().await.expect("Failed to get event cache store");
|
||||
$crate::event_cache_store::integration_tests::test_add_gap_chunk_and_delete_it_immediately(
|
||||
store,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
#[async_test]
|
||||
async fn test_linked_chunk_new_gap_chunk() {
|
||||
let store = get_event_cache_store().await.expect("Failed to get event cache store");
|
||||
$crate::event_cache_store::integration_tests::test_linked_chunk_new_gap_chunk(store).await
|
||||
}
|
||||
|
||||
#[async_test]
|
||||
async fn test_linked_chunk_replace_item() {
|
||||
let store = get_event_cache_store().await.expect("Failed to get event cache store");
|
||||
$crate::event_cache_store::integration_tests::test_linked_chunk_replace_item(store).await
|
||||
}
|
||||
|
||||
#[async_test]
|
||||
async fn test_linked_chunk_remove_chunk() {
|
||||
let store = get_event_cache_store().await.expect("Failed to get event cache store");
|
||||
$crate::event_cache_store::integration_tests::test_linked_chunk_remove_chunk(store).await
|
||||
}
|
||||
|
||||
#[async_test]
|
||||
async fn test_linked_chunk_push_items() {
|
||||
let store = get_event_cache_store().await.expect("Failed to get event cache store");
|
||||
$crate::event_cache_store::integration_tests::test_linked_chunk_push_items(store).await
|
||||
}
|
||||
|
||||
#[async_test]
|
||||
async fn test_linked_chunk_remove_item() {
|
||||
let store = get_event_cache_store().await.expect("Failed to get event cache store");
|
||||
$crate::event_cache_store::integration_tests::test_linked_chunk_remove_item(store).await
|
||||
}
|
||||
|
||||
#[async_test]
|
||||
async fn test_linked_chunk_detach_last_items() {
|
||||
let store = get_event_cache_store().await.expect("Failed to get event cache store");
|
||||
$crate::event_cache_store::integration_tests::test_linked_chunk_detach_last_items(store).await
|
||||
}
|
||||
|
||||
#[async_test]
|
||||
async fn test_linked_chunk_start_end_reattach_items() {
|
||||
let store = get_event_cache_store().await.expect("Failed to get event cache store");
|
||||
$crate::event_cache_store::integration_tests::test_linked_chunk_start_end_reattach_items(store)
|
||||
.await
|
||||
}
|
||||
|
||||
#[async_test]
|
||||
async fn test_linked_chunk_clear() {
|
||||
let store = get_event_cache_store().await.expect("Failed to get event cache store");
|
||||
$crate::event_cache_store::integration_tests::test_linked_chunk_clear(store).await
|
||||
}
|
||||
|
||||
#[async_test]
|
||||
async fn test_linked_chunk_multiple_rooms() {
|
||||
let store = get_event_cache_store().await.expect("Failed to get event cache store");
|
||||
$crate::event_cache_store::integration_tests::test_linked_chunk_multiple_rooms(store).await
|
||||
}
|
||||
|
||||
#[async_test]
|
||||
async fn test_linked_chunk_update_is_a_transaction() {
|
||||
let store = get_event_cache_store().await.expect("Failed to get event cache store");
|
||||
$crate::event_cache_store::integration_tests::test_linked_chunk_update_is_a_transaction(store)
|
||||
.await
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -42,6 +42,8 @@ use crate::event_cache_store::{
|
||||
|
||||
mod builder;
|
||||
mod error;
|
||||
#[cfg(test)]
|
||||
mod integration_tests;
|
||||
mod migrations;
|
||||
mod serializer;
|
||||
mod transaction;
|
||||
@@ -462,3 +464,39 @@ impl_event_cache_store! {
|
||||
.map_err(IndexeddbEventCacheStoreError::MemoryStore)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use matrix_sdk_base::event_cache::store::{EventCacheStore, EventCacheStoreError};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
event_cache_store::IndexeddbEventCacheStore, indexeddb_event_cache_store_integration_tests,
|
||||
};
|
||||
|
||||
mod unencrypted {
|
||||
use super::*;
|
||||
|
||||
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
async fn get_event_cache_store() -> Result<IndexeddbEventCacheStore, EventCacheStoreError> {
|
||||
let name = format!("test-event-cache-store-{}", Uuid::new_v4().as_hyphenated());
|
||||
Ok(IndexeddbEventCacheStore::builder().database_name(name).build().await?)
|
||||
}
|
||||
|
||||
indexeddb_event_cache_store_integration_tests!();
|
||||
}
|
||||
|
||||
mod encrypted {
|
||||
use super::*;
|
||||
|
||||
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
async fn get_event_cache_store() -> Result<IndexeddbEventCacheStore, EventCacheStoreError> {
|
||||
let name = format!("test-event-cache-store-{}", Uuid::new_v4().as_hyphenated());
|
||||
Ok(IndexeddbEventCacheStore::builder().database_name(name).build().await?)
|
||||
}
|
||||
|
||||
indexeddb_event_cache_store_integration_tests!();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user