use lb_rs::Lb;
use lb_rs::model::file::{File, ShareMode};
use lb_rs::model::file_metadata::FileType;
use std::collections::HashSet;
use test_utils::*;
use uuid::Uuid;
async fn assert_valid_list_metadatas(c: &Lb) {
let mut files: HashSet<Uuid> = HashSet::new();
for file in c.list_metadatas().await.unwrap() {
if !file.is_document() && !file.is_folder() {
panic!("non document/folder file in listed metadata: {file:#?}");
}
files.insert(file.id);
}
for file in c.list_metadatas().await.unwrap() {
assert!(files.contains(&file.parent));
}
}
#[tokio::test]
async fn get_path_document_link() {
let cores: Vec<Lb> = vec![test_core_with_account().await, test_core_with_account().await];
let accounts = cores
.iter()
.map(|core| core.get_account().unwrap())
.collect::<Vec<_>>();
let document = cores[0].create_at_path("document").await.unwrap();
cores[0]
.share_file(document.id, &accounts[1].username, ShareMode::Write)
.await
.unwrap();
cores[0].sync().await.unwrap();
cores[1].sync().await.unwrap();
cores[1]
.create_link_at_path("link", document.id)
.await
.unwrap();
assert_valid_list_metadatas(&cores[0]).await;
assert_valid_list_metadatas(&cores[1]).await;
assert_eq!(cores[1].get_by_path("/link").await.unwrap().id, document.id);
}
#[tokio::test]
async fn get_path_folder_link() {
let cores: Vec<Lb> = vec![test_core_with_account().await, test_core_with_account().await];
let accounts = cores
.iter()
.map(|core| core.get_account().unwrap())
.collect::<Vec<_>>();
let folder = cores[0].create_at_path("folder/").await.unwrap();
cores[0]
.share_file(folder.id, &accounts[1].username, ShareMode::Write)
.await
.unwrap();
cores[0].sync().await.unwrap();
cores[1].sync().await.unwrap();
cores[1]
.create_link_at_path("link", folder.id)
.await
.unwrap();
assert_valid_list_metadatas(&cores[0]).await;
assert_valid_list_metadatas(&cores[1]).await;
assert_eq!(cores[1].get_by_path("/link").await.unwrap().id, folder.id);
}
#[tokio::test]
async fn create_path_doc_under_link() {
let cores = [test_core_with_account().await, test_core_with_account().await];
let accounts = cores
.iter()
.map(|core| core.get_account().unwrap())
.collect::<Vec<_>>();
let roots = [cores[0].root().await.unwrap(), cores[1].root().await.unwrap()];
let folder = cores[0].create_at_path("folder/").await.unwrap();
cores[0]
.share_file(folder.id, &accounts[1].username, ShareMode::Write)
.await
.unwrap();
cores[0].sync().await.unwrap();
cores[1].sync().await.unwrap();
cores[1]
.create_link_at_path("link", folder.id)
.await
.unwrap();
let document = cores[1].create_at_path("link/document").await.unwrap();
assert::all_ids(&cores[1], &[roots[1].id, document.id, folder.id]).await;
assert::all_paths(&cores[1], &["/", "/link/", "/link/document"]).await;
}
#[tokio::test]
async fn create_path_folder_under_link() {
let cores = [test_core_with_account().await, test_core_with_account().await];
let accounts = cores
.iter()
.map(|core| core.get_account().unwrap())
.collect::<Vec<_>>();
let roots = [cores[0].root().await.unwrap(), cores[1].root().await.unwrap()];
let folder = cores[0].create_at_path("folder/").await.unwrap();
cores[0]
.share_file(folder.id, &accounts[1].username, ShareMode::Write)
.await
.unwrap();
cores[0].sync().await.unwrap();
cores[1].sync().await.unwrap();
cores[1]
.create_link_at_path("link", folder.id)
.await
.unwrap();
let folder1 = cores[1].create_at_path("link/folder/").await.unwrap();
assert::all_ids(&cores[1], &[roots[1].id, folder1.id, folder.id]).await;
assert::all_paths(&cores[1], &["/", "/link/", "/link/folder/"]).await;
}
#[tokio::test]
async fn list_metadatas_link() {
let cores = [test_core_with_account().await, test_core_with_account().await];
let accounts = cores
.iter()
.map(|core| core.get_account().unwrap())
.collect::<Vec<_>>();
let roots = [cores[0].root().await.unwrap(), cores[1].root().await.unwrap()];
let document = cores[0].create_at_path("document").await.unwrap();
cores[0]
.share_file(document.id, &accounts[1].username, ShareMode::Write)
.await
.unwrap();
cores[0].sync().await.unwrap();
cores[1].sync().await.unwrap();
cores[1]
.create_link_at_path("link", document.id)
.await
.unwrap();
assert_valid_list_metadatas(&cores[0]).await;
assert_valid_list_metadatas(&cores[1]).await;
assert::all_ids(&cores[1], &[roots[1].id, document.id]).await;
assert::all_paths(&cores[1], &["/", "/link"]).await;
assert::all_children_ids(&cores[1], &roots[1].id, &[document.id]).await;
assert::all_recursive_children_ids(&cores[1], roots[1].id, &[roots[1].id, document.id]).await;
assert::all_recursive_children_ids(&cores[1], document.id, &[document.id]).await;
}
#[tokio::test]
async fn list_metadatas_linked_folder() {
let cores = [test_core_with_account().await, test_core_with_account().await];
let accounts = cores
.iter()
.map(|core| core.get_account().unwrap())
.collect::<Vec<_>>();
let roots = [cores[0].root().await.unwrap(), cores[1].root().await.unwrap()];
let folder = cores[0].create_at_path("folder/").await.unwrap();
let document = cores[0].create_at_path("folder/document").await.unwrap();
cores[0]
.share_file(folder.id, &accounts[1].username, ShareMode::Write)
.await
.unwrap();
cores[0].sync().await.unwrap();
cores[1].sync().await.unwrap();
let _link = cores[1]
.create_link_at_path("link", folder.id)
.await
.unwrap();
assert_valid_list_metadatas(&cores[0]).await;
assert_valid_list_metadatas(&cores[1]).await;
assert::all_ids(&cores[1], &[roots[1].id, folder.id, document.id]).await;
assert::all_paths(&cores[1], &["/", "/link/", "/link/document"]).await;
assert::all_children_ids(&cores[1], &roots[1].id, &[folder.id]).await;
assert::all_children_ids(&cores[1], &folder.id, &[document.id]).await;
assert::all_recursive_children_ids(
&cores[1],
roots[1].id,
&[roots[1].id, folder.id, document.id],
)
.await;
assert::all_recursive_children_ids(&cores[1], folder.id, &[folder.id, document.id]).await;
assert::all_recursive_children_ids(&cores[1], document.id, &[document.id]).await;
}
#[tokio::test]
async fn list_metadatas_linked_nested_folder() {
let cores = [test_core_with_account().await, test_core_with_account().await];
let accounts = cores
.iter()
.map(|core| core.get_account().unwrap())
.collect::<Vec<_>>();
let roots = [cores[0].root().await.unwrap(), cores[1].root().await.unwrap()];
let folder1 = cores[0].create_at_path("folder/").await.unwrap();
let folder2 = cores[0].create_at_path("folder/folder/").await.unwrap();
let document = cores[0]
.create_at_path("folder/folder/document")
.await
.unwrap();
cores[0]
.share_file(folder1.id, &accounts[1].username, ShareMode::Write)
.await
.unwrap();
cores[0].sync().await.unwrap();
cores[1].sync().await.unwrap();
cores[1]
.create_link_at_path("link", folder1.id)
.await
.unwrap();
assert_valid_list_metadatas(&cores[0]).await;
assert_valid_list_metadatas(&cores[1]).await;
assert::all_ids(&cores[1], &[roots[1].id, folder1.id, folder2.id, document.id]).await;
assert::all_paths(&cores[1], &["/", "/link/", "/link/folder/", "/link/folder/document"]).await;
assert::all_children_ids(&cores[1], &roots[1].id, &[folder1.id]).await;
assert::all_children_ids(&cores[1], &folder1.id, &[folder2.id]).await;
assert::all_children_ids(&cores[1], &folder2.id, &[document.id]).await;
assert::all_recursive_children_ids(
&cores[1],
roots[1].id,
&[roots[1].id, folder1.id, folder2.id, document.id],
)
.await;
assert::all_recursive_children_ids(
&cores[1],
folder1.id,
&[folder1.id, folder2.id, document.id],
)
.await;
assert::all_recursive_children_ids(&cores[1], folder2.id, &[folder2.id, document.id]).await;
assert::all_recursive_children_ids(&cores[1], document.id, &[document.id]).await;
}
#[tokio::test]
async fn list_metadatas_linked_folder_shared_from_folder() {
let cores = [test_core_with_account().await, test_core_with_account().await];
let accounts = cores
.iter()
.map(|core| core.get_account().unwrap())
.collect::<Vec<_>>();
let roots = [cores[0].root().await.unwrap(), cores[1].root().await.unwrap()];
let folder2 = cores[0].create_at_path("folder/folder/").await.unwrap();
let document = cores[0]
.create_at_path("folder/folder/document")
.await
.unwrap();
cores[0]
.share_file(folder2.id, &accounts[1].username, ShareMode::Write)
.await
.unwrap();
cores[0].sync().await.unwrap();
cores[1].sync().await.unwrap();
cores[1]
.create_link_at_path("link", folder2.id)
.await
.unwrap();
assert_valid_list_metadatas(&cores[0]).await;
assert_valid_list_metadatas(&cores[1]).await;
assert::all_ids(&cores[1], &[roots[1].id, folder2.id, document.id]).await;
assert::all_paths(&cores[1], &["/", "/link/", "/link/document"]).await;
assert::all_children_ids(&cores[1], &roots[1].id, &[folder2.id]).await;
assert::all_children_ids(&cores[1], &folder2.id, &[document.id]).await;
assert::all_recursive_children_ids(
&cores[1],
roots[1].id,
&[roots[1].id, folder2.id, document.id],
)
.await;
assert::all_recursive_children_ids(&cores[1], folder2.id, &[folder2.id, document.id]).await;
assert::all_recursive_children_ids(&cores[1], document.id, &[document.id]).await;
}
#[tokio::test]
async fn list_metadatas_folder_linked_into_folder() {
let cores = [test_core_with_account().await, test_core_with_account().await];
let accounts = cores
.iter()
.map(|core| core.get_account().unwrap())
.collect::<Vec<_>>();
let roots = [cores[0].root().await.unwrap(), cores[1].root().await.unwrap()];
let folder1 = cores[0].create_at_path("folder/").await.unwrap();
let document = cores[0].create_at_path("folder/document").await.unwrap();
cores[0]
.share_file(folder1.id, &accounts[1].username, ShareMode::Write)
.await
.unwrap();
cores[0].sync().await.unwrap();
cores[1].sync().await.unwrap();
let folder2 = cores[1].create_at_path("folder/").await.unwrap();
cores[1]
.create_link_at_path("folder/link", folder1.id)
.await
.unwrap();
assert_valid_list_metadatas(&cores[0]).await;
assert_valid_list_metadatas(&cores[1]).await;
assert::all_ids(&cores[1], &[roots[1].id, folder2.id, folder1.id, document.id]).await;
assert::all_paths(&cores[1], &["/", "/folder/", "/folder/link/", "/folder/link/document"])
.await;
assert::all_children_ids(&cores[1], &roots[1].id, &[folder2.id]).await;
assert::all_children_ids(&cores[1], &folder2.id, &[folder1.id]).await;
assert::all_children_ids(&cores[1], &folder1.id, &[document.id]).await;
assert::all_recursive_children_ids(
&cores[1],
roots[1].id,
&[roots[1].id, folder2.id, folder1.id, document.id],
)
.await;
assert::all_recursive_children_ids(
&cores[1],
folder2.id,
&[folder2.id, folder1.id, document.id],
)
.await;
assert::all_recursive_children_ids(&cores[1], folder1.id, &[folder1.id, document.id]).await;
assert::all_recursive_children_ids(&cores[1], document.id, &[document.id]).await;
}
#[tokio::test]
async fn list_metadatas_nested_linked_folders() {
let cores = [test_core_with_account().await, test_core_with_account().await];
let accounts = cores
.iter()
.map(|core| core.get_account().unwrap())
.collect::<Vec<_>>();
let roots = [cores[0].root().await.unwrap(), cores[1].root().await.unwrap()];
let folder1 = cores[0].create_at_path("folder/").await.unwrap();
let folder2 = cores[0].create_at_path("folder/folder/").await.unwrap();
let document = cores[0]
.create_at_path("folder/folder/document")
.await
.unwrap();
cores[0]
.share_file(folder1.id, &accounts[1].username, ShareMode::Write)
.await
.unwrap();
cores[0]
.share_file(folder2.id, &accounts[1].username, ShareMode::Write)
.await
.unwrap();
cores[0].sync().await.unwrap();
cores[1].sync().await.unwrap();
cores[1]
.create_link_at_path("link1", folder1.id)
.await
.unwrap();
cores[1]
.create_link_at_path("link2", folder2.id)
.await
.unwrap();
assert_valid_list_metadatas(&cores[0]).await;
assert_valid_list_metadatas(&cores[1]).await;
assert::all_ids(&cores[1], &[roots[1].id, folder1.id, folder2.id, document.id]).await;
assert::all_paths(&cores[1], &["/", "/link1/", "/link2/", "/link2/document"]).await;
assert::all_children_ids(&cores[1], &roots[1].id, &[folder1.id, folder2.id]).await;
assert::all_children_ids(&cores[1], &folder2.id, &[document.id]).await;
assert::all_recursive_children_ids(
&cores[1],
roots[1].id,
&[roots[1].id, folder1.id, folder2.id, document.id],
)
.await;
assert::all_recursive_children_ids(
&cores[1],
folder1.id,
&[folder1.id, folder2.id, document.id],
)
.await;
assert::all_recursive_children_ids(&cores[1], folder2.id, &[folder2.id, document.id]).await;
assert::all_recursive_children_ids(&cores[1], document.id, &[document.id]).await;
}
#[tokio::test]
async fn inconsistent_share_finalization() {
let cores: Vec<Lb> = vec![
test_core_with_account().await,
test_core_with_account().await,
test_core_with_account().await,
];
let accounts = cores
.iter()
.map(|core| core.get_account().unwrap())
.collect::<Vec<_>>();
let roots = [
cores[0].root().await.unwrap(),
cores[1].root().await.unwrap(),
cores[2].root().await.unwrap(),
];
let folder = cores[0].create_at_path("folder/").await.unwrap();
cores[0]
.share_file(folder.id, &accounts[1].username, ShareMode::Write)
.await
.unwrap();
cores[0]
.share_file(folder.id, &accounts[2].username, ShareMode::Write)
.await
.unwrap();
cores[0].sync().await.unwrap();
cores[1].sync().await.unwrap();
cores[2].sync().await.unwrap();
cores[1]
.create_link_at_path("link", folder.id)
.await
.unwrap();
let file_single_finalization = cores[1].get_file_by_id(folder.id).await.unwrap();
let files_all_finalization = cores[1]
.get_and_get_children_recursively(&roots[1].id)
.await
.unwrap();
let file_all_finalization: &File = files_all_finalization
.iter()
.find(|f| f.id == folder.id)
.unwrap();
assert_eq!(file_all_finalization.shares, file_single_finalization.shares);
}
#[tokio::test]
async fn link_resolving() {
let cores = [test_core_with_account().await, test_core_with_account().await];
let accounts = cores
.iter()
.map(|core| core.get_account().unwrap())
.collect::<Vec<_>>();
let folder = cores[0].create_at_path("lockbook/").await.unwrap();
let file = cores[0]
.create_file("test.md", &folder.id, FileType::Document)
.await
.unwrap();
cores[0]
.share_file(folder.id, &accounts[1].username, ShareMode::Write)
.await
.unwrap();
cores[0].sync().await.unwrap();
cores[1].sync().await.unwrap();
cores[1]
.create_link_at_path("link", folder.id)
.await
.unwrap();
assert_eq!(cores[1].get_file_by_id(file.id).await.unwrap().parent, folder.id);
}