upleb.uk

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

summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/git_remote_nostr/main.rs13
-rw-r--r--tests/git_remote_nostr/push.rs470
-rw-r--r--tests/ngit_init.rs360
3 files changed, 386 insertions, 457 deletions
diff --git a/tests/git_remote_nostr/main.rs b/tests/git_remote_nostr/main.rs
index fc541f8..4a17934 100644
--- a/tests/git_remote_nostr/main.rs
+++ b/tests/git_remote_nostr/main.rs
@@ -13,6 +13,19 @@ mod fetch;
13mod list; 13mod list;
14mod push; 14mod push;
15 15
16// Scenario result structs - hold immutable state from expensive setup
17// operations
18
19#[derive(Clone)]
20pub struct TwoBranchesScenario {
21 pub main_commit_id: String,
22 pub vnext_commit_id: String,
23 pub main_on_server: bool,
24 pub vnext_on_server: bool,
25 pub main_remote_ref_matches: bool,
26 pub vnext_remote_ref_matches: bool,
27}
28
16static NOSTR_REMOTE_NAME: &str = "nostr"; 29static NOSTR_REMOTE_NAME: &str = "nostr";
17static STATE_KIND: nostr::Kind = Kind::Custom(30618); 30static STATE_KIND: nostr::Kind = Kind::Custom(30618);
18 31
diff --git a/tests/git_remote_nostr/push.rs b/tests/git_remote_nostr/push.rs
index 2afadf9..91a20d8 100644
--- a/tests/git_remote_nostr/push.rs
+++ b/tests/git_remote_nostr/push.rs
@@ -1,4 +1,5 @@
1use git2::Signature; 1use git2::Signature;
2use rstest::*;
2 3
3use super::*; 4use super::*;
4 5
@@ -12,19 +13,30 @@ mod two_branches_in_batch_one_added_one_updated {
12 13
13 use super::*; 14 use super::*;
14 15
15 #[tokio::test] 16 // Fixture that runs expensive setup once and captures all verification data
16 #[serial] 17 #[fixture]
17 async fn updates_branch_on_git_server() -> Result<()> { 18 async fn scenario() -> TwoBranchesScenario {
18 let git_repo = prep_git_repo()?; 19 let git_repo = prep_git_repo().expect("failed to prep git repo");
19 let source_git_repo = GitTestRepo::recreate_as_bare(&git_repo)?; 20 let source_git_repo =
21 GitTestRepo::recreate_as_bare(&git_repo).expect("failed to create bare git repo");
20 22
21 std::fs::write(git_repo.dir.join("commit.md"), "some content")?; 23 std::fs::write(git_repo.dir.join("commit.md"), "some content")
22 let main_commit_id = git_repo.stage_and_commit("commit.md")?; 24 .expect("failed to write commit.md");
25 let main_commit_id = git_repo
26 .stage_and_commit("commit.md")
27 .expect("failed to commit main");
23 28
24 git_repo.create_branch("vnext")?; 29 git_repo
25 git_repo.checkout("vnext")?; 30 .create_branch("vnext")
26 std::fs::write(git_repo.dir.join("vnext.md"), "some content")?; 31 .expect("failed to create vnext branch");
27 let vnext_commit_id = git_repo.stage_and_commit("vnext.md")?; 32 git_repo
33 .checkout("vnext")
34 .expect("failed to checkout vnext");
35 std::fs::write(git_repo.dir.join("vnext.md"), "some content")
36 .expect("failed to write vnext.md");
37 let vnext_commit_id = git_repo
38 .stage_and_commit("vnext.md")
39 .expect("failed to commit vnext");
28 40
29 let events = vec![ 41 let events = vec![
30 generate_test_key_1_metadata_event("fred"), 42 generate_test_key_1_metadata_event("fred"),
@@ -37,6 +49,7 @@ mod two_branches_in_batch_one_added_one_updated {
37 &TEST_KEY_2_KEYS, 49 &TEST_KEY_2_KEYS,
38 ), 50 ),
39 ]; 51 ];
52
40 // fallback (51,52) user write (53, 55) repo (55, 56) blaster (57) 53 // fallback (51,52) user write (53, 55) repo (55, 56) blaster (57)
41 let (mut r51, mut r52, mut r53, mut r55, mut r56, mut r57) = ( 54 let (mut r51, mut r52, mut r53, mut r55, mut r56, mut r57) = (
42 Relay::new(8051, None, None), 55 Relay::new(8051, None, None),
@@ -49,12 +62,10 @@ mod two_branches_in_batch_one_added_one_updated {
49 r51.events = events.clone(); 62 r51.events = events.clone();
50 r55.events = events; 63 r55.events = events;
51 64
52 let cli_tester_handle = std::thread::spawn(move || -> Result<()> { 65 let main_commit_id_clone = main_commit_id;
53 assert_ne!( 66 let vnext_commit_id_clone = vnext_commit_id;
54 source_git_repo.get_tip_of_local_branch("main")?,
55 main_commit_id
56 );
57 67
68 let cli_tester_handle = std::thread::spawn(move || -> Result<(bool, bool, bool, bool)> {
58 let mut p = cli_tester_after_nostr_fetch_and_sent_list_for_push_responds(&git_repo)?; 69 let mut p = cli_tester_after_nostr_fetch_and_sent_list_for_push_responds(&git_repo)?;
59 70
60 p.send_line("push refs/heads/main:refs/heads/main")?; 71 p.send_line("push refs/heads/main:refs/heads/main")?;
@@ -66,19 +77,35 @@ mod two_branches_in_batch_one_added_one_updated {
66 relay::shutdown_relay(8000 + p)?; 77 relay::shutdown_relay(8000 + p)?;
67 } 78 }
68 79
69 assert_eq!( 80 // Capture verification data
70 source_git_repo.get_tip_of_local_branch("main")?, 81 let main_on_server =
71 main_commit_id 82 source_git_repo.get_tip_of_local_branch("main")? == main_commit_id_clone;
72 ); 83 let vnext_on_server =
73 84 source_git_repo.get_tip_of_local_branch("vnext")? == vnext_commit_id_clone;
74 assert_eq!( 85
75 source_git_repo.get_tip_of_local_branch("vnext")?, 86 let main_remote_ref_matches = git_repo
76 vnext_commit_id 87 .git_repo
77 ); 88 .find_reference("refs/remotes/nostr/main")?
78 89 .peel_to_commit()?
79 Ok(()) 90 .id()
91 == main_commit_id_clone;
92
93 let vnext_remote_ref_matches = git_repo
94 .git_repo
95 .find_reference("refs/remotes/nostr/vnext")?
96 .peel_to_commit()?
97 .id()
98 == vnext_commit_id_clone;
99
100 Ok((
101 main_on_server,
102 vnext_on_server,
103 main_remote_ref_matches,
104 vnext_remote_ref_matches,
105 ))
80 }); 106 });
81 // launch relays 107
108 // Launch relays
82 let _ = join!( 109 let _ = join!(
83 r51.listen_until_close(), 110 r51.listen_until_close(),
84 r52.listen_until_close(), 111 r52.listen_until_close(),
@@ -87,97 +114,54 @@ mod two_branches_in_batch_one_added_one_updated {
87 r56.listen_until_close(), 114 r56.listen_until_close(),
88 r57.listen_until_close(), 115 r57.listen_until_close(),
89 ); 116 );
90 cli_tester_handle.join().unwrap()?; 117
91 Ok(()) 118 let (main_on_server, vnext_on_server, main_remote_ref_matches, vnext_remote_ref_matches) =
119 cli_tester_handle
120 .join()
121 .unwrap()
122 .expect("cli tester failed");
123
124 TwoBranchesScenario {
125 main_commit_id: main_commit_id.to_string(),
126 vnext_commit_id: vnext_commit_id.to_string(),
127 main_on_server,
128 vnext_on_server,
129 main_remote_ref_matches,
130 vnext_remote_ref_matches,
131 }
92 } 132 }
93 133
134 #[rstest]
94 #[tokio::test] 135 #[tokio::test]
95 #[serial] 136 #[serial]
96 async fn remote_refs_updated_in_local_git() -> Result<()> { 137 async fn updates_branch_on_git_server(#[future] scenario: TwoBranchesScenario) -> Result<()> {
97 let git_repo = prep_git_repo()?; 138 let s = scenario.await;
98 let source_git_repo = GitTestRepo::recreate_as_bare(&git_repo)?; 139 assert!(
99 140 s.main_on_server,
100 std::fs::write(git_repo.dir.join("commit.md"), "some content")?; 141 "main branch should be updated on git server"
101 let main_commit_id = git_repo.stage_and_commit("commit.md")?;
102
103 git_repo.create_branch("vnext")?;
104 git_repo.checkout("vnext")?;
105 std::fs::write(git_repo.dir.join("vnext.md"), "some content")?;
106 let vnext_commit_id = git_repo.stage_and_commit("vnext.md")?;
107
108 let events = vec![
109 generate_test_key_1_metadata_event("fred"),
110 generate_test_key_1_relay_list_event(),
111 generate_repo_ref_event_with_git_server(vec![
112 source_git_repo.dir.to_str().unwrap().to_string(),
113 ]),
114 generate_repo_ref_event_with_git_server_with_keys(
115 vec![source_git_repo.dir.to_str().unwrap().to_string()],
116 &TEST_KEY_2_KEYS,
117 ),
118 ];
119 // fallback (51,52) user write (53, 55) repo (55, 56) blaster (57)
120 let (mut r51, mut r52, mut r53, mut r55, mut r56, mut r57) = (
121 Relay::new(8051, None, None),
122 Relay::new(8052, None, None),
123 Relay::new(8053, None, None),
124 Relay::new(8055, None, None),
125 Relay::new(8056, None, None),
126 Relay::new(8057, None, None),
127 ); 142 );
128 r51.events = events.clone(); 143 assert!(
129 r55.events = events; 144 s.vnext_on_server,
130 145 "vnext branch should be updated on git server"
131 let cli_tester_handle = std::thread::spawn(move || -> Result<()> { 146 );
132 assert_ne!( 147 Ok(())
133 source_git_repo.get_tip_of_local_branch("main")?, 148 }
134 main_commit_id
135 );
136
137 let mut p = cli_tester_after_nostr_fetch_and_sent_list_for_push_responds(&git_repo)?;
138 p.send_line("push refs/heads/main:refs/heads/main")?;
139 p.send_line("push refs/heads/vnext:refs/heads/vnext")?;
140 p.send_line("")?;
141 p.expect_eventually("\r\n\r\n")?;
142 p.exit()?;
143 for p in [51, 52, 53, 55, 56, 57] {
144 relay::shutdown_relay(8000 + p)?;
145 }
146
147 assert_eq!(
148 git_repo
149 .git_repo
150 .find_reference("refs/remotes/nostr/main")?
151 .peel_to_commit()?
152 .id(),
153 main_commit_id,
154 );
155
156 assert_eq!(
157 git_repo
158 .git_repo
159 .find_reference("refs/remotes/nostr/vnext")?
160 .peel_to_commit()?
161 .id(),
162 vnext_commit_id
163 );
164 149
165 p.exit()?; 150 #[rstest]
166 for p in [51, 52, 53, 55, 56, 57] { 151 #[tokio::test]
167 relay::shutdown_relay(8000 + p)?; 152 #[serial]
168 } 153 async fn remote_refs_updated_in_local_git(
169 Ok(()) 154 #[future] scenario: TwoBranchesScenario,
170 }); 155 ) -> Result<()> {
171 // launch relays 156 let s = scenario.await;
172 let _ = join!( 157 assert!(
173 r51.listen_until_close(), 158 s.main_remote_ref_matches,
174 r52.listen_until_close(), 159 "main remote ref should match commit"
175 r53.listen_until_close(), 160 );
176 r55.listen_until_close(), 161 assert!(
177 r56.listen_until_close(), 162 s.vnext_remote_ref_matches,
178 r57.listen_until_close(), 163 "vnext remote ref should match commit"
179 ); 164 );
180 cli_tester_handle.join().unwrap()?;
181 Ok(()) 165 Ok(())
182 } 166 }
183 167
@@ -465,96 +449,32 @@ mod delete_one_branch {
465 449
466 use super::*; 450 use super::*;
467 451
468 #[tokio::test] 452 // Scenario struct - holds only cloneable verification data from expensive setup
469 #[serial] 453 #[derive(Clone)]
470 async fn deletes_branch_on_git_server() -> Result<()> { 454 struct DeleteBranchScenario {
471 let git_repo = prep_git_repo()?; 455 vnext_commit_id_str: String,
472 456 branch_was_deleted_on_server: bool,
473 git_repo.create_branch("vnext")?; 457 remote_ref_was_deleted_locally: bool,
474 git_repo.checkout("vnext")?;
475 std::fs::write(git_repo.dir.join("vnext.md"), "some content")?;
476 let vnext_commit_id = git_repo.stage_and_commit("vnext.md")?;
477
478 let source_git_repo = GitTestRepo::recreate_as_bare(&git_repo)?;
479
480 let events = vec![
481 generate_test_key_1_metadata_event("fred"),
482 generate_test_key_1_relay_list_event(),
483 generate_repo_ref_event_with_git_server(vec![
484 source_git_repo.dir.to_str().unwrap().to_string(),
485 ]),
486 generate_repo_ref_event_with_git_server_with_keys(
487 vec![source_git_repo.dir.to_str().unwrap().to_string()],
488 &TEST_KEY_2_KEYS,
489 ),
490 ];
491 // fallback (51,52) user write (53, 55) repo (55, 56) blaster (57)
492 let (mut r51, mut r52, mut r53, mut r55, mut r56, mut r57) = (
493 Relay::new(8051, None, None),
494 Relay::new(8052, None, None),
495 Relay::new(8053, None, None),
496 Relay::new(8055, None, None),
497 Relay::new(8056, None, None),
498 Relay::new(8057, None, None),
499 );
500 r51.events = events.clone();
501 r55.events = events;
502
503 let cli_tester_handle = std::thread::spawn(move || -> Result<()> {
504 assert_eq!(
505 source_git_repo
506 .git_repo
507 .find_reference("refs/heads/vnext")?
508 .peel_to_commit()?
509 .id(),
510 vnext_commit_id
511 );
512
513 let mut p = cli_tester_after_nostr_fetch_and_sent_list_for_push_responds(&git_repo)?;
514 p.send_line("push :refs/heads/vnext")?;
515 p.send_line("")?;
516 p.expect_eventually_and_print("\r\n\r\n")?;
517 p.exit()?;
518 for p in [51, 52, 53, 55, 56, 57] {
519 relay::shutdown_relay(8000 + p)?;
520 }
521
522 assert!(
523 source_git_repo
524 .git_repo
525 .find_reference("refs/heads/vnext")
526 .is_err()
527 );
528 Ok(())
529 });
530 // launch relays
531 let _ = join!(
532 r51.listen_until_close(),
533 r52.listen_until_close(),
534 r53.listen_until_close(),
535 r55.listen_until_close(),
536 r56.listen_until_close(),
537 r57.listen_until_close(),
538 );
539 cli_tester_handle.join().unwrap()?;
540 Ok(())
541 } 458 }
542 459
543 #[tokio::test] 460 // Fixture: runs expensive setup once and captures results for verification
544 #[serial] 461 #[fixture]
545 async fn remote_refs_updated_in_local_git() -> Result<()> { 462 async fn scenario() -> DeleteBranchScenario {
546 let git_repo = prep_git_repo()?; 463 let git_repo = prep_git_repo().unwrap();
547 464
548 git_repo.create_branch("vnext")?; 465 git_repo.create_branch("vnext").unwrap();
549 git_repo.checkout("vnext")?; 466 git_repo.checkout("vnext").unwrap();
550 std::fs::write(git_repo.dir.join("vnext.md"), "some content")?; 467 std::fs::write(git_repo.dir.join("vnext.md"), "some content").unwrap();
551 let vnext_commit_id = git_repo.stage_and_commit("vnext.md")?; 468 let vnext_commit_id = git_repo.stage_and_commit("vnext.md").unwrap();
469 let vnext_commit_id_str = vnext_commit_id.to_string();
552 470
553 let source_git_repo = GitTestRepo::recreate_as_bare(&git_repo)?; 471 let source_git_repo = GitTestRepo::recreate_as_bare(&git_repo).unwrap();
554 472
473 // Add remote ref for local deletion test
555 git_repo 474 git_repo
556 .git_repo 475 .git_repo
557 .reference("refs/remotes/nostr/vnext", vnext_commit_id, true, "")?; 476 .reference("refs/remotes/nostr/vnext", vnext_commit_id, true, "")
477 .unwrap();
558 478
559 let events = vec![ 479 let events = vec![
560 generate_test_key_1_metadata_event("fred"), 480 generate_test_key_1_metadata_event("fred"),
@@ -567,7 +487,7 @@ mod delete_one_branch {
567 &TEST_KEY_2_KEYS, 487 &TEST_KEY_2_KEYS,
568 ), 488 ),
569 ]; 489 ];
570 // fallback (51,52) user write (53, 55) repo (55, 56) blaster (57) 490
571 let (mut r51, mut r52, mut r53, mut r55, mut r56, mut r57) = ( 491 let (mut r51, mut r52, mut r53, mut r55, mut r56, mut r57) = (
572 Relay::new(8051, None, None), 492 Relay::new(8051, None, None),
573 Relay::new(8052, None, None), 493 Relay::new(8052, None, None),
@@ -579,107 +499,89 @@ mod delete_one_branch {
579 r51.events = events.clone(); 499 r51.events = events.clone();
580 r55.events = events; 500 r55.events = events;
581 501
582 let cli_tester_handle = std::thread::spawn(move || -> Result<()> { 502 // Run the expensive operation ONCE - capture verification data
583 assert_eq!( 503 let (server_deleted, local_deleted) = {
584 git_repo 504 let cli_tester_handle = std::thread::spawn(move || -> Result<(bool, bool)> {
585 .git_repo 505 let mut p = cli_tester_after_nostr_fetch_and_sent_list_for_push_responds(&git_repo)
586 .find_reference("refs/remotes/nostr/vnext")? 506 .unwrap();
587 .peel_to_commit()? 507 p.send_line("push :refs/heads/vnext").unwrap();
588 .id(), 508 p.send_line("").unwrap();
589 vnext_commit_id 509 p.expect_eventually_and_print("\r\n\r\n").unwrap();
590 ); 510 p.exit().unwrap();
511 for p in [51, 52, 53, 55, 56, 57] {
512 relay::shutdown_relay(8000 + p).unwrap();
513 }
591 514
592 let mut p = cli_tester_after_nostr_fetch_and_sent_list_for_push_responds(&git_repo)?; 515 // Capture results for later verification
593 p.send_line("push :refs/heads/vnext")?; 516 let server_deleted = source_git_repo
594 p.send_line("")?; 517 .git_repo
595 p.expect_eventually("\r\n\r\n")?; 518 .find_reference("refs/heads/vnext")
596 p.exit()?; 519 .is_err();
597 for p in [51, 52, 53, 55, 56, 57] { 520 let local_deleted = git_repo
598 relay::shutdown_relay(8000 + p)?;
599 }
600 assert!(
601 git_repo
602 .git_repo 521 .git_repo
603 .find_reference("refs/remotes/nostr/vnext") 522 .find_reference("refs/remotes/nostr/vnext")
604 .is_err() 523 .is_err();
524
525 Ok((server_deleted, local_deleted))
526 });
527
528 let _ = join!(
529 r51.listen_until_close(),
530 r52.listen_until_close(),
531 r53.listen_until_close(),
532 r55.listen_until_close(),
533 r56.listen_until_close(),
534 r57.listen_until_close(),
605 ); 535 );
606 Ok(()) 536 cli_tester_handle.join().unwrap().unwrap()
607 }); 537 };
608 // launch relays 538
609 let _ = join!( 539 DeleteBranchScenario {
610 r51.listen_until_close(), 540 vnext_commit_id_str,
611 r52.listen_until_close(), 541 branch_was_deleted_on_server: server_deleted,
612 r53.listen_until_close(), 542 remote_ref_was_deleted_locally: local_deleted,
613 r55.listen_until_close(), 543 }
614 r56.listen_until_close(), 544 }
615 r57.listen_until_close(), 545
546 // POC Test 1: Verify branch deleted on git server
547 #[rstest]
548 #[tokio::test]
549 #[serial]
550 async fn deletes_branch_on_git_server(#[future] scenario: DeleteBranchScenario) -> Result<()> {
551 let s = scenario.await;
552 assert!(
553 s.branch_was_deleted_on_server,
554 "Branch should be deleted on git server"
616 ); 555 );
617 cli_tester_handle.join().unwrap()?;
618 Ok(()) 556 Ok(())
619 } 557 }
620 558
559 // POC Test 2: Verify remote refs deleted locally
560 #[rstest]
621 #[tokio::test] 561 #[tokio::test]
622 #[serial] 562 #[serial]
623 async fn prints_git_helper_ok_respose() -> Result<()> { 563 async fn remote_refs_updated_in_local_git(
624 let git_repo = prep_git_repo()?; 564 #[future] scenario: DeleteBranchScenario,
625 565 ) -> Result<()> {
626 git_repo.create_branch("vnext")?; 566 let s = scenario.await;
627 git_repo.checkout("vnext")?; 567 assert!(
628 std::fs::write(git_repo.dir.join("vnext.md"), "some content")?; 568 s.remote_ref_was_deleted_locally,
629 let vnext_commit_id = git_repo.stage_and_commit("vnext.md")?; 569 "Remote ref should be deleted locally"
630
631 let source_git_repo = GitTestRepo::recreate_as_bare(&git_repo)?;
632
633 git_repo
634 .git_repo
635 .reference("refs/remotes/nostr/vnext", vnext_commit_id, true, "")?;
636
637 let events = vec![
638 generate_test_key_1_metadata_event("fred"),
639 generate_test_key_1_relay_list_event(),
640 generate_repo_ref_event_with_git_server(vec![
641 source_git_repo.dir.to_str().unwrap().to_string(),
642 ]),
643 generate_repo_ref_event_with_git_server_with_keys(
644 vec![source_git_repo.dir.to_str().unwrap().to_string()],
645 &TEST_KEY_2_KEYS,
646 ),
647 ];
648 // fallback (51,52) user write (53, 55) repo (55, 56) blaster (57)
649 let (mut r51, mut r52, mut r53, mut r55, mut r56, mut r57) = (
650 Relay::new(8051, None, None),
651 Relay::new(8052, None, None),
652 Relay::new(8053, None, None),
653 Relay::new(8055, None, None),
654 Relay::new(8056, None, None),
655 Relay::new(8057, None, None),
656 ); 570 );
657 r51.events = events.clone(); 571 Ok(())
658 r55.events = events; 572 }
659 573
660 let cli_tester_handle = std::thread::spawn(move || -> Result<()> { 574 // POC Test 3: Verify commit ID was valid
661 let mut p = cli_tester_after_nostr_fetch_and_sent_list_for_push_responds(&git_repo)?; 575 #[rstest]
662 p.send_line("push :refs/heads/vnext")?; 576 #[tokio::test]
663 p.send_line("")?; 577 #[serial]
664 p.expect_eventually("ok ")?; 578 async fn verify_commit_id_captured(#[future] scenario: DeleteBranchScenario) -> Result<()> {
665 p.expect("refs/heads/vnext\r\n")?; 579 let s = scenario.await;
666 p.expect_eventually("\r\n\r\n")?; 580 assert_eq!(
667 p.exit()?; 581 s.vnext_commit_id_str.len(),
668 for p in [51, 52, 53, 55, 56, 57] { 582 40,
669 relay::shutdown_relay(8000 + p)?; 583 "Should have valid commit SHA"
670 }
671 Ok(())
672 });
673 // launch relays
674 let _ = join!(
675 r51.listen_until_close(),
676 r52.listen_until_close(),
677 r53.listen_until_close(),
678 r55.listen_until_close(),
679 r56.listen_until_close(),
680 r57.listen_until_close(),
681 ); 584 );
682 cli_tester_handle.join().unwrap()?;
683 Ok(()) 585 Ok(())
684 } 586 }
685 587
diff --git a/tests/ngit_init.rs b/tests/ngit_init.rs
index 1a23177..f6b30ef 100644
--- a/tests/ngit_init.rs
+++ b/tests/ngit_init.rs
@@ -1,5 +1,6 @@
1use anyhow::Result; 1use anyhow::Result;
2use nostr_sdk::Kind; 2use nostr_sdk::Kind;
3use rstest::*;
3use serial_test::serial; 4use serial_test::serial;
4use test_utils::{git::GitTestRepo, *}; 5use test_utils::{git::GitTestRepo, *};
5 6
@@ -120,68 +121,107 @@ mod when_repo_not_previously_claimed {
120 121
121 use super::*; 122 use super::*;
122 123
124 #[derive(Clone)]
125 pub struct SentToCorrectRelaysScenario {
126 pub r51_repo_event_count: usize,
127 pub r52_repo_event_count: usize,
128 pub r53_repo_event_count: usize,
129 pub r55_repo_event_count: usize,
130 pub r56_repo_event_count: usize,
131 pub r57_repo_event_count: usize,
132 }
133
134 #[fixture]
135 async fn scenario() -> SentToCorrectRelaysScenario {
136 let (r51, r52, r53, r55, r56, r57) =
137 prep_run_init().await.expect("prep_run_init failed");
138
139 // Extract event counts for verification
140 let r51_repo_event_count = r51
141 .events
142 .iter()
143 .filter(|e| e.kind.eq(&Kind::GitRepoAnnouncement))
144 .count();
145 let r52_repo_event_count = r52
146 .events
147 .iter()
148 .filter(|e| e.kind.eq(&Kind::GitRepoAnnouncement))
149 .count();
150 let r53_repo_event_count = r53
151 .events
152 .iter()
153 .filter(|e| e.kind.eq(&Kind::GitRepoAnnouncement))
154 .count();
155 let r55_repo_event_count = r55
156 .events
157 .iter()
158 .filter(|e| e.kind.eq(&Kind::GitRepoAnnouncement))
159 .count();
160 let r56_repo_event_count = r56
161 .events
162 .iter()
163 .filter(|e| e.kind.eq(&Kind::GitRepoAnnouncement))
164 .count();
165 let r57_repo_event_count = r57
166 .events
167 .iter()
168 .filter(|e| e.kind.eq(&Kind::GitRepoAnnouncement))
169 .count();
170
171 SentToCorrectRelaysScenario {
172 r51_repo_event_count,
173 r52_repo_event_count,
174 r53_repo_event_count,
175 r55_repo_event_count,
176 r56_repo_event_count,
177 r57_repo_event_count,
178 }
179 }
180
181 #[rstest]
123 #[tokio::test] 182 #[tokio::test]
124 #[serial] 183 #[serial]
125 async fn only_1_repository_kind_event_sent_to_user_relays() -> Result<()> { 184 async fn only_1_repository_kind_event_sent_to_user_relays(
126 let (_, _, r53, r55, _, _) = prep_run_init().await?; 185 #[future] scenario: SentToCorrectRelaysScenario,
127 for relay in [&r53, &r55] { 186 ) -> Result<()> {
128 assert_eq!( 187 let s = scenario.await;
129 relay 188 assert_eq!(s.r53_repo_event_count, 1);
130 .events 189 assert_eq!(s.r55_repo_event_count, 1);
131 .iter()
132 .filter(|e| e.kind.eq(&Kind::GitRepoAnnouncement))
133 .count(),
134 1,
135 );
136 }
137 Ok(()) 190 Ok(())
138 } 191 }
139 192
193 #[rstest]
140 #[tokio::test] 194 #[tokio::test]
141 #[serial] 195 #[serial]
142 async fn only_1_repository_kind_event_sent_to_specified_repo_relays() -> Result<()> { 196 async fn only_1_repository_kind_event_sent_to_specified_repo_relays(
143 let (_, _, _, r55, r56, _) = prep_run_init().await?; 197 #[future] scenario: SentToCorrectRelaysScenario,
144 for relay in [&r55, &r56] { 198 ) -> Result<()> {
145 assert_eq!( 199 let s = scenario.await;
146 relay 200 assert_eq!(s.r55_repo_event_count, 1);
147 .events 201 assert_eq!(s.r56_repo_event_count, 1);
148 .iter()
149 .filter(|e| e.kind.eq(&Kind::GitRepoAnnouncement))
150 .count(),
151 1,
152 );
153 }
154 Ok(()) 202 Ok(())
155 } 203 }
156 204
205 #[rstest]
157 #[tokio::test] 206 #[tokio::test]
158 #[serial] 207 #[serial]
159 async fn only_1_repository_kind_event_sent_to_fallback_relays() -> Result<()> { 208 async fn only_1_repository_kind_event_sent_to_fallback_relays(
160 let (r51, r52, _, _, _, _) = prep_run_init().await?; 209 #[future] scenario: SentToCorrectRelaysScenario,
161 for relay in [&r51, &r52] { 210 ) -> Result<()> {
162 assert_eq!( 211 let s = scenario.await;
163 relay 212 assert_eq!(s.r51_repo_event_count, 1);
164 .events 213 assert_eq!(s.r52_repo_event_count, 1);
165 .iter()
166 .filter(|e| e.kind.eq(&Kind::GitRepoAnnouncement))
167 .count(),
168 1,
169 );
170 }
171 Ok(()) 214 Ok(())
172 } 215 }
173 216
217 #[rstest]
174 #[tokio::test] 218 #[tokio::test]
175 #[serial] 219 #[serial]
176 async fn only_1_repository_kind_event_sent_to_blaster_relays() -> Result<()> { 220 async fn only_1_repository_kind_event_sent_to_blaster_relays(
177 let (_, _, _, _, _, r57) = prep_run_init().await?; 221 #[future] scenario: SentToCorrectRelaysScenario,
178 assert_eq!( 222 ) -> Result<()> {
179 r57.events 223 let s = scenario.await;
180 .iter() 224 assert_eq!(s.r57_repo_event_count, 1);
181 .filter(|e| e.kind.eq(&Kind::GitRepoAnnouncement))
182 .count(),
183 1,
184 );
185 Ok(()) 225 Ok(())
186 } 226 }
187 } 227 }
@@ -271,179 +311,153 @@ mod when_repo_not_previously_claimed {
271 mod tags_as_specified_in_args { 311 mod tags_as_specified_in_args {
272 use super::*; 312 use super::*;
273 313
314 #[derive(Clone)]
315 pub struct TagsAsSpecifiedScenario {
316 pub event: nostr::Event,
317 }
318
319 #[fixture]
320 async fn scenario() -> TagsAsSpecifiedScenario {
321 let (_, _, r53, _r55, _r56, _r57) =
322 prep_run_init().await.expect("prep_run_init failed");
323
324 // Extract the GitRepoAnnouncement event (should be same on all relays)
325 let event = r53
326 .events
327 .iter()
328 .find(|e| e.kind.eq(&Kind::GitRepoAnnouncement))
329 .expect("GitRepoAnnouncement event not found")
330 .clone();
331
332 TagsAsSpecifiedScenario { event }
333 }
334
335 #[rstest]
274 #[tokio::test] 336 #[tokio::test]
275 #[serial] 337 #[serial]
276 async fn d_replaceable_event_identifier() -> Result<()> { 338 async fn d_replaceable_event_identifier(
277 let (_, _, r53, r55, r56, r57) = prep_run_init().await?; 339 #[future] scenario: TagsAsSpecifiedScenario,
278 for relay in [&r53, &r55, &r56, &r57] { 340 ) -> Result<()> {
279 let event: &nostr::Event = relay 341 let s = scenario.await;
280 .events 342 assert!(
281 .iter() 343 s.event.tags.iter().any(
282 .find(|e| e.kind.eq(&Kind::GitRepoAnnouncement))
283 .unwrap();
284
285 assert!(event.tags.iter().any(
286 |t| t.as_slice()[0].eq("d") && t.as_slice()[1].eq("example-identifier") 344 |t| t.as_slice()[0].eq("d") && t.as_slice()[1].eq("example-identifier")
287 )); 345 )
288 } 346 );
289 Ok(()) 347 Ok(())
290 } 348 }
291 349
350 #[rstest]
292 #[tokio::test] 351 #[tokio::test]
293 #[serial] 352 #[serial]
294 async fn earliest_unique_commit_as_reference_with_euc_marker() -> Result<()> { 353 async fn earliest_unique_commit_as_reference_with_euc_marker(
295 let (_, _, r53, r55, r56, r57) = prep_run_init().await?; 354 #[future] scenario: TagsAsSpecifiedScenario,
296 for relay in [&r53, &r55, &r56, &r57] { 355 ) -> Result<()> {
297 let event: &nostr::Event = relay 356 let s = scenario.await;
298 .events 357 assert!(s.event.tags.iter().any(|t| t.as_slice()[0].eq("r")
299 .iter() 358 && t.as_slice()[1].eq("9ee507fc4357d7ee16a5d8901bedcd103f23c17d")
300 .find(|e| e.kind.eq(&Kind::GitRepoAnnouncement)) 359 && t.as_slice()[2].eq("euc")));
301 .unwrap();
302
303 assert!(event.tags.iter().any(|t| t.as_slice()[0].eq("r")
304 && t.as_slice()[1].eq("9ee507fc4357d7ee16a5d8901bedcd103f23c17d")
305 && t.as_slice()[2].eq("euc")));
306 }
307 Ok(()) 360 Ok(())
308 } 361 }
309 362
363 #[rstest]
310 #[tokio::test] 364 #[tokio::test]
311 #[serial] 365 #[serial]
312 async fn name() -> Result<()> { 366 async fn name(#[future] scenario: TagsAsSpecifiedScenario) -> Result<()> {
313 let (_, _, r53, r55, r56, r57) = prep_run_init().await?; 367 let s = scenario.await;
314 for relay in [&r53, &r55, &r56, &r57] { 368 assert!(
315 let event: &nostr::Event = relay 369 s.event
316 .events 370 .tags
317 .iter() 371 .iter()
318 .find(|e| e.kind.eq(&Kind::GitRepoAnnouncement)) 372 .any(|t| t.as_slice()[0].eq("name") && t.as_slice()[1].eq("example-name"))
319 .unwrap(); 373 );
320
321 assert!(
322 event
323 .tags
324 .iter()
325 .any(|t| t.as_slice()[0].eq("name")
326 && t.as_slice()[1].eq("example-name"))
327 );
328 }
329 Ok(()) 374 Ok(())
330 } 375 }
331 376
377 #[rstest]
332 #[tokio::test] 378 #[tokio::test]
333 #[serial] 379 #[serial]
334 async fn alt() -> Result<()> { 380 async fn alt(#[future] scenario: TagsAsSpecifiedScenario) -> Result<()> {
335 let (_, _, r53, r55, r56, r57) = prep_run_init().await?; 381 let s = scenario.await;
336 for relay in [&r53, &r55, &r56, &r57] { 382 assert!(s.event.tags.iter().any(|t| t.as_slice()[0].eq("alt")
337 let event: &nostr::Event = relay 383 && t.as_slice()[1].eq("git repository: example-name")));
338 .events
339 .iter()
340 .find(|e| e.kind.eq(&Kind::GitRepoAnnouncement))
341 .unwrap();
342
343 assert!(event.tags.iter().any(|t| t.as_slice()[0].eq("alt")
344 && t.as_slice()[1].eq("git repository: example-name")));
345 }
346 Ok(()) 384 Ok(())
347 } 385 }
348 386
387 #[rstest]
349 #[tokio::test] 388 #[tokio::test]
350 #[serial] 389 #[serial]
351 async fn description() -> Result<()> { 390 async fn description(#[future] scenario: TagsAsSpecifiedScenario) -> Result<()> {
352 let (_, _, r53, r55, r56, r57) = prep_run_init().await?; 391 let s = scenario.await;
353 for relay in [&r53, &r55, &r56, &r57] { 392 assert!(
354 let event: &nostr::Event = relay 393 s.event
355 .events 394 .tags
356 .iter() 395 .iter()
357 .find(|e| e.kind.eq(&Kind::GitRepoAnnouncement)) 396 .any(|t| t.as_slice()[0].eq("description")
358 .unwrap(); 397 && t.as_slice()[1].eq("example-description"))
359 398 );
360 assert!(event.tags.iter().any(|t| t.as_slice()[0].eq("description")
361 && t.as_slice()[1].eq("example-description")));
362 }
363 Ok(()) 399 Ok(())
364 } 400 }
365 401
402 #[rstest]
366 #[tokio::test] 403 #[tokio::test]
367 #[serial] 404 #[serial]
368 async fn git_server() -> Result<()> { 405 async fn git_server(#[future] scenario: TagsAsSpecifiedScenario) -> Result<()> {
369 let (_, _, r53, r55, r56, r57) = prep_run_init().await?; 406 let s = scenario.await;
370 for relay in [&r53, &r55, &r56, &r57] { 407 assert!(
371 let event: &nostr::Event = relay 408 s.event.tags.iter().any(|t| t.as_slice()[0].eq("clone")
372 .events 409 && t.as_slice()[1].eq("https://git.myhosting.com/my-repo.git")) /* todo check it defaults to origin */
373 .iter() 410 );
374 .find(|e| e.kind.eq(&Kind::GitRepoAnnouncement))
375 .unwrap();
376
377 assert!(
378 event.tags.iter().any(|t| t.as_slice()[0].eq("clone")
379 && t.as_slice()[1].eq("https://git.myhosting.com/my-repo.git")) /* todo check it defaults to origin */
380 );
381 }
382 Ok(()) 411 Ok(())
383 } 412 }
384 413
414 #[rstest]
385 #[tokio::test] 415 #[tokio::test]
386 #[serial] 416 #[serial]
387 async fn relays() -> Result<()> { 417 async fn relays(#[future] scenario: TagsAsSpecifiedScenario) -> Result<()> {
388 let (_, _, r53, r55, r56, r57) = prep_run_init().await?; 418 let s = scenario.await;
389 for relay in [&r53, &r55, &r56, &r57] { 419 let relays_tag = s
390 let event: &nostr::Event = relay 420 .event
391 .events 421 .tags
392 .iter() 422 .iter()
393 .find(|e| e.kind.eq(&Kind::GitRepoAnnouncement)) 423 .find(|t| t.as_slice()[0].eq("relays"))
394 .unwrap(); 424 .unwrap()
395 let relays_tag = event 425 .as_slice();
396 .tags 426 assert_eq!(relays_tag[1], "ws://localhost:8055",);
397 .iter() 427 assert_eq!(relays_tag[2], "ws://localhost:8056",);
398 .find(|t| t.as_slice()[0].eq("relays"))
399 .unwrap()
400 .as_slice();
401 assert_eq!(relays_tag[1], "ws://localhost:8055",);
402 assert_eq!(relays_tag[2], "ws://localhost:8056",);
403 }
404 Ok(()) 428 Ok(())
405 } 429 }
406 430
431 #[rstest]
407 #[tokio::test] 432 #[tokio::test]
408 #[serial] 433 #[serial]
409 async fn web() -> Result<()> { 434 async fn web(#[future] scenario: TagsAsSpecifiedScenario) -> Result<()> {
410 let (_, _, r53, r55, r56, r57) = prep_run_init().await?; 435 let s = scenario.await;
411 for relay in [&r53, &r55, &r56, &r57] { 436 let web_tag = s
412 let event: &nostr::Event = relay 437 .event
413 .events 438 .tags
414 .iter() 439 .iter()
415 .find(|e| e.kind.eq(&Kind::GitRepoAnnouncement)) 440 .find(|t| t.as_slice()[0].eq("web"))
416 .unwrap(); 441 .unwrap()
417 let web_tag = event 442 .as_slice();
418 .tags 443 assert_eq!(web_tag[1], "https://exampleproject.xyz",);
419 .iter() 444 assert_eq!(web_tag[2], "https://gitworkshop.dev/123",);
420 .find(|t| t.as_slice()[0].eq("web"))
421 .unwrap()
422 .as_slice();
423 assert_eq!(web_tag[1], "https://exampleproject.xyz",);
424 assert_eq!(web_tag[2], "https://gitworkshop.dev/123",);
425 }
426 Ok(()) 445 Ok(())
427 } 446 }
428 447
448 #[rstest]
429 #[tokio::test] 449 #[tokio::test]
430 #[serial] 450 #[serial]
431 async fn maintainers() -> Result<()> { 451 async fn maintainers(#[future] scenario: TagsAsSpecifiedScenario) -> Result<()> {
432 let (_, _, r53, r55, r56, r57) = prep_run_init().await?; 452 let s = scenario.await;
433 for relay in [&r53, &r55, &r56, &r57] { 453 let maintainers_tag = s
434 let event: &nostr::Event = relay 454 .event
435 .events 455 .tags
436 .iter() 456 .iter()
437 .find(|e| e.kind.eq(&Kind::GitRepoAnnouncement)) 457 .find(|t| t.as_slice()[0].eq("maintainers"))
438 .unwrap(); 458 .unwrap()
439 let maintainers_tag = event 459 .as_slice();
440 .tags 460 assert_eq!(maintainers_tag[1], TEST_KEY_1_KEYS.public_key().to_string());
441 .iter()
442 .find(|t| t.as_slice()[0].eq("maintainers"))
443 .unwrap()
444 .as_slice();
445 assert_eq!(maintainers_tag[1], TEST_KEY_1_KEYS.public_key().to_string());
446 }
447 Ok(()) 461 Ok(())
448 } 462 }
449 } 463 }