upleb.uk

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

summaryrefslogtreecommitdiff
path: root/tests/ngit/init.rs
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2024-09-09 09:40:06 +0100
committerDanConwayDev <DanConwayDev@protonmail.com>2024-09-09 09:40:19 +0100
commit9a9b13a11868fe58fa0390938a39483bf1f3cc9a (patch)
tree3aa80ebfaacac233f022ebc85b6c20a7793bbc7c /tests/ngit/init.rs
parentd2d0eeb72912809a00f09fafdae4e827a34d0e26 (diff)
test: refactor into binary subdirs
in prep for splitting git_remote_nostr tests
Diffstat (limited to 'tests/ngit/init.rs')
-rw-r--r--tests/ngit/init.rs706
1 files changed, 706 insertions, 0 deletions
diff --git a/tests/ngit/init.rs b/tests/ngit/init.rs
new file mode 100644
index 0000000..c8390e3
--- /dev/null
+++ b/tests/ngit/init.rs
@@ -0,0 +1,706 @@
1use anyhow::Result;
2use nostr_sdk::Kind;
3use serial_test::serial;
4use test_utils::{git::GitTestRepo, *};
5
6fn expect_msgs_first(p: &mut CliTester) -> Result<()> {
7 p.expect("searching for profile...\r\n")?;
8 p.expect("logged in as fred\r\n")?;
9 // // p.expect("searching for existing claims on repository...\r\n")?;
10 p.expect("publishing repostory reference...\r\n")?;
11 Ok(())
12}
13
14fn expect_msgs_after(p: &mut CliTester) -> Result<()> {
15 p.expect_after_whitespace("maintainers.yaml created. commit and push.\r\n")?;
16 p.expect(
17 "this optional file helps in identifying who the maintainers are over time through the commit history\r\n",
18 )?;
19 Ok(())
20}
21
22fn get_cli_args() -> Vec<&'static str> {
23 vec![
24 "--nsec",
25 TEST_KEY_1_NSEC,
26 "--password",
27 TEST_PASSWORD,
28 "--disable-cli-spinners",
29 "init",
30 "--title",
31 "example-name",
32 "--identifier",
33 "example-identifier",
34 "--description",
35 "example-description",
36 "--web",
37 "https://exampleproject.xyz",
38 "https://gitworkshop.dev/123",
39 "--relays",
40 "ws://localhost:8055",
41 "ws://localhost:8056",
42 "--clone-url",
43 "https://git.myhosting.com/my-repo.git",
44 "--earliest-unique-commit",
45 "9ee507fc4357d7ee16a5d8901bedcd103f23c17d",
46 "--other-maintainers",
47 TEST_KEY_1_NPUB,
48 ]
49}
50
51mod when_repo_not_previously_claimed {
52 use super::*;
53
54 mod when_repo_relays_specified_as_arguments {
55 use futures::join;
56 use test_utils::relay::Relay;
57
58 use super::*;
59
60 fn prep_git_repo() -> Result<GitTestRepo> {
61 let test_repo = GitTestRepo::without_repo_in_git_config();
62 test_repo.populate()?;
63 test_repo.add_remote("origin", "https://localhost:1000")?;
64 Ok(test_repo)
65 }
66
67 fn cli_tester_init(git_repo: &GitTestRepo) -> CliTester {
68 CliTester::new_from_dir(&git_repo.dir, get_cli_args())
69 }
70
71 async fn prep_run_init() -> Result<(
72 Relay<'static>,
73 Relay<'static>,
74 Relay<'static>,
75 Relay<'static>,
76 Relay<'static>,
77 Relay<'static>,
78 )> {
79 let git_repo = prep_git_repo()?;
80 // fallback (51,52) user write (53, 55) repo (55, 56) blaster (57)
81 let (mut r51, mut r52, mut r53, mut r55, mut r56, mut r57) = (
82 Relay::new(
83 8051,
84 None,
85 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
86 relay.respond_events(
87 client_id,
88 &subscription_id,
89 &vec![
90 generate_test_key_1_metadata_event("fred"),
91 generate_test_key_1_relay_list_event(),
92 ],
93 )?;
94 Ok(())
95 }),
96 ),
97 Relay::new(8052, None, None),
98 Relay::new(8053, None, None),
99 Relay::new(8055, None, None),
100 Relay::new(8056, None, None),
101 Relay::new(8057, None, None),
102 );
103
104 // // check relay had the right number of events
105 let cli_tester_handle = std::thread::spawn(move || -> Result<()> {
106 let mut p = cli_tester_init(&git_repo);
107 p.expect_end_eventually()?;
108 for p in [51, 52, 53, 55, 56, 57] {
109 relay::shutdown_relay(8000 + p)?;
110 }
111 Ok(())
112 });
113
114 // launch relay
115 let _ = join!(
116 r51.listen_until_close(),
117 r52.listen_until_close(),
118 r53.listen_until_close(),
119 r55.listen_until_close(),
120 r56.listen_until_close(),
121 r57.listen_until_close(),
122 );
123 cli_tester_handle.join().unwrap()?;
124 Ok((r51, r52, r53, r55, r56, r57))
125 }
126
127 mod sent_to_correct_relays {
128
129 use super::*;
130
131 #[tokio::test]
132 #[serial]
133 async fn only_1_repository_kind_event_sent_to_user_relays() -> Result<()> {
134 let (_, _, r53, r55, _, _) = prep_run_init().await?;
135 for relay in [&r53, &r55] {
136 assert_eq!(
137 relay
138 .events
139 .iter()
140 .filter(|e| e.kind.eq(&Kind::GitRepoAnnouncement))
141 .count(),
142 1,
143 );
144 }
145 Ok(())
146 }
147
148 #[tokio::test]
149 #[serial]
150 async fn only_1_repository_kind_event_sent_to_specified_repo_relays() -> Result<()> {
151 let (_, _, _, r55, r56, _) = prep_run_init().await?;
152 for relay in [&r55, &r56] {
153 assert_eq!(
154 relay
155 .events
156 .iter()
157 .filter(|e| e.kind.eq(&Kind::GitRepoAnnouncement))
158 .count(),
159 1,
160 );
161 }
162 Ok(())
163 }
164
165 #[tokio::test]
166 #[serial]
167 async fn only_1_repository_kind_event_sent_to_fallback_relays() -> Result<()> {
168 let (r51, r52, _, _, _, _) = prep_run_init().await?;
169 for relay in [&r51, &r52] {
170 assert_eq!(
171 relay
172 .events
173 .iter()
174 .filter(|e| e.kind.eq(&Kind::GitRepoAnnouncement))
175 .count(),
176 1,
177 );
178 }
179 Ok(())
180 }
181
182 #[tokio::test]
183 #[serial]
184 async fn only_1_repository_kind_event_sent_to_blaster_relays() -> Result<()> {
185 let (_, _, _, _, _, r57) = prep_run_init().await?;
186 assert_eq!(
187 r57.events
188 .iter()
189 .filter(|e| e.kind.eq(&Kind::GitRepoAnnouncement))
190 .count(),
191 1,
192 );
193 Ok(())
194 }
195 }
196
197 mod yaml_file {
198 use std::{fs, io::Read};
199
200 use super::*;
201
202 async fn async_run_test() -> Result<()> {
203 let git_repo = prep_git_repo()?;
204 // fallback (51,52) user write (53, 55) repo (55, 56) blaster (57)
205 let (mut r51, mut r52, mut r53, mut r55, mut r56, mut r57) = (
206 Relay::new(
207 8051,
208 None,
209 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
210 relay.respond_events(
211 client_id,
212 &subscription_id,
213 &vec![
214 generate_test_key_1_metadata_event("fred"),
215 generate_test_key_1_relay_list_event(),
216 ],
217 )?;
218 Ok(())
219 }),
220 ),
221 Relay::new(8052, None, None),
222 Relay::new(8053, None, None),
223 Relay::new(8055, None, None),
224 Relay::new(8056, None, None),
225 Relay::new(8057, None, None),
226 );
227
228 // // check relay had the right number of events
229 let cli_tester_handle = std::thread::spawn(move || -> Result<()> {
230 let mut p = cli_tester_init(&git_repo);
231 p.expect_end_eventually()?;
232
233 let yaml_path = git_repo.dir.join("maintainers.yaml");
234
235 assert!(yaml_path.exists());
236
237 let mut file = fs::File::open(yaml_path).expect("no such file");
238 let mut file_contents = "".to_string();
239 let _ = file.read_to_string(&mut file_contents);
240
241 for p in [51, 52, 53, 55, 56, 57] {
242 relay::shutdown_relay(8000 + p)?;
243 }
244 assert_eq!(
245 file_contents,
246 format!(
247 "\
248 identifier: example-identifier\n\
249 maintainers:\n\
250 - {TEST_KEY_1_NPUB}\n\
251 relays:\n\
252 - ws://localhost:8055\n\
253 - ws://localhost:8056\n\
254 "
255 ),
256 );
257 Ok(())
258 });
259
260 // launch relay
261 let _ = join!(
262 r51.listen_until_close(),
263 r52.listen_until_close(),
264 r53.listen_until_close(),
265 r55.listen_until_close(),
266 r56.listen_until_close(),
267 r57.listen_until_close(),
268 );
269 cli_tester_handle.join().unwrap()?;
270 Ok(())
271 }
272
273 #[tokio::test]
274 #[serial]
275 async fn contains_identifier_maintainers_and_relays() -> Result<()> {
276 async_run_test().await
277 }
278 mod updates_existing_with_missing_identifier {
279 use std::io::Write;
280
281 use super::*;
282 async fn async_run_test() -> Result<()> {
283 let git_repo = prep_git_repo()?;
284 // fallback (51,52) user write (53, 55) repo (55, 56) blaster (57)
285 let (mut r51, mut r52, mut r53, mut r55, mut r56, mut r57) = (
286 Relay::new(
287 8051,
288 None,
289 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
290 relay.respond_events(
291 client_id,
292 &subscription_id,
293 &vec![
294 generate_test_key_1_metadata_event("fred"),
295 generate_test_key_1_relay_list_event(),
296 ],
297 )?;
298 Ok(())
299 }),
300 ),
301 Relay::new(8052, None, None),
302 Relay::new(8053, None, None),
303 Relay::new(8055, None, None),
304 Relay::new(8056, None, None),
305 Relay::new(8057, None, None),
306 );
307
308 // // check relay had the right number of events
309 let cli_tester_handle = std::thread::spawn(move || -> Result<()> {
310 let yaml_path = git_repo.dir.join("maintainers.yaml");
311 let mut file = std::fs::File::create(&yaml_path)
312 .expect("cannot create maintainers.yaml file");
313 write!(
314 file,
315 "\
316 maintainers:\n\
317 - {TEST_KEY_1_NPUB}\n\
318 relays:\n\
319 - ws://localhost:8055\n\
320 - ws://localhost:8056\n\
321 "
322 )?;
323
324 let mut p = cli_tester_init(&git_repo);
325 p.expect_end_eventually()?;
326
327 assert!(yaml_path.exists());
328
329 let mut file = fs::File::open(yaml_path).expect("no such file");
330 let mut file_contents = "".to_string();
331 let _ = file.read_to_string(&mut file_contents);
332
333 for p in [51, 52, 53, 55, 56, 57] {
334 relay::shutdown_relay(8000 + p)?;
335 }
336 assert_eq!(
337 file_contents,
338 format!(
339 "\
340 identifier: example-identifier\n\
341 maintainers:\n\
342 - {TEST_KEY_1_NPUB}\n\
343 relays:\n\
344 - ws://localhost:8055\n\
345 - ws://localhost:8056\n\
346 "
347 ),
348 );
349 Ok(())
350 });
351
352 // launch relay
353 let _ = join!(
354 r51.listen_until_close(),
355 r52.listen_until_close(),
356 r53.listen_until_close(),
357 r55.listen_until_close(),
358 r56.listen_until_close(),
359 r57.listen_until_close(),
360 );
361 cli_tester_handle.join().unwrap()?;
362 Ok(())
363 }
364
365 #[tokio::test]
366 #[serial]
367 async fn adds_missing_identifier() -> Result<()> {
368 async_run_test().await
369 }
370 }
371 }
372
373 mod git_config_updated {
374
375 use nostr::nips::nip01::Coordinate;
376 use nostr_sdk::ToBech32;
377
378 use super::*;
379
380 async fn async_run_test() -> Result<()> {
381 let git_repo = prep_git_repo()?;
382 // fallback (51,52) user write (53, 55) repo (55, 56) blaster (57)
383 let (mut r51, mut r52, mut r53, mut r55, mut r56, mut r57) = (
384 Relay::new(
385 8051,
386 None,
387 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
388 relay.respond_events(
389 client_id,
390 &subscription_id,
391 &vec![
392 generate_test_key_1_metadata_event("fred"),
393 generate_test_key_1_relay_list_event(),
394 ],
395 )?;
396 Ok(())
397 }),
398 ),
399 Relay::new(8052, None, None),
400 Relay::new(8053, None, None),
401 Relay::new(8055, None, None),
402 Relay::new(8056, None, None),
403 Relay::new(8057, None, None),
404 );
405
406 // // check relay had the right number of events
407 let cli_tester_handle = std::thread::spawn(move || -> Result<()> {
408 let mut p = cli_tester_init(&git_repo);
409 p.expect_end_eventually()?;
410 for p in [51, 52, 53, 55, 56, 57] {
411 relay::shutdown_relay(8000 + p)?;
412 }
413 assert_eq!(
414 git_repo
415 .git_repo
416 .config()?
417 .get_entry("nostr.repo")?
418 .value()
419 .unwrap(),
420 Coordinate {
421 kind: nostr_sdk::Kind::GitRepoAnnouncement,
422 identifier: "example-identifier".to_string(),
423 public_key: TEST_KEY_1_KEYS.public_key(),
424 relays: vec![],
425 }
426 .to_bech32()?,
427 );
428
429 Ok(())
430 });
431
432 // launch relay
433 let _ = join!(
434 r51.listen_until_close(),
435 r52.listen_until_close(),
436 r53.listen_until_close(),
437 r55.listen_until_close(),
438 r56.listen_until_close(),
439 r57.listen_until_close(),
440 );
441 cli_tester_handle.join().unwrap()?;
442 Ok(())
443 }
444
445 #[tokio::test]
446 #[serial]
447 async fn with_nostr_repo_set_to_user_and_identifer_naddr() -> Result<()> {
448 async_run_test().await?;
449 Ok(())
450 }
451 }
452
453 mod tags_as_specified_in_args {
454 use super::*;
455
456 #[tokio::test]
457 #[serial]
458 async fn d_replaceable_event_identifier() -> Result<()> {
459 let (_, _, r53, r55, r56, r57) = prep_run_init().await?;
460 for relay in [&r53, &r55, &r56, &r57] {
461 let event: &nostr::Event = relay
462 .events
463 .iter()
464 .find(|e| e.kind.eq(&Kind::GitRepoAnnouncement))
465 .unwrap();
466
467 assert!(
468 event.tags.iter().any(
469 |t| t.as_vec()[0].eq("d") && t.as_vec()[1].eq("example-identifier")
470 )
471 );
472 }
473 Ok(())
474 }
475
476 #[tokio::test]
477 #[serial]
478 async fn earliest_unique_commit_as_reference_with_euc_marker() -> Result<()> {
479 let (_, _, r53, r55, r56, r57) = prep_run_init().await?;
480 for relay in [&r53, &r55, &r56, &r57] {
481 let event: &nostr::Event = relay
482 .events
483 .iter()
484 .find(|e| e.kind.eq(&Kind::GitRepoAnnouncement))
485 .unwrap();
486
487 assert!(event.tags.iter().any(|t| t.as_vec()[0].eq("r")
488 && t.as_vec()[1].eq("9ee507fc4357d7ee16a5d8901bedcd103f23c17d")
489 && t.as_vec()[2].eq("euc")));
490 }
491 Ok(())
492 }
493
494 #[tokio::test]
495 #[serial]
496 async fn name() -> Result<()> {
497 let (_, _, r53, r55, r56, r57) = prep_run_init().await?;
498 for relay in [&r53, &r55, &r56, &r57] {
499 let event: &nostr::Event = relay
500 .events
501 .iter()
502 .find(|e| e.kind.eq(&Kind::GitRepoAnnouncement))
503 .unwrap();
504
505 assert!(
506 event
507 .tags
508 .iter()
509 .any(|t| t.as_vec()[0].eq("name") && t.as_vec()[1].eq("example-name"))
510 );
511 }
512 Ok(())
513 }
514
515 #[tokio::test]
516 #[serial]
517 async fn alt() -> Result<()> {
518 let (_, _, r53, r55, r56, r57) = prep_run_init().await?;
519 for relay in [&r53, &r55, &r56, &r57] {
520 let event: &nostr::Event = relay
521 .events
522 .iter()
523 .find(|e| e.kind.eq(&Kind::GitRepoAnnouncement))
524 .unwrap();
525
526 assert!(event.tags.iter().any(|t| t.as_vec()[0].eq("alt")
527 && t.as_vec()[1].eq("git repository: example-name")));
528 }
529 Ok(())
530 }
531
532 #[tokio::test]
533 #[serial]
534 async fn description() -> Result<()> {
535 let (_, _, r53, r55, r56, r57) = prep_run_init().await?;
536 for relay in [&r53, &r55, &r56, &r57] {
537 let event: &nostr::Event = relay
538 .events
539 .iter()
540 .find(|e| e.kind.eq(&Kind::GitRepoAnnouncement))
541 .unwrap();
542
543 assert!(event.tags.iter().any(|t| t.as_vec()[0].eq("description")
544 && t.as_vec()[1].eq("example-description")));
545 }
546 Ok(())
547 }
548
549 #[tokio::test]
550 #[serial]
551 async fn git_server() -> Result<()> {
552 let (_, _, r53, r55, r56, r57) = prep_run_init().await?;
553 for relay in [&r53, &r55, &r56, &r57] {
554 let event: &nostr::Event = relay
555 .events
556 .iter()
557 .find(|e| e.kind.eq(&Kind::GitRepoAnnouncement))
558 .unwrap();
559
560 assert!(
561 event.tags.iter().any(|t| t.as_vec()[0].eq("clone")
562 && t.as_vec()[1].eq("https://git.myhosting.com/my-repo.git")) /* todo check it defaults to origin */
563 );
564 }
565 Ok(())
566 }
567
568 #[tokio::test]
569 #[serial]
570 async fn relays() -> Result<()> {
571 let (_, _, r53, r55, r56, r57) = prep_run_init().await?;
572 for relay in [&r53, &r55, &r56, &r57] {
573 let event: &nostr::Event = relay
574 .events
575 .iter()
576 .find(|e| e.kind.eq(&Kind::GitRepoAnnouncement))
577 .unwrap();
578 let relays_tag = event
579 .tags
580 .iter()
581 .find(|t| t.as_vec()[0].eq("relays"))
582 .unwrap()
583 .as_vec();
584 assert_eq!(relays_tag[1], "ws://localhost:8055",);
585 assert_eq!(relays_tag[2], "ws://localhost:8056",);
586 }
587 Ok(())
588 }
589
590 #[tokio::test]
591 #[serial]
592 async fn web() -> Result<()> {
593 let (_, _, r53, r55, r56, r57) = prep_run_init().await?;
594 for relay in [&r53, &r55, &r56, &r57] {
595 let event: &nostr::Event = relay
596 .events
597 .iter()
598 .find(|e| e.kind.eq(&Kind::GitRepoAnnouncement))
599 .unwrap();
600 let web_tag = event
601 .tags
602 .iter()
603 .find(|t| t.as_vec()[0].eq("web"))
604 .unwrap()
605 .as_vec();
606 assert_eq!(web_tag[1], "https://exampleproject.xyz",);
607 assert_eq!(web_tag[2], "https://gitworkshop.dev/123",);
608 }
609 Ok(())
610 }
611
612 #[tokio::test]
613 #[serial]
614 async fn maintainers() -> Result<()> {
615 let (_, _, r53, r55, r56, r57) = prep_run_init().await?;
616 for relay in [&r53, &r55, &r56, &r57] {
617 let event: &nostr::Event = relay
618 .events
619 .iter()
620 .find(|e| e.kind.eq(&Kind::GitRepoAnnouncement))
621 .unwrap();
622 let maintainers_tag = event
623 .tags
624 .iter()
625 .find(|t| t.as_vec()[0].eq("maintainers"))
626 .unwrap()
627 .as_vec();
628 assert_eq!(maintainers_tag[1], TEST_KEY_1_KEYS.public_key().to_string());
629 }
630 Ok(())
631 }
632 }
633
634 mod cli_ouput {
635 use super::*;
636
637 #[tokio::test]
638 #[serial]
639 async fn check_cli_output() -> Result<()> {
640 let git_repo = prep_git_repo()?;
641
642 // fallback (51,52) user write (53, 55) repo (55, 56) blaster (57)
643 let (mut r51, mut r52, mut r53, mut r55, mut r56, mut r57) = (
644 Relay::new(
645 8051,
646 None,
647 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
648 relay.respond_events(
649 client_id,
650 &subscription_id,
651 &vec![
652 generate_test_key_1_metadata_event("fred"),
653 generate_test_key_1_relay_list_event(),
654 ],
655 )?;
656 Ok(())
657 }),
658 ),
659 Relay::new(8052, None, None),
660 Relay::new(8053, None, None),
661 Relay::new(8055, None, None),
662 Relay::new(8056, None, None),
663 Relay::new(8057, None, None),
664 );
665
666 // // check relay had the right number of events
667 let cli_tester_handle = std::thread::spawn(move || -> Result<()> {
668 let mut p = cli_tester_init(&git_repo);
669 expect_msgs_first(&mut p)?;
670 relay::expect_send_with_progress(
671 &mut p,
672 vec![
673 (" [my-relay] [repo-relay] ws://localhost:8055", true, ""),
674 (" [my-relay] ws://localhost:8053", true, ""),
675 (" [repo-relay] ws://localhost:8056", true, ""),
676 (" [default] ws://localhost:8051", true, ""),
677 (" [default] ws://localhost:8052", true, ""),
678 (" [default] ws://localhost:8057", true, ""),
679 ],
680 1,
681 )?;
682 expect_msgs_after(&mut p)?;
683 p.expect_end()?;
684 for p in [51, 52, 53, 55, 56, 57] {
685 relay::shutdown_relay(8000 + p)?;
686 }
687 Ok(())
688 });
689
690 // launch relay
691 let _ = join!(
692 r51.listen_until_close(),
693 r52.listen_until_close(),
694 r53.listen_until_close(),
695 r55.listen_until_close(),
696 r56.listen_until_close(),
697 r57.listen_until_close(),
698 );
699 cli_tester_handle.join().unwrap()?;
700 Ok(())
701 }
702 }
703 }
704 // TODO: cli caputuring input
705}
706// TODO: when_updating_existing_repoistory correct defaults are used