upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2024-12-13 12:02:15 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2024-12-13 12:37:22 +0000
commitee0e048ed9c244449ffb12284e444933eb67e118 (patch)
tree7447813026f9ef834ccae1e3cb3de4735f3a7f02
parentf294a249307accc0f173917989ce27c27f0c6792 (diff)
test(push): merge event for applied commits
publish a merge event when the commit author signature and timestamp match patches within an open proposal
-rw-r--r--test_utils/src/lib.rs13
-rw-r--r--tests/git_remote_nostr/push.rs175
2 files changed, 179 insertions, 9 deletions
diff --git a/test_utils/src/lib.rs b/test_utils/src/lib.rs
index 3ac171b..5079c26 100644
--- a/test_utils/src/lib.rs
+++ b/test_utils/src/lib.rs
@@ -1212,9 +1212,9 @@ pub fn cli_tester_create_proposals() -> Result<GitTestRepo> {
1212pub fn cli_tester_create_proposal_branches_ready_to_send() -> Result<GitTestRepo> { 1212pub fn cli_tester_create_proposal_branches_ready_to_send() -> Result<GitTestRepo> {
1213 let git_repo = GitTestRepo::default(); 1213 let git_repo = GitTestRepo::default();
1214 git_repo.populate()?; 1214 git_repo.populate()?;
1215 create_and_populate_branch(&git_repo, FEATURE_BRANCH_NAME_1, "a", false)?; 1215 create_and_populate_branch(&git_repo, FEATURE_BRANCH_NAME_1, "a", false, None)?;
1216 create_and_populate_branch(&git_repo, FEATURE_BRANCH_NAME_2, "b", false)?; 1216 create_and_populate_branch(&git_repo, FEATURE_BRANCH_NAME_2, "b", false, None)?;
1217 create_and_populate_branch(&git_repo, FEATURE_BRANCH_NAME_3, "c", false)?; 1217 create_and_populate_branch(&git_repo, FEATURE_BRANCH_NAME_3, "c", false, None)?;
1218 Ok(git_repo) 1218 Ok(git_repo)
1219} 1219}
1220 1220
@@ -1223,6 +1223,7 @@ pub fn create_and_populate_branch(
1223 branch_name: &str, 1223 branch_name: &str,
1224 prefix: &str, 1224 prefix: &str,
1225 only_one_commit: bool, 1225 only_one_commit: bool,
1226 commiter: Option<&Signature>,
1226) -> Result<()> { 1227) -> Result<()> {
1227 test_repo.checkout("main")?; 1228 test_repo.checkout("main")?;
1228 test_repo.create_branch(branch_name)?; 1229 test_repo.create_branch(branch_name)?;
@@ -1239,7 +1240,7 @@ pub fn create_and_populate_branch(
1239 ) 1240 )
1240 .unwrap(), 1241 .unwrap(),
1241 ), 1242 ),
1242 None, 1243 commiter,
1243 )?; 1244 )?;
1244 if !only_one_commit { 1245 if !only_one_commit {
1245 let file_name = format!("{}4.md", prefix); 1246 let file_name = format!("{}4.md", prefix);
@@ -1254,7 +1255,7 @@ pub fn create_and_populate_branch(
1254 ) 1255 )
1255 .unwrap(), 1256 .unwrap(),
1256 ), 1257 ),
1257 None, 1258 commiter,
1258 )?; 1259 )?;
1259 } 1260 }
1260 Ok(()) 1261 Ok(())
@@ -1292,7 +1293,7 @@ pub fn cli_tester_create_proposal(
1292 cover_letter_title_and_description: Option<(&str, &str)>, 1293 cover_letter_title_and_description: Option<(&str, &str)>,
1293 in_reply_to: Option<String>, 1294 in_reply_to: Option<String>,
1294) -> Result<()> { 1295) -> Result<()> {
1295 create_and_populate_branch(test_repo, branch_name, prefix, false)?; 1296 create_and_populate_branch(test_repo, branch_name, prefix, false, None)?;
1296 std::thread::sleep(std::time::Duration::from_millis(1000)); 1297 std::thread::sleep(std::time::Duration::from_millis(1000));
1297 if let Some(in_reply_to) = in_reply_to { 1298 if let Some(in_reply_to) = in_reply_to {
1298 let mut p = CliTester::new_from_dir( 1299 let mut p = CliTester::new_from_dir(
diff --git a/tests/git_remote_nostr/push.rs b/tests/git_remote_nostr/push.rs
index a8ea0ac..30602c9 100644
--- a/tests/git_remote_nostr/push.rs
+++ b/tests/git_remote_nostr/push.rs
@@ -1,3 +1,5 @@
1use git2::Signature;
2
1use super::*; 3use super::*;
2 4
3#[tokio::test] 5#[tokio::test]
@@ -1159,9 +1161,6 @@ async fn proposal_fast_forward_merge_commits_pushed_to_main_leads_to_status_even
1159 .iter() 1161 .iter()
1160 .find(|e| e.kind.eq(&Kind::GitStatusApplied)) 1162 .find(|e| e.kind.eq(&Kind::GitStatusApplied))
1161 .unwrap(); 1163 .unwrap();
1162 // println!("{:?}", proposal_cover_letter_event);
1163 // println!("merge status");
1164 // println!("{:?}", merge_status);
1165 1164
1166 let patch_commit_ids_parents_first = proposal_patches 1165 let patch_commit_ids_parents_first = proposal_patches
1167 .iter() 1166 .iter()
@@ -1235,6 +1234,176 @@ async fn proposal_fast_forward_merge_commits_pushed_to_main_leads_to_status_even
1235 1234
1236#[tokio::test] 1235#[tokio::test]
1237#[serial] 1236#[serial]
1237async fn proposal_commits_applied_and_pushed_to_main_leads_to_status_event_issued() -> Result<()> {
1238 //
1239 let (events, source_git_repo) = prep_source_repo_and_events_including_proposals().await?;
1240 let source_path = source_git_repo.dir.to_str().unwrap().to_string();
1241 let (mut r51, mut r52, mut r53, mut r55, mut r56, mut r57) = (
1242 Relay::new(8051, None, None),
1243 Relay::new(8052, None, None),
1244 Relay::new(8053, None, None),
1245 Relay::new(8055, None, None),
1246 Relay::new(8056, None, None),
1247 Relay::new(8057, None, None),
1248 );
1249 r51.events = events.clone();
1250 r55.events = events.clone();
1251
1252 #[allow(clippy::mutable_key_type)]
1253 let before = r55.events.iter().cloned().collect::<HashSet<Event>>();
1254
1255 let cli_tester_handle = std::thread::spawn(move || -> Result<(String, Oid, Oid)> {
1256 let branch_name = get_proposal_branch_name_from_events(&events, FEATURE_BRANCH_NAME_1)?;
1257
1258 let git_repo = clone_git_repo_with_nostr_url()?;
1259 create_and_populate_branch(
1260 &git_repo,
1261 "tmptmp",
1262 "a",
1263 false,
1264 Some(&Signature::now("Different User", "other.user@nostr.com")?),
1265 )?;
1266 let applied_proposal_tip = git_repo.get_tip_of_local_branch("tmptmp")?;
1267
1268 git_repo.git_repo.branch(
1269 "main",
1270 &git_repo.git_repo.find_commit(applied_proposal_tip)?,
1271 true,
1272 )?;
1273 let main_oid = git_repo.checkout("refs/heads/main")?;
1274 assert_eq!(applied_proposal_tip, main_oid);
1275
1276 let mut p = CliTester::new_git_with_remote_helper_from_dir(&git_repo.dir, ["push"]);
1277 cli_expect_nostr_fetch(&mut p)?;
1278 p.expect(format!("fetching {} ref list over filesystem...\r\n", source_path).as_str())?;
1279 p.expect("list: connecting...\r\n")?;
1280 p.expect_eventually(format!(
1281 "applied commits from proposal: create nostr proposal status event for {branch_name}\r\n" ))?;
1282 // status updates printed here
1283 p.expect_eventually(format!("To {}\r\n", get_nostr_remote_url()?).as_str())?;
1284 let output = p.expect_end_eventually()?;
1285
1286 for p in [51, 52, 53, 55, 56, 57] {
1287 relay::shutdown_relay(8000 + p)?;
1288 }
1289
1290 let first_applied_commit_oid = git_repo
1291 .git_repo
1292 .find_commit(applied_proposal_tip)?
1293 .parent(0)?
1294 .id();
1295 Ok((output, first_applied_commit_oid, applied_proposal_tip))
1296 });
1297 // launch relays
1298 let _ = join!(
1299 r51.listen_until_close(),
1300 r52.listen_until_close(),
1301 r53.listen_until_close(),
1302 r55.listen_until_close(),
1303 r56.listen_until_close(),
1304 r57.listen_until_close(),
1305 );
1306
1307 let (output, first_oid, tip_oid) = cli_tester_handle.join().unwrap()?;
1308
1309 assert_eq!(
1310 output,
1311 format!(
1312 " 431b84e..{} main -> main\r\n",
1313 &tip_oid.to_string()[..7]
1314 )
1315 );
1316
1317 let new_events = r55
1318 .events
1319 .iter()
1320 .cloned()
1321 .collect::<HashSet<Event>>()
1322 .difference(&before)
1323 .cloned()
1324 .collect::<Vec<Event>>();
1325
1326 assert_eq!(new_events.len(), 2, "{new_events:?}");
1327
1328 let proposal_cover_letter_event = r55
1329 .events
1330 .iter()
1331 .find(|e| {
1332 e.tags
1333 .iter()
1334 .find(|t| t.as_slice()[0].eq("branch-name"))
1335 .is_some_and(|t| t.as_slice()[1].eq(FEATURE_BRANCH_NAME_1))
1336 })
1337 .unwrap();
1338
1339 let proposal_patches: Vec<&Event> = r55
1340 .events
1341 .iter()
1342 .filter(|e| {
1343 e.kind == Kind::GitPatch
1344 && e.tags
1345 .iter()
1346 .any(|t| t.as_slice()[1].eq(&proposal_cover_letter_event.id.to_string()))
1347 })
1348 .collect();
1349
1350 let merge_status = new_events
1351 .iter()
1352 .find(|e| e.kind.eq(&Kind::GitStatusApplied))
1353 .unwrap();
1354
1355 assert_eq!(
1356 HashSet::<String>::from_iter(vec![
1357 "applied-as-commits".to_string(),
1358 first_oid.to_string(),
1359 tip_oid.to_string(),
1360 ]),
1361 HashSet::<String>::from_iter(
1362 merge_status
1363 .tags
1364 .iter()
1365 .find(|t| t.as_slice()[0].eq("applied-as-commits"))
1366 .unwrap()
1367 .clone()
1368 .to_vec()
1369 .iter()
1370 .cloned(),
1371 ),
1372 "status sets correct applied-as-commits tag {merge_status:?}"
1373 );
1374
1375 for patch_id in proposal_patches
1376 .iter()
1377 .map(|e| e.id.to_string())
1378 .collect::<Vec<String>>()
1379 {
1380 assert!(
1381 merge_status.tags.iter().any(|t| t.as_slice().len().eq(&4)
1382 && t.as_slice()[1] == patch_id
1383 && t.as_slice()[3].eq("mention")),
1384 "merge status doesnt mention proposal patch {patch_id} \r\nmerge status:\r\n{}",
1385 merge_status.as_json(),
1386 );
1387 }
1388
1389 assert_eq!(
1390 proposal_cover_letter_event.id.to_string(),
1391 merge_status
1392 .tags
1393 .iter()
1394 .find(|t| t.is_root())
1395 .unwrap()
1396 .as_slice()[1],
1397 "status tags proposal id as root \r\nmerge status:\r\n{}\r\nproposal:\r\n{}",
1398 merge_status.as_json(),
1399 proposal_cover_letter_event.as_json(),
1400 );
1401
1402 Ok(())
1403}
1404
1405#[tokio::test]
1406#[serial]
1238async fn push_2_commits_to_existing_proposal() -> Result<()> { 1407async fn push_2_commits_to_existing_proposal() -> Result<()> {
1239 let (events, source_git_repo) = prep_source_repo_and_events_including_proposals().await?; 1408 let (events, source_git_repo) = prep_source_repo_and_events_including_proposals().await?;
1240 let source_path = source_git_repo.dir.to_str().unwrap().to_string(); 1409 let source_path = source_git_repo.dir.to_str().unwrap().to_string();