upleb.uk

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

summaryrefslogtreecommitdiff
path: root/tests/ngit/list.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/list.rs
parentd2d0eeb72912809a00f09fafdae4e827a34d0e26 (diff)
test: refactor into binary subdirs
in prep for splitting git_remote_nostr tests
Diffstat (limited to 'tests/ngit/list.rs')
-rw-r--r--tests/ngit/list.rs1549
1 files changed, 1549 insertions, 0 deletions
diff --git a/tests/ngit/list.rs b/tests/ngit/list.rs
new file mode 100644
index 0000000..c145fa4
--- /dev/null
+++ b/tests/ngit/list.rs
@@ -0,0 +1,1549 @@
1use anyhow::Result;
2use futures::join;
3use serial_test::serial;
4use test_utils::{git::GitTestRepo, relay::Relay, *};
5
6async fn prep_proposals_repo_and_repo_with_proposal_pulled_and_checkedout(
7 proposal_number: u16,
8) -> Result<(GitTestRepo, GitTestRepo)> {
9 // fallback (51,52) user write (53, 55) repo (55, 56)
10 let (mut r51, mut r52, mut r53, mut r55, mut r56) = (
11 Relay::new(8051, None, None),
12 Relay::new(8052, None, None),
13 Relay::new(8053, None, None),
14 Relay::new(8055, None, None),
15 Relay::new(8056, None, None),
16 );
17
18 r51.events.push(generate_test_key_1_relay_list_event());
19 r51.events.push(generate_test_key_1_metadata_event("fred"));
20 r51.events.push(generate_repo_ref_event());
21
22 r55.events.push(generate_repo_ref_event());
23 r55.events.push(generate_test_key_1_metadata_event("fred"));
24 r55.events.push(generate_test_key_1_relay_list_event());
25
26 let cli_tester_handle = std::thread::spawn(move || -> Result<(GitTestRepo, GitTestRepo)> {
27 let (originating_repo, test_repo) =
28 create_proposals_and_repo_with_proposal_pulled_and_checkedout(proposal_number)?;
29
30 for p in [51, 52, 53, 55, 56] {
31 relay::shutdown_relay(8000 + p)?;
32 }
33 Ok((originating_repo, test_repo))
34 });
35
36 // launch relay
37 let _ = join!(
38 r51.listen_until_close(),
39 r52.listen_until_close(),
40 r53.listen_until_close(),
41 r55.listen_until_close(),
42 r56.listen_until_close(),
43 );
44 let res = cli_tester_handle.join().unwrap()?;
45
46 Ok(res)
47}
48
49mod cannot_find_repo_event {
50 use super::*;
51 mod cli_prompts {
52 use nostr::{nips::nip01::Coordinate, ToBech32};
53
54 use super::*;
55 async fn run_async_repo_event_ref_needed(invalid_input: bool, naddr: bool) -> Result<()> {
56 let (mut r51, mut r52, mut r53, mut r55, mut r56) = (
57 Relay::new(8051, None, None),
58 Relay::new(8052, None, None),
59 Relay::new(8053, None, None),
60 Relay::new(8055, None, None),
61 Relay::new(8056, None, None),
62 );
63
64 r51.events.push(generate_test_key_1_relay_list_event());
65 r51.events.push(generate_test_key_1_metadata_event("fred"));
66
67 r55.events.push(generate_test_key_1_relay_list_event());
68 r55.events.push(generate_test_key_1_metadata_event("fred"));
69
70 let repo_event = generate_repo_ref_event();
71 r56.events.push(repo_event.clone());
72
73 let cli_tester_handle = std::thread::spawn(move || -> Result<()> {
74 let test_repo = GitTestRepo::without_repo_in_git_config();
75 test_repo.populate()?;
76 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
77 p.expect(
78 "hint: https://gitworkshop.dev/repos lists repositories and their naddr\r\n",
79 )?;
80 if invalid_input {
81 let mut input = p.expect_input("repository naddr")?;
82 input.succeeds_with("dfgvfvfzadvd")?;
83 p.expect("not a valid naddr\r\n")?;
84 let _ = p.expect_input("repository naddr")?;
85 p.exit()?;
86 }
87 if naddr {
88 let mut input = p.expect_input("repository naddr")?;
89 input.succeeds_with(
90 &Coordinate {
91 kind: nostr::Kind::GitRepoAnnouncement,
92 public_key: TEST_KEY_1_KEYS.public_key(),
93 identifier: repo_event.identifier().unwrap().to_string(),
94 relays: vec!["ws://localhost:8056".to_string()],
95 }
96 .to_bech32()?,
97 )?;
98 p.expect("fetching updates...\r\n")?;
99 p.expect_eventually("\r\n")?; // some updates listed here
100 p.expect_end_with("no proposals found... create one? try `ngit send`\r\n")?;
101 }
102
103 for p in [51, 52, 53, 55, 56] {
104 relay::shutdown_relay(8000 + p)?;
105 }
106 Ok(())
107 });
108
109 // launch relay
110 let _ = join!(
111 r51.listen_until_close(),
112 r52.listen_until_close(),
113 r53.listen_until_close(),
114 r55.listen_until_close(),
115 r56.listen_until_close(),
116 );
117 cli_tester_handle.join().unwrap()?;
118 Ok(())
119 }
120
121 #[tokio::test]
122 #[serial]
123 async fn warns_not_valid_input_and_asks_again() -> Result<()> {
124 run_async_repo_event_ref_needed(true, false).await
125 }
126
127 #[tokio::test]
128 #[serial]
129 async fn finds_based_on_naddr_on_embeded_relay() -> Result<()> {
130 run_async_repo_event_ref_needed(false, true).await
131 }
132 }
133}
134mod when_main_branch_is_uptodate {
135 use super::*;
136
137 mod when_proposal_branch_doesnt_exist {
138 use super::*;
139
140 mod when_main_is_checked_out {
141 use super::*;
142
143 mod when_first_proposal_selected {
144 use super::*;
145
146 // TODO: test when other proposals with the same name but from other
147 // repositories are present on relays
148
149 mod cli_prompts {
150 use super::*;
151 #[tokio::test]
152 #[serial]
153 async fn prompts_to_choose_from_proposal_titles() -> Result<()> {
154 let (mut r51, mut r52, mut r53, mut r55, mut r56) = (
155 Relay::new(8051, None, None),
156 Relay::new(8052, None, None),
157 Relay::new(8053, None, None),
158 Relay::new(8055, None, None),
159 Relay::new(8056, None, None),
160 );
161
162 r51.events.push(generate_test_key_1_relay_list_event());
163 r51.events.push(generate_test_key_1_metadata_event("fred"));
164 r51.events.push(generate_repo_ref_event());
165
166 r55.events.push(generate_repo_ref_event());
167 r55.events.push(generate_test_key_1_metadata_event("fred"));
168 r55.events.push(generate_test_key_1_relay_list_event());
169
170 let cli_tester_handle = std::thread::spawn(move || -> Result<()> {
171 cli_tester_create_proposals()?;
172
173 let test_repo = GitTestRepo::default();
174 test_repo.populate()?;
175 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
176
177 p.expect("fetching updates...\r\n")?;
178 p.expect_eventually("\r\n")?; // some updates listed here
179 let mut c = p.expect_choice(
180 "all proposals",
181 vec![
182 format!("\"{PROPOSAL_TITLE_3}\""),
183 format!("\"{PROPOSAL_TITLE_2}\""),
184 format!("\"{PROPOSAL_TITLE_1}\""),
185 ],
186 )?;
187 c.succeeds_with(2, true, None)?;
188 let mut c = p.expect_choice(
189 "",
190 vec![
191 format!(
192 "create and checkout proposal branch (2 ahead 0 behind 'main')" ),
193 format!("apply to current branch with `git am`"),
194 format!("download to ./patches"),
195 format!("back"),
196 ],
197 )?;
198 c.succeeds_with(0, false, None)?;
199 p.expect(&format!(
200 "checked out proposal as 'pr/{}(",
201 FEATURE_BRANCH_NAME_1,
202 ))?;
203 p.expect_end_eventually_with(")' branch\r\n")?;
204
205 for p in [51, 52, 53, 55, 56] {
206 relay::shutdown_relay(8000 + p)?;
207 }
208 Ok(())
209 });
210
211 // launch relay
212 let _ = join!(
213 r51.listen_until_close(),
214 r52.listen_until_close(),
215 r53.listen_until_close(),
216 r55.listen_until_close(),
217 r56.listen_until_close(),
218 );
219 cli_tester_handle.join().unwrap()?;
220 println!("{:?}", r55.events);
221 Ok(())
222 }
223 }
224
225 #[tokio::test]
226 #[serial]
227 async fn proposal_branch_created_with_correct_name() -> Result<()> {
228 let (_, test_repo) =
229 prep_proposals_repo_and_repo_with_proposal_pulled_and_checkedout(1).await?;
230 assert_eq!(
231 vec![
232 "main",
233 &get_proposal_branch_name(&test_repo, FEATURE_BRANCH_NAME_1)?,
234 ],
235 test_repo.get_local_branch_names()?
236 );
237 Ok(())
238 }
239
240 #[tokio::test]
241 #[serial]
242 async fn proposal_branch_checked_out() -> Result<()> {
243 let (_, test_repo) =
244 prep_proposals_repo_and_repo_with_proposal_pulled_and_checkedout(1).await?;
245 assert_eq!(
246 get_proposal_branch_name(&test_repo, FEATURE_BRANCH_NAME_1)?,
247 test_repo.get_checked_out_branch_name()?,
248 );
249 Ok(())
250 }
251
252 #[tokio::test]
253 #[serial]
254 async fn proposal_branch_tip_is_most_recent_patch() -> Result<()> {
255 let (originating_repo, test_repo) =
256 prep_proposals_repo_and_repo_with_proposal_pulled_and_checkedout(1).await?;
257 assert_eq!(
258 originating_repo.get_tip_of_local_branch(FEATURE_BRANCH_NAME_1)?,
259 test_repo.get_tip_of_local_branch(&get_proposal_branch_name(
260 &test_repo,
261 FEATURE_BRANCH_NAME_1
262 )?)?,
263 );
264 Ok(())
265 }
266 }
267 mod when_third_proposal_selected {
268 use super::*;
269
270 mod cli_prompts {
271 use super::*;
272
273 #[tokio::test]
274 #[serial]
275 async fn prompts_to_choose_from_proposal_titles() -> Result<()> {
276 let (mut r51, mut r52, mut r53, mut r55, mut r56) = (
277 Relay::new(8051, None, None),
278 Relay::new(8052, None, None),
279 Relay::new(8053, None, None),
280 Relay::new(8055, None, None),
281 Relay::new(8056, None, None),
282 );
283
284 r51.events.push(generate_test_key_1_relay_list_event());
285 r51.events.push(generate_test_key_1_metadata_event("fred"));
286 r51.events.push(generate_repo_ref_event());
287
288 r55.events.push(generate_repo_ref_event());
289 r55.events.push(generate_test_key_1_metadata_event("fred"));
290 r55.events.push(generate_test_key_1_relay_list_event());
291
292 let cli_tester_handle = std::thread::spawn(move || -> Result<()> {
293 cli_tester_create_proposals()?;
294
295 let test_repo = GitTestRepo::default();
296 test_repo.populate()?;
297 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
298
299 p.expect("fetching updates...\r\n")?;
300 p.expect_eventually("\r\n")?; // some updates listed here
301 let mut c = p.expect_choice(
302 "all proposals",
303 vec![
304 format!("\"{PROPOSAL_TITLE_3}\""),
305 format!("\"{PROPOSAL_TITLE_2}\""),
306 format!("\"{PROPOSAL_TITLE_1}\""),
307 ],
308 )?;
309 c.succeeds_with(0, true, None)?;
310 let mut c = p.expect_choice(
311 "",
312 vec![
313 format!(
314 "create and checkout proposal branch (2 ahead 0 behind 'main')" ),
315 format!("apply to current branch with `git am`"),
316 format!("download to ./patches"),
317 format!("back"),
318 ],
319 )?;
320 c.succeeds_with(0, false, Some(0))?;
321 p.expect(&format!(
322 "checked out proposal as 'pr/{}(",
323 FEATURE_BRANCH_NAME_3,
324 ))?;
325 p.expect_end_eventually_with(")' branch\r\n")?;
326
327 for p in [51, 52, 53, 55, 56] {
328 relay::shutdown_relay(8000 + p)?;
329 }
330 Ok(())
331 });
332
333 // launch relay
334 let _ = join!(
335 r51.listen_until_close(),
336 r52.listen_until_close(),
337 r53.listen_until_close(),
338 r55.listen_until_close(),
339 r56.listen_until_close(),
340 );
341 cli_tester_handle.join().unwrap()?;
342 println!("{:?}", r55.events);
343 Ok(())
344 }
345 }
346
347 #[tokio::test]
348 #[serial]
349 async fn proposal_branch_created_with_correct_name() -> Result<()> {
350 let (_, test_repo) =
351 prep_proposals_repo_and_repo_with_proposal_pulled_and_checkedout(3).await?;
352 assert_eq!(
353 vec![
354 "main",
355 &get_proposal_branch_name(&test_repo, FEATURE_BRANCH_NAME_3)?,
356 ],
357 test_repo.get_local_branch_names()?
358 );
359 Ok(())
360 }
361
362 #[tokio::test]
363 #[serial]
364 async fn proposal_branch_checked_out() -> Result<()> {
365 let (_, test_repo) =
366 prep_proposals_repo_and_repo_with_proposal_pulled_and_checkedout(3).await?;
367 assert_eq!(
368 get_proposal_branch_name(&test_repo, FEATURE_BRANCH_NAME_3)?,
369 test_repo.get_checked_out_branch_name()?,
370 );
371 Ok(())
372 }
373
374 #[tokio::test]
375 #[serial]
376 async fn proposal_branch_tip_is_most_recent_patch() -> Result<()> {
377 let (originating_repo, test_repo) =
378 prep_proposals_repo_and_repo_with_proposal_pulled_and_checkedout(3).await?;
379 assert_eq!(
380 originating_repo.get_tip_of_local_branch(FEATURE_BRANCH_NAME_3)?,
381 test_repo.get_tip_of_local_branch(&get_proposal_branch_name(
382 &test_repo,
383 FEATURE_BRANCH_NAME_3
384 )?)?,
385 );
386 Ok(())
387 }
388 }
389 mod when_forth_proposal_has_no_cover_letter {
390 use super::*;
391
392 async fn prep_and_run() -> Result<(GitTestRepo, GitTestRepo)> {
393 // fallback (51,52) user write (53, 55) repo (55, 56)
394 let (mut r51, mut r52, mut r53, mut r55, mut r56) = (
395 Relay::new(8051, None, None),
396 Relay::new(8052, None, None),
397 Relay::new(8053, None, None),
398 Relay::new(8055, None, None),
399 Relay::new(8056, None, None),
400 );
401
402 r51.events.push(generate_test_key_1_relay_list_event());
403 r51.events.push(generate_test_key_1_metadata_event("fred"));
404 r51.events.push(generate_repo_ref_event());
405
406 r55.events.push(generate_repo_ref_event());
407 r55.events.push(generate_test_key_1_metadata_event("fred"));
408 r55.events.push(generate_test_key_1_relay_list_event());
409
410 let cli_tester_handle = std::thread::spawn(
411 move || -> Result<(GitTestRepo, GitTestRepo)> {
412 let originating_repo = cli_tester_create_proposals()?;
413 cli_tester_create_proposal(
414 &originating_repo,
415 FEATURE_BRANCH_NAME_4,
416 "d",
417 None,
418 None,
419 )?;
420 let test_repo = GitTestRepo::default();
421 test_repo.populate()?;
422 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
423
424 p.expect("fetching updates...\r\n")?;
425 p.expect_eventually("\r\n")?; // some updates listed here
426 let mut c = p.expect_choice(
427 "all proposals",
428 vec![
429 format!("add d3.md"), // commit msg title
430 format!("\"{PROPOSAL_TITLE_3}\""),
431 format!("\"{PROPOSAL_TITLE_2}\""),
432 format!("\"{PROPOSAL_TITLE_1}\""),
433 ],
434 )?;
435 c.succeeds_with(0, true, None)?;
436 let mut c = p.expect_choice(
437 "",
438 vec![
439 format!(
440 "create and checkout proposal branch (2 ahead 0 behind 'main')" ),
441 format!("apply to current branch with `git am`"),
442 format!("download to ./patches"),
443 format!("back"),
444 ],
445 )?;
446 c.succeeds_with(0, false, Some(0))?;
447 p.expect_end_eventually_and_print()?;
448
449 for p in [51, 52, 53, 55, 56] {
450 relay::shutdown_relay(8000 + p)?;
451 }
452 Ok((originating_repo, test_repo))
453 },
454 );
455
456 // launch relay
457 let _ = join!(
458 r51.listen_until_close(),
459 r52.listen_until_close(),
460 r53.listen_until_close(),
461 r55.listen_until_close(),
462 r56.listen_until_close(),
463 );
464 let res = cli_tester_handle.join().unwrap()?;
465
466 Ok(res)
467 }
468
469 mod cli_prompts {
470 use super::*;
471
472 #[tokio::test]
473 #[serial]
474 async fn prompts_to_choose_from_proposal_titles() -> Result<()> {
475 let (mut r51, mut r52, mut r53, mut r55, mut r56) = (
476 Relay::new(8051, None, None),
477 Relay::new(8052, None, None),
478 Relay::new(8053, None, None),
479 Relay::new(8055, None, None),
480 Relay::new(8056, None, None),
481 );
482
483 r51.events.push(generate_test_key_1_relay_list_event());
484 r51.events.push(generate_test_key_1_metadata_event("fred"));
485 r51.events.push(generate_repo_ref_event());
486
487 r55.events.push(generate_repo_ref_event());
488 r55.events.push(generate_test_key_1_metadata_event("fred"));
489 r55.events.push(generate_test_key_1_relay_list_event());
490
491 let cli_tester_handle = std::thread::spawn(move || -> Result<()> {
492 let originating_repo = cli_tester_create_proposals()?;
493 std::thread::sleep(std::time::Duration::from_millis(1000));
494 cli_tester_create_proposal(
495 &originating_repo,
496 FEATURE_BRANCH_NAME_4,
497 "d",
498 None,
499 None,
500 )?;
501 let test_repo = GitTestRepo::default();
502 test_repo.populate()?;
503 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
504
505 p.expect("fetching updates...\r\n")?;
506 p.expect_eventually("\r\n")?; // some updates listed here
507 let mut c = p.expect_choice(
508 "all proposals",
509 vec![
510 format!("add d3.md"), // commit msg title
511 format!("\"{PROPOSAL_TITLE_3}\""),
512 format!("\"{PROPOSAL_TITLE_2}\""),
513 format!("\"{PROPOSAL_TITLE_1}\""),
514 ],
515 )?;
516 c.succeeds_with(0, true, None)?;
517 let mut c = p.expect_choice(
518 "",
519 vec![
520 format!(
521 "create and checkout proposal branch (2 ahead 0 behind 'main')" ),
522 format!("apply to current branch with `git am`"),
523 format!("download to ./patches"),
524 format!("back"),
525 ],
526 )?;
527 c.succeeds_with(0, false, Some(0))?;
528 p.expect(&format!(
529 "checked out proposal as 'pr/{}(",
530 FEATURE_BRANCH_NAME_4,
531 ))?;
532 p.expect_end_eventually_with(")' branch\r\n")?;
533
534 for p in [51, 52, 53, 55, 56] {
535 relay::shutdown_relay(8000 + p)?;
536 }
537 Ok(())
538 });
539
540 // launch relay
541 let _ = join!(
542 r51.listen_until_close(),
543 r52.listen_until_close(),
544 r53.listen_until_close(),
545 r55.listen_until_close(),
546 r56.listen_until_close(),
547 );
548 cli_tester_handle.join().unwrap()?;
549 println!("{:?}", r55.events);
550 Ok(())
551 }
552 }
553
554 #[tokio::test]
555 #[serial]
556 async fn proposal_branch_created_with_correct_name() -> Result<()> {
557 let (_, test_repo) = prep_and_run().await?;
558 assert_eq!(
559 vec![
560 "main",
561 &get_proposal_branch_name(&test_repo, FEATURE_BRANCH_NAME_4)?,
562 ],
563 test_repo.get_local_branch_names()?
564 );
565 Ok(())
566 }
567
568 #[tokio::test]
569 #[serial]
570 async fn proposal_branch_checked_out() -> Result<()> {
571 let (_, test_repo) = prep_and_run().await?;
572 assert_eq!(
573 get_proposal_branch_name(&test_repo, FEATURE_BRANCH_NAME_4)?,
574 test_repo.get_checked_out_branch_name()?,
575 );
576 Ok(())
577 }
578
579 #[tokio::test]
580 #[serial]
581 async fn proposal_branch_tip_is_most_recent_patch() -> Result<()> {
582 let (originating_repo, test_repo) = prep_and_run().await?;
583 assert_eq!(
584 originating_repo.get_tip_of_local_branch(FEATURE_BRANCH_NAME_4)?,
585 test_repo.get_tip_of_local_branch(&get_proposal_branch_name(
586 &test_repo,
587 FEATURE_BRANCH_NAME_4
588 )?)?,
589 );
590 Ok(())
591 }
592 }
593 }
594 }
595
596 mod when_proposal_branch_exists {
597 use super::*;
598
599 mod when_main_is_checked_out {
600 use super::*;
601
602 mod when_branch_is_up_to_date {
603 use super::*;
604 async fn prep_and_run() -> Result<(GitTestRepo, GitTestRepo)> {
605 // fallback (51,52) user write (53, 55) repo (55, 56)
606 let (mut r51, mut r52, mut r53, mut r55, mut r56) = (
607 Relay::new(8051, None, None),
608 Relay::new(8052, None, None),
609 Relay::new(8053, None, None),
610 Relay::new(8055, None, None),
611 Relay::new(8056, None, None),
612 );
613
614 r51.events.push(generate_test_key_1_relay_list_event());
615 r51.events.push(generate_test_key_1_metadata_event("fred"));
616 r51.events.push(generate_repo_ref_event());
617
618 r55.events.push(generate_repo_ref_event());
619 r55.events.push(generate_test_key_1_metadata_event("fred"));
620 r55.events.push(generate_test_key_1_relay_list_event());
621
622 let cli_tester_handle = std::thread::spawn(
623 move || -> Result<(GitTestRepo, GitTestRepo)> {
624 let originating_repo = cli_tester_create_proposals()?;
625
626 let test_repo = GitTestRepo::default();
627 test_repo.populate()?;
628 // create proposal branch
629 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
630 p.expect("fetching updates...\r\n")?;
631 p.expect_eventually("\r\n")?; // some updates listed here
632 let mut c = p.expect_choice(
633 "all proposals",
634 vec![
635 format!("\"{PROPOSAL_TITLE_3}\""),
636 format!("\"{PROPOSAL_TITLE_2}\""),
637 format!("\"{PROPOSAL_TITLE_1}\""),
638 ],
639 )?;
640 c.succeeds_with(2, true, None)?;
641 let mut c = p.expect_choice(
642 "",
643 vec![
644 format!("create and checkout proposal branch (2 ahead 0 behind 'main')"),
645 format!("apply to current branch with `git am`"),
646 format!("download to ./patches"),
647 format!("back"),
648 ],
649 )?;
650 c.succeeds_with(0, false, Some(0))?;
651 p.expect_end_eventually()?;
652
653 test_repo.checkout("main")?;
654 // run test
655 p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
656 p.expect("fetching updates...\r\n")?;
657 p.expect_eventually("\r\n")?; // some updates listed here
658 let mut c = p.expect_choice(
659 "all proposals",
660 vec![
661 format!("\"{PROPOSAL_TITLE_3}\""),
662 format!("\"{PROPOSAL_TITLE_2}\""),
663 format!("\"{PROPOSAL_TITLE_1}\""),
664 ],
665 )?;
666 c.succeeds_with(2, true, None)?;
667 let mut c = p.expect_choice(
668 "",
669 vec![
670 format!("checkout proposal branch (2 ahead 0 behind 'main')"),
671 format!("apply to current branch with `git am`"),
672 format!("download to ./patches"),
673 format!("back"),
674 ],
675 )?;
676 c.succeeds_with(0, false, Some(0))?;
677 p.expect_end_eventually_and_print()?;
678
679 for p in [51, 52, 53, 55, 56] {
680 relay::shutdown_relay(8000 + p)?;
681 }
682 Ok((originating_repo, test_repo))
683 },
684 );
685
686 // launch relay
687 let _ = join!(
688 r51.listen_until_close(),
689 r52.listen_until_close(),
690 r53.listen_until_close(),
691 r55.listen_until_close(),
692 r56.listen_until_close(),
693 );
694 let res = cli_tester_handle.join().unwrap()?;
695
696 Ok(res)
697 }
698
699 mod cli_prompts {
700 use super::*;
701
702 #[tokio::test]
703 #[serial]
704 async fn prompts_to_choose_from_proposal_titles() -> Result<()> {
705 let (mut r51, mut r52, mut r53, mut r55, mut r56) = (
706 Relay::new(8051, None, None),
707 Relay::new(8052, None, None),
708 Relay::new(8053, None, None),
709 Relay::new(8055, None, None),
710 Relay::new(8056, None, None),
711 );
712
713 r51.events.push(generate_test_key_1_relay_list_event());
714 r51.events.push(generate_test_key_1_metadata_event("fred"));
715 r51.events.push(generate_repo_ref_event());
716
717 r55.events.push(generate_repo_ref_event());
718 r55.events.push(generate_test_key_1_metadata_event("fred"));
719 r55.events.push(generate_test_key_1_relay_list_event());
720
721 let cli_tester_handle = std::thread::spawn(move || -> Result<()> {
722 cli_tester_create_proposals()?;
723
724 let test_repo = GitTestRepo::default();
725 test_repo.populate()?;
726 // create proposal branch
727 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
728 p.expect("fetching updates...\r\n")?;
729 p.expect_eventually("\r\n")?; // some updates listed here
730 let mut c = p.expect_choice(
731 "all proposals",
732 vec![
733 format!("\"{PROPOSAL_TITLE_3}\""),
734 format!("\"{PROPOSAL_TITLE_2}\""),
735 format!("\"{PROPOSAL_TITLE_1}\""),
736 ],
737 )?;
738 c.succeeds_with(2, true, None)?;
739 let mut c = p.expect_choice(
740 "",
741 vec![
742 format!("create and checkout proposal branch (2 ahead 0 behind 'main')"),
743 format!("apply to current branch with `git am`"),
744 format!("download to ./patches"),
745 format!("back"),
746 ],
747 )?;
748 c.succeeds_with(0, false, Some(0))?;
749 p.expect_end_eventually()?;
750
751 test_repo.checkout("main")?;
752 // run test
753 p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
754 p.expect("fetching updates...\r\n")?;
755 p.expect_eventually("\r\n")?; // some updates listed here
756 let mut c = p.expect_choice(
757 "all proposals",
758 vec![
759 format!("\"{PROPOSAL_TITLE_3}\""),
760 format!("\"{PROPOSAL_TITLE_2}\""),
761 format!("\"{PROPOSAL_TITLE_1}\""),
762 ],
763 )?;
764 c.succeeds_with(2, true, None)?;
765 let mut c = p.expect_choice(
766 "",
767 vec![
768 format!("checkout proposal branch (2 ahead 0 behind 'main')"),
769 format!("apply to current branch with `git am`"),
770 format!("download to ./patches"),
771 format!("back"),
772 ],
773 )?;
774 c.succeeds_with(0, false, Some(0))?;
775 p.expect(&format!(
776 "checked out proposal as 'pr/{}(",
777 FEATURE_BRANCH_NAME_1,
778 ))?;
779 p.expect_end_eventually_with(")' branch\r\n")?;
780
781 for p in [51, 52, 53, 55, 56] {
782 relay::shutdown_relay(8000 + p)?;
783 }
784 Ok(())
785 });
786
787 // launch relay
788 let _ = join!(
789 r51.listen_until_close(),
790 r52.listen_until_close(),
791 r53.listen_until_close(),
792 r55.listen_until_close(),
793 r56.listen_until_close(),
794 );
795 cli_tester_handle.join().unwrap()?;
796 println!("{:?}", r55.events);
797 Ok(())
798 }
799 }
800
801 #[tokio::test]
802 #[serial]
803 async fn proposal_branch_checked_out() -> Result<()> {
804 let (_, test_repo) = prep_and_run().await?;
805 assert_eq!(
806 get_proposal_branch_name(&test_repo, FEATURE_BRANCH_NAME_1)?,
807 test_repo.get_checked_out_branch_name()?,
808 );
809 Ok(())
810 }
811 }
812
813 mod when_branch_is_behind {
814 use super::*;
815
816 async fn prep_and_run() -> Result<(GitTestRepo, GitTestRepo)> {
817 // fallback (51,52) user write (53, 55) repo (55, 56)
818 let (mut r51, mut r52, mut r53, mut r55, mut r56) = (
819 Relay::new(8051, None, None),
820 Relay::new(8052, None, None),
821 Relay::new(8053, None, None),
822 Relay::new(8055, None, None),
823 Relay::new(8056, None, None),
824 );
825
826 r51.events.push(generate_test_key_1_relay_list_event());
827 r51.events.push(generate_test_key_1_metadata_event("fred"));
828 r51.events.push(generate_repo_ref_event());
829
830 r55.events.push(generate_repo_ref_event());
831 r55.events.push(generate_test_key_1_metadata_event("fred"));
832 r55.events.push(generate_test_key_1_relay_list_event());
833
834 let cli_tester_handle = std::thread::spawn(
835 move || -> Result<(GitTestRepo, GitTestRepo)> {
836 let (originating_repo, test_repo) =
837 create_proposals_and_repo_with_proposal_pulled_and_checkedout(1)?;
838
839 remove_latest_commit_so_proposal_branch_is_behind_and_checkout_main(
840 &test_repo,
841 )?;
842
843 // run test
844 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
845 p.expect("fetching updates...\r\n")?;
846 p.expect_eventually("\r\n")?; // some updates listed here
847 let mut c = p.expect_choice(
848 "all proposals",
849 vec![
850 format!("\"{PROPOSAL_TITLE_3}\""),
851 format!("\"{PROPOSAL_TITLE_2}\""),
852 format!("\"{PROPOSAL_TITLE_1}\""),
853 ],
854 )?;
855 c.succeeds_with(2, true, None)?;
856 let mut c = p.expect_choice(
857 "",
858 vec![
859 format!("checkout proposal branch and apply 1 appendments"),
860 format!("apply to current branch with `git am`"),
861 format!("download to ./patches"),
862 format!("back"),
863 ],
864 )?;
865 c.succeeds_with(0, false, Some(0))?;
866 p.expect("checked out proposal branch and applied 1 appendments (2 ahead 0 behind 'main')\r\n")?;
867 p.expect_end()?;
868
869 for p in [51, 52, 53, 55, 56] {
870 relay::shutdown_relay(8000 + p)?;
871 }
872 Ok((originating_repo, test_repo))
873 },
874 );
875
876 // launch relay
877 let _ = join!(
878 r51.listen_until_close(),
879 r52.listen_until_close(),
880 r53.listen_until_close(),
881 r55.listen_until_close(),
882 r56.listen_until_close(),
883 );
884 let res = cli_tester_handle.join().unwrap()?;
885
886 Ok(res)
887 }
888
889 mod cli_prompts {
890 use super::*;
891
892 #[tokio::test]
893 #[serial]
894 async fn prompts_to_choose_from_proposal_titles() -> Result<()> {
895 let (mut r51, mut r52, mut r53, mut r55, mut r56) = (
896 Relay::new(8051, None, None),
897 Relay::new(8052, None, None),
898 Relay::new(8053, None, None),
899 Relay::new(8055, None, None),
900 Relay::new(8056, None, None),
901 );
902
903 r51.events.push(generate_test_key_1_relay_list_event());
904 r51.events.push(generate_test_key_1_metadata_event("fred"));
905 r51.events.push(generate_repo_ref_event());
906
907 r55.events.push(generate_repo_ref_event());
908 r55.events.push(generate_test_key_1_metadata_event("fred"));
909 r55.events.push(generate_test_key_1_relay_list_event());
910
911 let cli_tester_handle = std::thread::spawn(move || -> Result<()> {
912 let (_, test_repo) =
913 create_proposals_and_repo_with_proposal_pulled_and_checkedout(1)?;
914
915 remove_latest_commit_so_proposal_branch_is_behind_and_checkout_main(
916 &test_repo,
917 )?;
918
919 // run test
920 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
921 p.expect("fetching updates...\r\n")?;
922 p.expect_eventually("\r\n")?; // some updates listed here
923 let mut c = p.expect_choice(
924 "all proposals",
925 vec![
926 format!("\"{PROPOSAL_TITLE_3}\""),
927 format!("\"{PROPOSAL_TITLE_2}\""),
928 format!("\"{PROPOSAL_TITLE_1}\""),
929 ],
930 )?;
931 c.succeeds_with(2, true, None)?;
932 let mut c = p.expect_choice(
933 "",
934 vec![
935 format!("checkout proposal branch and apply 1 appendments"),
936 format!("apply to current branch with `git am`"),
937 format!("download to ./patches"),
938 format!("back"),
939 ],
940 )?;
941 c.succeeds_with(0, false, Some(0))?;
942 p.expect("checked out proposal branch and applied 1 appendments (2 ahead 0 behind 'main')\r\n")?;
943 p.expect_end()?;
944
945 for p in [51, 52, 53, 55, 56] {
946 relay::shutdown_relay(8000 + p)?;
947 }
948 Ok(())
949 });
950
951 // launch relay
952 let _ = join!(
953 r51.listen_until_close(),
954 r52.listen_until_close(),
955 r53.listen_until_close(),
956 r55.listen_until_close(),
957 r56.listen_until_close(),
958 );
959 cli_tester_handle.join().unwrap()?;
960 println!("{:?}", r55.events);
961 Ok(())
962 }
963 }
964
965 #[tokio::test]
966 #[serial]
967 async fn proposal_branch_checked_out() -> Result<()> {
968 let (_, test_repo) = prep_and_run().await?;
969 assert_eq!(
970 get_proposal_branch_name(&test_repo, FEATURE_BRANCH_NAME_1)?,
971 test_repo.get_checked_out_branch_name()?,
972 );
973 Ok(())
974 }
975
976 #[tokio::test]
977 #[serial]
978 async fn proposal_branch_tip_is_most_recent_patch() -> Result<()> {
979 let (originating_repo, test_repo) = prep_and_run().await?;
980 assert_eq!(
981 originating_repo.get_tip_of_local_branch(FEATURE_BRANCH_NAME_1)?,
982 test_repo.get_tip_of_local_branch(&get_proposal_branch_name(
983 &test_repo,
984 FEATURE_BRANCH_NAME_1
985 )?)?,
986 );
987 Ok(())
988 }
989 }
990
991 mod when_latest_proposal_amended_locally {
992 // other rebase scenarios should work if this test passes
993 use super::*;
994 async fn prep_and_run() -> Result<(GitTestRepo, GitTestRepo)> {
995 // fallback (51,52) user write (53, 55) repo (55, 56)
996 let (mut r51, mut r52, mut r53, mut r55, mut r56) = (
997 Relay::new(8051, None, None),
998 Relay::new(8052, None, None),
999 Relay::new(8053, None, None),
1000 Relay::new(8055, None, None),
1001 Relay::new(8056, None, None),
1002 );
1003
1004 r51.events.push(generate_test_key_1_relay_list_event());
1005 r51.events.push(generate_test_key_1_metadata_event("fred"));
1006 r51.events.push(generate_repo_ref_event());
1007
1008 r55.events.push(generate_repo_ref_event());
1009 r55.events.push(generate_test_key_1_metadata_event("fred"));
1010 r55.events.push(generate_test_key_1_relay_list_event());
1011
1012 let cli_tester_handle =
1013 std::thread::spawn(move || -> Result<(GitTestRepo, GitTestRepo)> {
1014 let (originating_repo, test_repo) =
1015 create_proposals_and_repo_with_proposal_pulled_and_checkedout(1)?;
1016
1017 let branch_name = test_repo.get_checked_out_branch_name()?;
1018
1019 remove_latest_commit_so_proposal_branch_is_behind_and_checkout_main(
1020 &test_repo,
1021 )?;
1022
1023 // add another commit (so we have an ammened local branch)
1024 test_repo.checkout(&branch_name)?;
1025 std::fs::write(
1026 test_repo.dir.join("ammended-commit.md"),
1027 "some content",
1028 )?;
1029 test_repo.stage_and_commit("add ammended-commit.md")?;
1030 test_repo.checkout("main")?;
1031
1032 // run test
1033 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
1034 p.expect("fetching updates...\r\n")?;
1035 p.expect_eventually("\r\n")?; // some updates listed here
1036 let mut c = p.expect_choice(
1037 "all proposals",
1038 vec![
1039 format!("\"{PROPOSAL_TITLE_3}\""),
1040 format!("\"{PROPOSAL_TITLE_2}\""),
1041 format!("\"{PROPOSAL_TITLE_1}\""),
1042 ],
1043 )?;
1044 c.succeeds_with(2, true, None)?;
1045 p.expect_eventually("--force`\r\n")?;
1046
1047 let mut c = p.expect_choice(
1048 "",
1049 vec![
1050 format!("checkout local branch with unpublished changes"),
1051 format!(
1052 "discard unpublished changes and checkout new revision"
1053 ),
1054 format!("apply to current branch with `git am`"),
1055 format!("download to ./patches"),
1056 "back".to_string(),
1057 ],
1058 )?;
1059 c.succeeds_with(1, false, Some(0))?;
1060
1061 p.expect_end_eventually_and_print()?;
1062
1063 for p in [51, 52, 53, 55, 56] {
1064 relay::shutdown_relay(8000 + p)?;
1065 }
1066 Ok((originating_repo, test_repo))
1067 });
1068 // launch relay
1069 let _ = join!(
1070 r51.listen_until_close(),
1071 r52.listen_until_close(),
1072 r53.listen_until_close(),
1073 r55.listen_until_close(),
1074 r56.listen_until_close(),
1075 );
1076 let res = cli_tester_handle.join().unwrap()?;
1077
1078 Ok(res)
1079 }
1080
1081 mod cli_prompts {
1082 use super::*;
1083
1084 #[tokio::test]
1085 #[serial]
1086 async fn out_reflects_second_choice_discarding_old_and_applying_new()
1087 -> Result<()> {
1088 let (mut r51, mut r52, mut r53, mut r55, mut r56) = (
1089 Relay::new(8051, None, None),
1090 Relay::new(8052, None, None),
1091 Relay::new(8053, None, None),
1092 Relay::new(8055, None, None),
1093 Relay::new(8056, None, None),
1094 );
1095
1096 r51.events.push(generate_test_key_1_relay_list_event());
1097 r51.events.push(generate_test_key_1_metadata_event("fred"));
1098 r51.events.push(generate_repo_ref_event());
1099
1100 r55.events.push(generate_repo_ref_event());
1101 r55.events.push(generate_test_key_1_metadata_event("fred"));
1102 r55.events.push(generate_test_key_1_relay_list_event());
1103
1104 let cli_tester_handle = std::thread::spawn(move || -> Result<()> {
1105 let (_, test_repo) =
1106 create_proposals_and_repo_with_proposal_pulled_and_checkedout(1)?;
1107
1108 amend_last_commit(&test_repo, "add ammended-commit.md")?;
1109 test_repo.checkout("main")?;
1110
1111 // run test
1112 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
1113 p.expect("fetching updates...\r\n")?;
1114 p.expect_eventually("\r\n")?; // some updates listed here
1115 let mut c = p.expect_choice(
1116 "all proposals",
1117 vec![
1118 format!("\"{PROPOSAL_TITLE_3}\""),
1119 format!("\"{PROPOSAL_TITLE_2}\""),
1120 format!("\"{PROPOSAL_TITLE_1}\""),
1121 ],
1122 )?;
1123 c.succeeds_with(2, true, None)?;
1124 p.expect("you have an amended/rebase version the proposal that is unpublished\r\n")?;
1125 p.expect("you have previously applied the latest version of the proposal (2 ahead 0 behind 'main') but your local proposal branch has amended or rebased it (2 ahead 0 behind 'main')\r\n")?;
1126 p.expect("to view the latest proposal but retain your changes:\r\n")?;
1127 p.expect(" 1) create a new branch off the tip commit of this one to store your changes\r\n")?;
1128 p.expect(" 2) run `ngit list` and checkout the latest published version of this proposal\r\n")?;
1129 p.expect("if you are confident in your changes consider running `ngit push --force`\r\n")?;
1130
1131 let mut c = p.expect_choice(
1132 "",
1133 vec![
1134 format!("checkout local branch with unpublished changes"),
1135 format!(
1136 "discard unpublished changes and checkout new revision"
1137 ),
1138 format!("apply to current branch with `git am`"),
1139 format!("download to ./patches"),
1140 "back".to_string(),
1141 ],
1142 )?;
1143 c.succeeds_with(1, false, Some(1))?;
1144 p.expect_end_with("checked out latest version of proposal (2 ahead 0 behind 'main'), replacing unpublished version (2 ahead 0 behind 'main')\r\n")?;
1145
1146 for p in [51, 52, 53, 55, 56] {
1147 relay::shutdown_relay(8000 + p)?;
1148 }
1149 Ok(())
1150 });
1151
1152 // launch relay
1153 let _ = join!(
1154 r51.listen_until_close(),
1155 r52.listen_until_close(),
1156 r53.listen_until_close(),
1157 r55.listen_until_close(),
1158 r56.listen_until_close(),
1159 );
1160 cli_tester_handle.join().unwrap()?;
1161 println!("{:?}", r55.events);
1162 Ok(())
1163 }
1164 }
1165
1166 #[tokio::test]
1167 #[serial]
1168 async fn second_choice_discarded_unpublished_commits_and_checked_out_latest_revision()
1169 -> Result<()> {
1170 let (originating_repo, test_repo) = prep_and_run().await?;
1171 println!("test_dir: {:?}", test_repo.dir);
1172 assert_eq!(
1173 test_repo.get_tip_of_local_branch(&get_proposal_branch_name(
1174 &test_repo,
1175 FEATURE_BRANCH_NAME_1
1176 )?)?,
1177 originating_repo.get_tip_of_local_branch(FEATURE_BRANCH_NAME_1)?,
1178 );
1179 Ok(())
1180 }
1181 }
1182
1183 mod when_local_commits_on_uptodate_proposal {
1184 use super::*;
1185 async fn prep_and_run() -> Result<(GitTestRepo, GitTestRepo)> {
1186 // fallback (51,52) user write (53, 55) repo (55, 56)
1187 let (mut r51, mut r52, mut r53, mut r55, mut r56) = (
1188 Relay::new(8051, None, None),
1189 Relay::new(8052, None, None),
1190 Relay::new(8053, None, None),
1191 Relay::new(8055, None, None),
1192 Relay::new(8056, None, None),
1193 );
1194
1195 r51.events.push(generate_test_key_1_relay_list_event());
1196 r51.events.push(generate_test_key_1_metadata_event("fred"));
1197 r51.events.push(generate_repo_ref_event());
1198
1199 r55.events.push(generate_repo_ref_event());
1200 r55.events.push(generate_test_key_1_metadata_event("fred"));
1201 r55.events.push(generate_test_key_1_relay_list_event());
1202
1203 let cli_tester_handle = std::thread::spawn(
1204 move || -> Result<(GitTestRepo, GitTestRepo)> {
1205 let (originating_repo, test_repo) =
1206 create_proposals_and_repo_with_proposal_pulled_and_checkedout(1)?;
1207
1208 // add another commit (so we have a local branch 1 ahead)
1209 std::fs::write(
1210 test_repo.dir.join("ammended-commit.md"),
1211 "some content",
1212 )?;
1213 test_repo.stage_and_commit("add ammended-commit.md")?;
1214 test_repo.checkout("main")?;
1215
1216 // run test
1217 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
1218 p.expect("fetching updates...\r\n")?;
1219 p.expect_eventually("\r\n")?; // some updates listed here
1220 let mut c = p.expect_choice(
1221 "all proposals",
1222 vec![
1223 format!("\"{PROPOSAL_TITLE_3}\""),
1224 format!("\"{PROPOSAL_TITLE_2}\""),
1225 format!("\"{PROPOSAL_TITLE_1}\""),
1226 ],
1227 )?;
1228 c.succeeds_with(2, true, None)?;
1229 p.expect(
1230 "local proposal branch exists with 1 unpublished commits on top of the most up-to-date version of the proposal (3 ahead 0 behind 'main')\r\n",
1231 )?;
1232
1233 let mut c = p.expect_choice(
1234 "",
1235 vec![
1236 format!("checkout proposal branch with 1 unpublished commits"),
1237 format!("back"),
1238 ],
1239 )?;
1240 c.succeeds_with(0, false, Some(0))?;
1241 p.expect("checked out proposal branch with 1 unpublished commits (3 ahead 0 behind 'main')\r\n")?;
1242 p.expect_end()?;
1243
1244 for p in [51, 52, 53, 55, 56] {
1245 relay::shutdown_relay(8000 + p)?;
1246 }
1247 Ok((originating_repo, test_repo))
1248 },
1249 );
1250
1251 // launch relay
1252 let _ = join!(
1253 r51.listen_until_close(),
1254 r52.listen_until_close(),
1255 r53.listen_until_close(),
1256 r55.listen_until_close(),
1257 r56.listen_until_close(),
1258 );
1259 let res = cli_tester_handle.join().unwrap()?;
1260
1261 Ok(res)
1262 }
1263
1264 mod cli_prompts {
1265 use super::*;
1266
1267 #[tokio::test]
1268 #[serial]
1269 async fn prompts_to_choose_from_proposal_titles() -> Result<()> {
1270 let (mut r51, mut r52, mut r53, mut r55, mut r56) = (
1271 Relay::new(8051, None, None),
1272 Relay::new(8052, None, None),
1273 Relay::new(8053, None, None),
1274 Relay::new(8055, None, None),
1275 Relay::new(8056, None, None),
1276 );
1277
1278 r51.events.push(generate_test_key_1_relay_list_event());
1279 r51.events.push(generate_test_key_1_metadata_event("fred"));
1280 r51.events.push(generate_repo_ref_event());
1281
1282 r55.events.push(generate_repo_ref_event());
1283 r55.events.push(generate_test_key_1_metadata_event("fred"));
1284 r55.events.push(generate_test_key_1_relay_list_event());
1285
1286 let cli_tester_handle = std::thread::spawn(move || -> Result<()> {
1287 let (_, test_repo) =
1288 create_proposals_and_repo_with_proposal_pulled_and_checkedout(1)?;
1289
1290 // add another commit (so we have a local branch 1 ahead)
1291 std::fs::write(
1292 test_repo.dir.join("ammended-commit.md"),
1293 "some content",
1294 )?;
1295 test_repo.stage_and_commit("add ammended-commit.md")?;
1296 test_repo.checkout("main")?;
1297
1298 // run test
1299 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
1300 p.expect("fetching updates...\r\n")?;
1301 p.expect_eventually("\r\n")?; // some updates listed here
1302 let mut c = p.expect_choice(
1303 "all proposals",
1304 vec![
1305 format!("\"{PROPOSAL_TITLE_3}\""),
1306 format!("\"{PROPOSAL_TITLE_2}\""),
1307 format!("\"{PROPOSAL_TITLE_1}\""),
1308 ],
1309 )?;
1310 c.succeeds_with(2, true, None)?;
1311 p.expect(
1312 "local proposal branch exists with 1 unpublished commits on top of the most up-to-date version of the proposal (3 ahead 0 behind 'main')\r\n",
1313 )?;
1314
1315 let mut c = p.expect_choice(
1316 "",
1317 vec![
1318 format!("checkout proposal branch with 1 unpublished commits"),
1319 format!("back"),
1320 ],
1321 )?;
1322 c.succeeds_with(0, false, Some(0))?;
1323 p.expect("checked out proposal branch with 1 unpublished commits (3 ahead 0 behind 'main')\r\n")?;
1324 p.expect_end()?;
1325
1326 for p in [51, 52, 53, 55, 56] {
1327 relay::shutdown_relay(8000 + p)?;
1328 }
1329 Ok(())
1330 });
1331
1332 // launch relay
1333 let _ = join!(
1334 r51.listen_until_close(),
1335 r52.listen_until_close(),
1336 r53.listen_until_close(),
1337 r55.listen_until_close(),
1338 r56.listen_until_close(),
1339 );
1340 cli_tester_handle.join().unwrap()?;
1341 println!("{:?}", r55.events);
1342 Ok(())
1343 }
1344 }
1345
1346 #[tokio::test]
1347 #[serial]
1348 async fn proposal_branch_checked_out() -> Result<()> {
1349 let (_, test_repo) = prep_and_run().await?;
1350 assert_eq!(
1351 get_proposal_branch_name(&test_repo, FEATURE_BRANCH_NAME_1)?,
1352 test_repo.get_checked_out_branch_name()?,
1353 );
1354 Ok(())
1355 }
1356
1357 #[tokio::test]
1358 #[serial]
1359 async fn didnt_overwrite_local_appendments() -> Result<()> {
1360 let (originating_repo, test_repo) = prep_and_run().await?;
1361 assert_ne!(
1362 test_repo.get_tip_of_local_branch(&get_proposal_branch_name(
1363 &test_repo,
1364 FEATURE_BRANCH_NAME_1
1365 )?)?,
1366 originating_repo.get_tip_of_local_branch(FEATURE_BRANCH_NAME_1)?,
1367 );
1368 Ok(())
1369 }
1370 }
1371
1372 mod when_latest_revision_rebases_branch {
1373
1374 use tokio::task::JoinHandle;
1375
1376 use super::*;
1377
1378 async fn prep_and_run() -> Result<(GitTestRepo, GitTestRepo)> {
1379 // fallback (51,52) user write (53, 55) repo (55, 56)
1380 let (mut r51, mut r52, mut r53, mut r55, mut r56) = (
1381 Relay::new(8051, None, None),
1382 Relay::new(8052, None, None),
1383 Relay::new(8053, None, None),
1384 Relay::new(8055, None, None),
1385 Relay::new(8056, None, None),
1386 );
1387
1388 r51.events.push(generate_test_key_1_relay_list_event());
1389 r51.events.push(generate_test_key_1_metadata_event("fred"));
1390 r51.events.push(generate_repo_ref_event());
1391
1392 r55.events.push(generate_repo_ref_event());
1393 r55.events.push(generate_test_key_1_metadata_event("fred"));
1394 r55.events.push(generate_test_key_1_relay_list_event());
1395
1396 let cli_tester_handle: JoinHandle<Result<(GitTestRepo, GitTestRepo)>> =
1397 tokio::task::spawn_blocking(move || {
1398 let (originating_repo, test_repo) = create_proposals_with_first_rebased_and_repo_with_latest_main_and_unrebased_proposal()?;
1399 test_repo.checkout("main")?;
1400
1401 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
1402 p.expect("fetching updates...\r\n")?;
1403 p.expect_eventually("\r\n")?; // some updates listed here
1404 let mut c = p.expect_choice(
1405 "all proposals",
1406 vec![
1407 format!("\"{PROPOSAL_TITLE_3}\""),
1408 format!("\"{PROPOSAL_TITLE_2}\""),
1409 format!("\"{PROPOSAL_TITLE_1}\""),
1410 ],
1411 )?;
1412 c.succeeds_with(2, true, None)?;
1413 p.expect("updated proposal available (2 ahead 0 behind 'main'). existing version is 2 ahead 1 behind 'main'\r\n")?;
1414 let mut c = p.expect_choice(
1415 "",
1416 vec![
1417 format!("checkout and overwrite existing proposal branch"),
1418 format!("checkout existing outdated proposal branch"),
1419 format!("apply to current branch with `git am`"),
1420 format!("download to ./patches"),
1421 format!("back"),
1422 ],
1423 )?;
1424 c.succeeds_with(0, false, Some(0))?;
1425 p.expect("checked out new version of proposal (2 ahead 0 behind 'main'), replacing old version (2 ahead 1 behind 'main')\r\n")?;
1426 p.expect_end()?;
1427
1428 for p in [51, 52, 53, 55, 56] {
1429 relay::shutdown_relay(8000 + p)?;
1430 }
1431 Ok((originating_repo, test_repo))
1432 });
1433
1434 // launch relay
1435 let _ = join!(
1436 r51.listen_until_close(),
1437 r52.listen_until_close(),
1438 r53.listen_until_close(),
1439 r55.listen_until_close(),
1440 r56.listen_until_close(),
1441 );
1442 let res = cli_tester_handle.await??;
1443
1444 Ok(res)
1445 }
1446
1447 mod cli_prompts {
1448 use super::*;
1449
1450 #[tokio::test]
1451 #[serial]
1452 async fn prompts_to_choose_from_proposal_titles() -> Result<()> {
1453 let (mut r51, mut r52, mut r53, mut r55, mut r56) = (
1454 Relay::new(8051, None, None),
1455 Relay::new(8052, None, None),
1456 Relay::new(8053, None, None),
1457 Relay::new(8055, None, None),
1458 Relay::new(8056, None, None),
1459 );
1460
1461 r51.events.push(generate_test_key_1_relay_list_event());
1462 r51.events.push(generate_test_key_1_metadata_event("fred"));
1463 r51.events.push(generate_repo_ref_event());
1464
1465 r55.events.push(generate_repo_ref_event());
1466 r55.events.push(generate_test_key_1_metadata_event("fred"));
1467 r55.events.push(generate_test_key_1_relay_list_event());
1468
1469 let cli_tester_handle: JoinHandle<Result<()>> = tokio::task::spawn_blocking(
1470 move || {
1471 let (_, test_repo) = create_proposals_with_first_rebased_and_repo_with_latest_main_and_unrebased_proposal()?;
1472 test_repo.checkout("main")?;
1473
1474 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
1475 p.expect("fetching updates...\r\n")?;
1476 p.expect_eventually("\r\n")?; // some updates listed here
1477 let mut c = p.expect_choice(
1478 "all proposals",
1479 vec![
1480 format!("\"{PROPOSAL_TITLE_3}\""),
1481 format!("\"{PROPOSAL_TITLE_2}\""),
1482 format!("\"{PROPOSAL_TITLE_1}\""),
1483 ],
1484 )?;
1485 c.succeeds_with(2, true, None)?;
1486 p.expect("updated proposal available (2 ahead 0 behind 'main'). existing version is 2 ahead 1 behind 'main'\r\n")?;
1487 let mut c = p.expect_choice(
1488 "",
1489 vec![
1490 format!("checkout and overwrite existing proposal branch"),
1491 format!("checkout existing outdated proposal branch"),
1492 format!("apply to current branch with `git am`"),
1493 format!("download to ./patches"),
1494 format!("back"),
1495 ],
1496 )?;
1497 c.succeeds_with(0, false, Some(0))?;
1498 p.expect("checked out new version of proposal (2 ahead 0 behind 'main'), replacing old version (2 ahead 1 behind 'main')\r\n")?;
1499 p.expect_end()?;
1500
1501 for p in [51, 52, 53, 55, 56] {
1502 relay::shutdown_relay(8000 + p)?;
1503 }
1504 Ok(())
1505 },
1506 );
1507
1508 // launch relay
1509 let _ = join!(
1510 r51.listen_until_close(),
1511 r52.listen_until_close(),
1512 r53.listen_until_close(),
1513 r55.listen_until_close(),
1514 r56.listen_until_close(),
1515 );
1516 cli_tester_handle.await??;
1517 println!("{:?}", r55.events);
1518 Ok(())
1519 }
1520 }
1521
1522 #[tokio::test]
1523 #[serial]
1524 async fn proposal_branch_checked_out() -> Result<()> {
1525 let (_, test_repo) = prep_and_run().await?;
1526 assert_eq!(
1527 get_proposal_branch_name(&test_repo, FEATURE_BRANCH_NAME_1)?,
1528 test_repo.get_checked_out_branch_name()?,
1529 );
1530 Ok(())
1531 }
1532
1533 #[tokio::test]
1534 #[serial]
1535 async fn proposal_branch_tip_is_most_recent_proposal_revision_tip() -> Result<()> {
1536 let (originating_repo, test_repo) = prep_and_run().await?;
1537 assert_eq!(
1538 originating_repo.get_tip_of_local_branch(FEATURE_BRANCH_NAME_1)?,
1539 test_repo.get_tip_of_local_branch(&get_proposal_branch_name(
1540 &test_repo,
1541 FEATURE_BRANCH_NAME_1
1542 )?)?,
1543 );
1544 Ok(())
1545 }
1546 }
1547 }
1548 }
1549}