Skip to content

Commit 6fb5b40

Browse files
committed
test: add cross-group refresh isolation regression
1 parent 250125e commit 6fb5b40

1 file changed

Lines changed: 94 additions & 0 deletions

File tree

src/lib.rs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,100 @@ mod tests {
876876
Ok(())
877877
}
878878

879+
#[actix_web::test]
880+
#[serial]
881+
async fn test_refresh_group_isolation_across_groups() -> Result<()> {
882+
let _ = env_logger::try_init();
883+
log::info!("Testing refresh isolation across groups");
884+
885+
let _path = init_test_backend("test_refresh_group_isolation").await?;
886+
887+
// Create two groups with distinct repos/files.
888+
let (group_a, repo_a, group_b, _repo_b, file_a, file_b) = {
889+
use server::get_backend;
890+
let backend = get_backend().await?;
891+
892+
let mut group_a = backend.create_group().await?;
893+
group_a.set_name("Group A").await?;
894+
let repo_a = group_a.create_repo().await?;
895+
repo_a.set_name("Repo A").await?;
896+
let file_a = "group_a_only.txt";
897+
repo_a.upload(file_a, b"alpha".to_vec()).await?;
898+
899+
let mut group_b = backend.create_group().await?;
900+
group_b.set_name("Group B").await?;
901+
let repo_b = group_b.create_repo().await?;
902+
repo_b.set_name("Repo B").await?;
903+
let file_b = "group_b_only.txt";
904+
repo_b.upload(file_b, b"beta".to_vec()).await?;
905+
906+
(group_a, repo_a, group_b, repo_b, file_a, file_b)
907+
};
908+
909+
let app = test::init_service(
910+
App::new()
911+
.service(status)
912+
.service(health)
913+
.service(web::scope("/api").service(groups::scope())),
914+
)
915+
.await;
916+
917+
// Refresh group B and verify it only reports its own files.
918+
let refresh_req = test::TestRequest::post()
919+
.uri(&format!("/api/groups/{}/refresh", group_b.id()))
920+
.to_request();
921+
let refresh_resp = test::call_service(&app, refresh_req).await;
922+
assert!(
923+
refresh_resp.status().is_success(),
924+
"Refresh should succeed for group B"
925+
);
926+
let refresh_data: serde_json::Value = test::read_body_json(refresh_resp).await;
927+
assert_eq!(refresh_data["status"], "success");
928+
929+
let repos = refresh_data["repos"].as_array().expect("repos should be an array");
930+
assert!(!repos.is_empty(), "Group B should have at least one repo");
931+
932+
// Aggregate all files reported by refresh for group B.
933+
let mut group_b_files = Vec::new();
934+
for repo_data in repos {
935+
let files = repo_data["all_files"]
936+
.as_array()
937+
.expect("all_files should be an array");
938+
for file in files {
939+
if let Some(name) = file.as_str() {
940+
group_b_files.push(name.to_string());
941+
}
942+
}
943+
}
944+
945+
assert!(
946+
group_b_files.iter().any(|f| f == file_b),
947+
"Group B refresh should include its own file"
948+
);
949+
assert!(
950+
!group_b_files.iter().any(|f| f == file_a),
951+
"Group B refresh should not include Group A file"
952+
);
953+
954+
// Sanity: group A file remains accessible in group A.
955+
let get_a_file_req = test::TestRequest::get()
956+
.uri(&format!(
957+
"/api/groups/{}/repos/{}/media/{}",
958+
group_a.id(),
959+
repo_a.id(),
960+
file_a
961+
))
962+
.to_request();
963+
let get_a_file_resp = test::call_service(&app, get_a_file_req).await;
964+
assert!(
965+
get_a_file_resp.status().is_success(),
966+
"Group A file should remain accessible in Group A"
967+
);
968+
969+
cleanup_test_resources().await?;
970+
Ok(())
971+
}
972+
879973
// P2P tests: use in-test retries (like save-dweb-backend) so nextest retries + internal
880974
// retry loops give the Veilid network time to converge.
881975
#[actix_web::test]

0 commit comments

Comments
 (0)