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/prs_create.rs483
-rw-r--r--tests/prs_list.rs241
2 files changed, 562 insertions, 162 deletions
diff --git a/tests/prs_create.rs b/tests/prs_create.rs
index 6272ccd..316c9fe 100644
--- a/tests/prs_create.rs
+++ b/tests/prs_create.rs
@@ -1,6 +1,7 @@
1use anyhow::Result; 1use anyhow::Result;
2use futures::join;
2use serial_test::serial; 3use serial_test::serial;
3use test_utils::{git::GitTestRepo, *}; 4use test_utils::{git::GitTestRepo, relay::Relay, *};
4 5
5#[test] 6#[test]
6fn when_to_branch_doesnt_exist_return_error() -> Result<()> { 7fn when_to_branch_doesnt_exist_return_error() -> Result<()> {
@@ -150,121 +151,133 @@ fn is_patch(event: &nostr::Event) -> bool {
150 && !event.iter_tags().any(|t| t.as_vec()[1].eq("cover-letter")) 151 && !event.iter_tags().any(|t| t.as_vec()[1].eq("cover-letter"))
151} 152}
152 153
153mod sends_pr_and_2_patches_to_3_relays { 154fn prep_git_repo() -> Result<GitTestRepo> {
154 use futures::join; 155 let test_repo = GitTestRepo::default();
155 use test_utils::relay::Relay; 156 test_repo.populate()?;
156 157 // create feature branch with 2 commit ahead
157 use super::*; 158 test_repo.create_branch("feature")?;
159 test_repo.checkout("feature")?;
160 std::fs::write(test_repo.dir.join("t3.md"), "some content")?;
161 test_repo.stage_and_commit("add t3.md")?;
162 std::fs::write(test_repo.dir.join("t4.md"), "some content")?;
163 test_repo.stage_and_commit("add t4.md")?;
164 Ok(test_repo)
165}
158 166
159 fn prep_git_repo() -> Result<GitTestRepo> { 167fn cli_tester_create_pr(git_repo: &GitTestRepo, include_cover_letter: bool) -> CliTester {
160 let test_repo = GitTestRepo::default(); 168 let mut args = vec![
161 test_repo.populate()?; 169 "--nsec",
162 // create feature branch with 2 commit ahead 170 TEST_KEY_1_NSEC,
163 test_repo.create_branch("feature")?; 171 "--password",
164 test_repo.checkout("feature")?; 172 TEST_PASSWORD,
165 std::fs::write(test_repo.dir.join("t3.md"), "some content")?; 173 "--disable-cli-spinners",
166 test_repo.stage_and_commit("add t3.md")?; 174 "prs",
167 std::fs::write(test_repo.dir.join("t4.md"), "some content")?; 175 "create",
168 test_repo.stage_and_commit("add t4.md")?; 176 ];
169 Ok(test_repo) 177 if include_cover_letter {
178 for arg in [
179 "--title",
180 "exampletitle",
181 "--description",
182 "exampledescription",
183 ] {
184 args.push(arg);
185 }
186 } else {
187 args.push("--no-cover-letter");
170 } 188 }
189 CliTester::new_from_dir(&git_repo.dir, args)
190}
171 191
172 fn cli_tester_create_pr(git_repo: &GitTestRepo) -> CliTester { 192fn expect_msgs_first(p: &mut CliTester, include_cover_letter: bool) -> Result<()> {
173 CliTester::new_from_dir( 193 p.expect("creating patch for 2 commits from 'head' that can be merged into 'main'\r\n")?;
174 &git_repo.dir, 194 p.expect("searching for your details...\r\n")?;
175 [ 195 p.expect("\r")?;
176 "--nsec", 196 p.expect("logged in as fred\r\n")?;
177 TEST_KEY_1_NSEC, 197 p.expect(format!(
178 "--password", 198 "posting 2 patches {} a covering letter...\r\n",
179 TEST_PASSWORD, 199 if include_cover_letter {
180 "--disable-cli-spinners", 200 "with"
181 "prs", 201 } else {
182 "create", 202 "without"
183 "--title", 203 }
184 "exampletitle", 204 ))?;
185 "--description", 205 Ok(())
186 "exampledescription", 206}
187 ],
188 )
189 }
190 207
191 fn expect_msgs_first(p: &mut CliTester) -> Result<()> { 208async fn prep_run_create_pr(
192 p.expect("creating patch for 2 commits from 'head' that can be merged into 'main'\r\n")?; 209 include_cover_letter: bool,
193 p.expect("searching for your details...\r\n")?; 210) -> Result<(
194 p.expect("\r")?; 211 Relay<'static>,
195 p.expect("logged in as fred\r\n")?; 212 Relay<'static>,
196 p.expect("posting 1 pull request with 2 commits...\r\n")?; 213 Relay<'static>,
214 Relay<'static>,
215 Relay<'static>,
216)> {
217 let git_repo = prep_git_repo()?;
218 // fallback (51,52) user write (53, 55) repo (55, 56)
219 let (mut r51, mut r52, mut r53, mut r55, mut r56) = (
220 Relay::new(
221 8051,
222 None,
223 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
224 relay.respond_events(
225 client_id,
226 &subscription_id,
227 &vec![
228 generate_test_key_1_metadata_event("fred"),
229 generate_test_key_1_relay_list_event(),
230 ],
231 )?;
232 Ok(())
233 }),
234 ),
235 Relay::new(8052, None, None),
236 Relay::new(8053, None, None),
237 Relay::new(
238 8055,
239 None,
240 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
241 relay.respond_events(
242 client_id,
243 &subscription_id,
244 &vec![generate_repo_ref_event()],
245 )?;
246 Ok(())
247 }),
248 ),
249 Relay::new(8056, None, None),
250 );
251
252 // // check relay had the right number of events
253 let cli_tester_handle = std::thread::spawn(move || -> Result<()> {
254 let mut p = cli_tester_create_pr(&git_repo, include_cover_letter);
255 p.expect_end_eventually()?;
256 for p in [51, 52, 53, 55, 56] {
257 relay::shutdown_relay(8000 + p)?;
258 }
197 Ok(()) 259 Ok(())
198 } 260 });
261
262 // launch relay
263 let _ = join!(
264 r51.listen_until_close(),
265 r52.listen_until_close(),
266 r53.listen_until_close(),
267 r55.listen_until_close(),
268 r56.listen_until_close(),
269 );
270 cli_tester_handle.join().unwrap()?;
271 Ok((r51, r52, r53, r55, r56))
272}
199 273
200 async fn prep_run_create_pr() -> Result<( 274mod sends_cover_letter_and_2_patches_to_3_relays {
201 Relay<'static>,
202 Relay<'static>,
203 Relay<'static>,
204 Relay<'static>,
205 Relay<'static>,
206 )> {
207 let git_repo = prep_git_repo()?;
208 // fallback (51,52) user write (53, 55) repo (55, 56)
209 let (mut r51, mut r52, mut r53, mut r55, mut r56) = (
210 Relay::new(
211 8051,
212 None,
213 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
214 relay.respond_events(
215 client_id,
216 &subscription_id,
217 &vec![
218 generate_test_key_1_metadata_event("fred"),
219 generate_test_key_1_relay_list_event(),
220 ],
221 )?;
222 Ok(())
223 }),
224 ),
225 Relay::new(8052, None, None),
226 Relay::new(8053, None, None),
227 Relay::new(
228 8055,
229 None,
230 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
231 relay.respond_events(
232 client_id,
233 &subscription_id,
234 &vec![generate_repo_ref_event()],
235 )?;
236 Ok(())
237 }),
238 ),
239 Relay::new(8056, None, None),
240 );
241
242 // // check relay had the right number of events
243 let cli_tester_handle = std::thread::spawn(move || -> Result<()> {
244 let mut p = cli_tester_create_pr(&git_repo);
245 p.expect_end_eventually()?;
246 for p in [51, 52, 53, 55, 56] {
247 relay::shutdown_relay(8000 + p)?;
248 }
249 Ok(())
250 });
251
252 // launch relay
253 let _ = join!(
254 r51.listen_until_close(),
255 r52.listen_until_close(),
256 r53.listen_until_close(),
257 r55.listen_until_close(),
258 r56.listen_until_close(),
259 );
260 cli_tester_handle.join().unwrap()?;
261 Ok((r51, r52, r53, r55, r56))
262 }
263 275
276 use super::*;
264 #[tokio::test] 277 #[tokio::test]
265 #[serial] 278 #[serial]
266 async fn only_1_pr_kind_event_sent_to_each_relay() -> Result<()> { 279 async fn only_1_pr_kind_event_sent_to_each_relay() -> Result<()> {
267 let (_, _, r53, r55, r56) = prep_run_create_pr().await?; 280 let (_, _, r53, r55, r56) = prep_run_create_pr(true).await?;
268 for relay in [&r53, &r55, &r56] { 281 for relay in [&r53, &r55, &r56] {
269 assert_eq!( 282 assert_eq!(
270 relay.events.iter().filter(|e| is_cover_letter(e)).count(), 283 relay.events.iter().filter(|e| is_cover_letter(e)).count(),
@@ -277,7 +290,7 @@ mod sends_pr_and_2_patches_to_3_relays {
277 #[tokio::test] 290 #[tokio::test]
278 #[serial] 291 #[serial]
279 async fn only_1_pr_kind_event_sent_to_user_relays() -> Result<()> { 292 async fn only_1_pr_kind_event_sent_to_user_relays() -> Result<()> {
280 let (_, _, r53, r55, _) = prep_run_create_pr().await?; 293 let (_, _, r53, r55, _) = prep_run_create_pr(true).await?;
281 for relay in [&r53, &r55] { 294 for relay in [&r53, &r55] {
282 assert_eq!( 295 assert_eq!(
283 relay.events.iter().filter(|e| is_cover_letter(e)).count(), 296 relay.events.iter().filter(|e| is_cover_letter(e)).count(),
@@ -290,7 +303,7 @@ mod sends_pr_and_2_patches_to_3_relays {
290 #[tokio::test] 303 #[tokio::test]
291 #[serial] 304 #[serial]
292 async fn only_1_pr_kind_event_sent_to_repo_relays() -> Result<()> { 305 async fn only_1_pr_kind_event_sent_to_repo_relays() -> Result<()> {
293 let (_, _, _, r55, r56) = prep_run_create_pr().await?; 306 let (_, _, _, r55, r56) = prep_run_create_pr(true).await?;
294 for relay in [&r55, &r56] { 307 for relay in [&r55, &r56] {
295 assert_eq!( 308 assert_eq!(
296 relay.events.iter().filter(|e| is_cover_letter(e)).count(), 309 relay.events.iter().filter(|e| is_cover_letter(e)).count(),
@@ -303,7 +316,7 @@ mod sends_pr_and_2_patches_to_3_relays {
303 #[tokio::test] 316 #[tokio::test]
304 #[serial] 317 #[serial]
305 async fn pr_not_sent_to_fallback_relay() -> Result<()> { 318 async fn pr_not_sent_to_fallback_relay() -> Result<()> {
306 let (r51, r52, _, _, _) = prep_run_create_pr().await?; 319 let (r51, r52, _, _, _) = prep_run_create_pr(true).await?;
307 for relay in [&r51, &r52] { 320 for relay in [&r51, &r52] {
308 assert_eq!( 321 assert_eq!(
309 relay.events.iter().filter(|e| is_cover_letter(e)).count(), 322 relay.events.iter().filter(|e| is_cover_letter(e)).count(),
@@ -316,7 +329,7 @@ mod sends_pr_and_2_patches_to_3_relays {
316 #[tokio::test] 329 #[tokio::test]
317 #[serial] 330 #[serial]
318 async fn only_2_patch_kind_events_sent_to_each_relay() -> Result<()> { 331 async fn only_2_patch_kind_events_sent_to_each_relay() -> Result<()> {
319 let (_, _, r53, r55, r56) = prep_run_create_pr().await?; 332 let (_, _, r53, r55, r56) = prep_run_create_pr(true).await?;
320 for relay in [&r53, &r55, &r56] { 333 for relay in [&r53, &r55, &r56] {
321 assert_eq!(relay.events.iter().filter(|e| is_patch(e)).count(), 2,); 334 assert_eq!(relay.events.iter().filter(|e| is_patch(e)).count(), 2,);
322 } 335 }
@@ -327,18 +340,18 @@ mod sends_pr_and_2_patches_to_3_relays {
327 #[serial] 340 #[serial]
328 async fn patch_content_contains_patch_in_email_format_with_patch_series_numbers() -> Result<()> 341 async fn patch_content_contains_patch_in_email_format_with_patch_series_numbers() -> Result<()>
329 { 342 {
330 let (_, _, r53, r55, r56) = prep_run_create_pr().await?; 343 let (_, _, r53, r55, r56) = prep_run_create_pr(true).await?;
331 for relay in [&r53, &r55, &r56] { 344 for relay in [&r53, &r55, &r56] {
332 let patch_events: Vec<&nostr::Event> = 345 let patch_events: Vec<&nostr::Event> =
333 relay.events.iter().filter(|e| is_patch(e)).collect(); 346 relay.events.iter().filter(|e| is_patch(e)).collect();
334 347
335 assert_eq!( 348 assert_eq!(
336 patch_events[0].content, 349 patch_events[1].content,
337 "\ 350 "\
338 From fe973a840fba2a8ab37dd505c154854a69a6505c Mon Sep 17 00:00:00 2001\n\ 351 From fe973a840fba2a8ab37dd505c154854a69a6505c Mon Sep 17 00:00:00 2001\n\
339 From: Joe Bloggs <joe.bloggs@pm.me>\n\ 352 From: Joe Bloggs <joe.bloggs@pm.me>\n\
340 Date: Thu, 1 Jan 1970 00:00:00 +0000\n\ 353 Date: Thu, 1 Jan 1970 00:00:00 +0000\n\
341 Subject: [PATCH 1/2] add t4.md\n\ 354 Subject: [PATCH 2/2] add t4.md\n\
342 \n\ 355 \n\
343 ---\n \ 356 ---\n \
344 t4.md | 1 +\n \ 357 t4.md | 1 +\n \
@@ -359,12 +372,12 @@ mod sends_pr_and_2_patches_to_3_relays {
359 ", 372 ",
360 ); 373 );
361 assert_eq!( 374 assert_eq!(
362 patch_events[1].content, 375 patch_events[0].content,
363 "\ 376 "\
364 From 232efb37ebc67692c9e9ff58b83c0d3d63971a0a Mon Sep 17 00:00:00 2001\n\ 377 From 232efb37ebc67692c9e9ff58b83c0d3d63971a0a Mon Sep 17 00:00:00 2001\n\
365 From: Joe Bloggs <joe.bloggs@pm.me>\n\ 378 From: Joe Bloggs <joe.bloggs@pm.me>\n\
366 Date: Thu, 1 Jan 1970 00:00:00 +0000\n\ 379 Date: Thu, 1 Jan 1970 00:00:00 +0000\n\
367 Subject: [PATCH 2/2] add t3.md\n\ 380 Subject: [PATCH 1/2] add t3.md\n\
368 \n\ 381 \n\
369 ---\n \ 382 ---\n \
370 t3.md | 1 +\n \ 383 t3.md | 1 +\n \
@@ -394,7 +407,7 @@ mod sends_pr_and_2_patches_to_3_relays {
394 #[tokio::test] 407 #[tokio::test]
395 #[serial] 408 #[serial]
396 async fn root_commit_as_r() -> Result<()> { 409 async fn root_commit_as_r() -> Result<()> {
397 let (_, _, r53, r55, r56) = prep_run_create_pr().await?; 410 let (_, _, r53, r55, r56) = prep_run_create_pr(true).await?;
398 for relay in [&r53, &r55, &r56] { 411 for relay in [&r53, &r55, &r56] {
399 let pr_event: &nostr::Event = 412 let pr_event: &nostr::Event =
400 relay.events.iter().find(|e| is_cover_letter(e)).unwrap(); 413 relay.events.iter().find(|e| is_cover_letter(e)).unwrap();
@@ -414,7 +427,7 @@ mod sends_pr_and_2_patches_to_3_relays {
414 #[tokio::test] 427 #[tokio::test]
415 #[serial] 428 #[serial]
416 async fn a_tag_for_repo_event() -> Result<()> { 429 async fn a_tag_for_repo_event() -> Result<()> {
417 let (_, _, r53, r55, r56) = prep_run_create_pr().await?; 430 let (_, _, r53, r55, r56) = prep_run_create_pr(true).await?;
418 for relay in [&r53, &r55, &r56] { 431 for relay in [&r53, &r55, &r56] {
419 let pr_event: &nostr::Event = 432 let pr_event: &nostr::Event =
420 relay.events.iter().find(|e| is_cover_letter(e)).unwrap(); 433 relay.events.iter().find(|e| is_cover_letter(e)).unwrap();
@@ -436,7 +449,7 @@ mod sends_pr_and_2_patches_to_3_relays {
436 .unwrap() 449 .unwrap()
437 .as_vec() 450 .as_vec()
438 .clone()[1..]; 451 .clone()[1..];
439 let (_, _, r53, r55, r56) = prep_run_create_pr().await?; 452 let (_, _, r53, r55, r56) = prep_run_create_pr(true).await?;
440 for relay in [&r53, &r55, &r56] { 453 for relay in [&r53, &r55, &r56] {
441 for m in maintainers { 454 for m in maintainers {
442 let pr_event: &nostr::Event = 455 let pr_event: &nostr::Event =
@@ -454,7 +467,7 @@ mod sends_pr_and_2_patches_to_3_relays {
454 #[tokio::test] 467 #[tokio::test]
455 #[serial] 468 #[serial]
456 async fn t_tag_cover_letter() -> Result<()> { 469 async fn t_tag_cover_letter() -> Result<()> {
457 let (_, _, r53, r55, r56) = prep_run_create_pr().await?; 470 let (_, _, r53, r55, r56) = prep_run_create_pr(true).await?;
458 for relay in [&r53, &r55, &r56] { 471 for relay in [&r53, &r55, &r56] {
459 let pr_event: &nostr::Event = 472 let pr_event: &nostr::Event =
460 relay.events.iter().find(|e| is_cover_letter(e)).unwrap(); 473 relay.events.iter().find(|e| is_cover_letter(e)).unwrap();
@@ -470,7 +483,7 @@ mod sends_pr_and_2_patches_to_3_relays {
470 #[tokio::test] 483 #[tokio::test]
471 #[serial] 484 #[serial]
472 async fn t_tag_root() -> Result<()> { 485 async fn t_tag_root() -> Result<()> {
473 let (_, _, r53, r55, r56) = prep_run_create_pr().await?; 486 let (_, _, r53, r55, r56) = prep_run_create_pr(true).await?;
474 for relay in [&r53, &r55, &r56] { 487 for relay in [&r53, &r55, &r56] {
475 let pr_event: &nostr::Event = 488 let pr_event: &nostr::Event =
476 relay.events.iter().find(|e| is_cover_letter(e)).unwrap(); 489 relay.events.iter().find(|e| is_cover_letter(e)).unwrap();
@@ -486,7 +499,7 @@ mod sends_pr_and_2_patches_to_3_relays {
486 #[tokio::test] 499 #[tokio::test]
487 #[serial] 500 #[serial]
488 async fn pr_tags_branch_name() -> Result<()> { 501 async fn pr_tags_branch_name() -> Result<()> {
489 let (_, _, r53, r55, r56) = prep_run_create_pr().await?; 502 let (_, _, r53, r55, r56) = prep_run_create_pr(true).await?;
490 for relay in [&r53, &r55, &r56] { 503 for relay in [&r53, &r55, &r56] {
491 let pr_event: &nostr::Event = 504 let pr_event: &nostr::Event =
492 relay.events.iter().find(|e| is_cover_letter(e)).unwrap(); 505 relay.events.iter().find(|e| is_cover_letter(e)).unwrap();
@@ -509,14 +522,14 @@ mod sends_pr_and_2_patches_to_3_relays {
509 use super::*; 522 use super::*;
510 523
511 async fn prep() -> Result<nostr::Event> { 524 async fn prep() -> Result<nostr::Event> {
512 let (_, _, r53, _, _) = prep_run_create_pr().await?; 525 let (_, _, r53, _, _) = prep_run_create_pr(true).await?;
513 Ok(r53.events.iter().find(|e| is_patch(e)).unwrap().clone()) 526 Ok(r53.events.iter().find(|e| is_patch(e)).unwrap().clone())
514 } 527 }
515 528
516 #[tokio::test] 529 #[tokio::test]
517 #[serial] 530 #[serial]
518 async fn commit_and_commit_r() -> Result<()> { 531 async fn commit_and_commit_r() -> Result<()> {
519 static COMMIT_ID: &str = "fe973a840fba2a8ab37dd505c154854a69a6505c"; 532 static COMMIT_ID: &str = "232efb37ebc67692c9e9ff58b83c0d3d63971a0a";
520 let most_recent_patch = prep().await?; 533 let most_recent_patch = prep().await?;
521 assert!( 534 assert!(
522 most_recent_patch 535 most_recent_patch
@@ -537,12 +550,16 @@ mod sends_pr_and_2_patches_to_3_relays {
537 #[serial] 550 #[serial]
538 async fn parent_commit() -> Result<()> { 551 async fn parent_commit() -> Result<()> {
539 // commit parent 'r' and 'parent-commit' tag 552 // commit parent 'r' and 'parent-commit' tag
540 static COMMIT_PARENT_ID: &str = "232efb37ebc67692c9e9ff58b83c0d3d63971a0a"; 553 static COMMIT_PARENT_ID: &str = "431b84edc0d2fa118d63faa3c2db9c73d630a5ae";
541 let most_recent_patch = prep().await?; 554 let most_recent_patch = prep().await?;
542 assert!( 555 assert_eq!(
543 most_recent_patch.tags.iter().any( 556 most_recent_patch
544 |t| t.as_vec()[0].eq("parent-commit") && t.as_vec()[1].eq(COMMIT_PARENT_ID) 557 .tags
545 ) 558 .iter()
559 .find(|t| t.as_vec()[0].eq("parent-commit"))
560 .unwrap()
561 .as_vec()[1],
562 COMMIT_PARENT_ID,
546 ); 563 );
547 Ok(()) 564 Ok(())
548 } 565 }
@@ -599,7 +616,7 @@ mod sends_pr_and_2_patches_to_3_relays {
599 .find(|t| t.as_vec()[0].eq("description")) 616 .find(|t| t.as_vec()[0].eq("description"))
600 .unwrap() 617 .unwrap()
601 .as_vec()[1], 618 .as_vec()[1],
602 "add t4.md" 619 "add t3.md"
603 ); 620 );
604 Ok(()) 621 Ok(())
605 } 622 }
@@ -639,7 +656,7 @@ mod sends_pr_and_2_patches_to_3_relays {
639 #[tokio::test] 656 #[tokio::test]
640 #[serial] 657 #[serial]
641 async fn patch_tags_pr_event_as_root() -> Result<()> { 658 async fn patch_tags_pr_event_as_root() -> Result<()> {
642 let (_, _, r53, r55, r56) = prep_run_create_pr().await?; 659 let (_, _, r53, r55, r56) = prep_run_create_pr(true).await?;
643 for relay in [&r53, &r55, &r56] { 660 for relay in [&r53, &r55, &r56] {
644 let patch_events: Vec<&nostr::Event> = 661 let patch_events: Vec<&nostr::Event> =
645 relay.events.iter().filter(|e| is_patch(e)).collect(); 662 relay.events.iter().filter(|e| is_patch(e)).collect();
@@ -659,6 +676,43 @@ mod sends_pr_and_2_patches_to_3_relays {
659 } 676 }
660 Ok(()) 677 Ok(())
661 } 678 }
679
680 #[tokio::test]
681 #[serial]
682 async fn second_patch_tags_first_with_reply() -> Result<()> {
683 let (_, _, r53, r55, r56) = prep_run_create_pr(true).await?;
684 for relay in [&r53, &r55, &r56] {
685 let patch_events = relay
686 .events
687 .iter()
688 .filter(|e| is_patch(e))
689 .collect::<Vec<&nostr::Event>>();
690 assert_eq!(
691 patch_events[1]
692 .iter_tags()
693 .find(|t| t.as_vec()[0].eq("e")
694 && t.as_vec().len().eq(&4)
695 && t.as_vec()[3].eq("reply"))
696 .unwrap()
697 .as_vec()[1],
698 patch_events[0].id.to_string(),
699 );
700 }
701 Ok(())
702 }
703
704 #[tokio::test]
705 #[serial]
706 async fn no_t_root_tag() -> Result<()> {
707 assert!(
708 !prep()
709 .await?
710 .tags
711 .iter()
712 .any(|t| t.as_vec()[0].eq("t") && t.as_vec()[1].eq("root"))
713 );
714 Ok(())
715 }
662 } 716 }
663 mod cli_ouput { 717 mod cli_ouput {
664 use super::*; 718 use super::*;
@@ -701,8 +755,8 @@ mod sends_pr_and_2_patches_to_3_relays {
701 755
702 // // check relay had the right number of events 756 // // check relay had the right number of events
703 let cli_tester_handle = std::thread::spawn(move || -> Result<()> { 757 let cli_tester_handle = std::thread::spawn(move || -> Result<()> {
704 let mut p = cli_tester_create_pr(&git_repo); 758 let mut p = cli_tester_create_pr(&git_repo, true);
705 expect_msgs_first(&mut p)?; 759 expect_msgs_first(&mut p, true)?;
706 relay::expect_send_with_progress( 760 relay::expect_send_with_progress(
707 &mut p, 761 &mut p,
708 vec![ 762 vec![
@@ -790,7 +844,7 @@ mod sends_pr_and_2_patches_to_3_relays {
790 844
791 // // check relay had the right number of events 845 // // check relay had the right number of events
792 let cli_tester_handle = std::thread::spawn(move || -> Result<()> { 846 let cli_tester_handle = std::thread::spawn(move || -> Result<()> {
793 let mut p = cli_tester_create_pr(&git_repo); 847 let mut p = cli_tester_create_pr(&git_repo, true);
794 p.expect_end_eventually()?; 848 p.expect_end_eventually()?;
795 for p in [51, 52, 53, 55, 56] { 849 for p in [51, 52, 53, 55, 56] {
796 relay::shutdown_relay(8000 + p)?; 850 relay::shutdown_relay(8000 + p)?;
@@ -869,8 +923,8 @@ mod sends_pr_and_2_patches_to_3_relays {
869 923
870 // // check relay had the right number of events 924 // // check relay had the right number of events
871 let cli_tester_handle = std::thread::spawn(move || -> Result<()> { 925 let cli_tester_handle = std::thread::spawn(move || -> Result<()> {
872 let mut p = cli_tester_create_pr(&git_repo); 926 let mut p = cli_tester_create_pr(&git_repo, true);
873 expect_msgs_first(&mut p)?; 927 expect_msgs_first(&mut p, true)?;
874 // p.expect_end_with("bla")?; 928 // p.expect_end_with("bla")?;
875 relay::expect_send_with_progress( 929 relay::expect_send_with_progress(
876 &mut p, 930 &mut p,
@@ -915,7 +969,162 @@ mod sends_pr_and_2_patches_to_3_relays {
915 } 969 }
916} 970}
917 971
918mod without_cover_letter { 972mod sends_2_patches_without_cover_letter {
919 use super::*; 973 use super::*;
920 // TODO 974
975 mod cli_ouput {
976 use super::*;
977
978 async fn run_test_async() -> Result<()> {
979 let git_repo = prep_git_repo()?;
980
981 let (mut r51, mut r52, mut r53, mut r55, mut r56) = (
982 Relay::new(
983 8051,
984 None,
985 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
986 relay.respond_events(
987 client_id,
988 &subscription_id,
989 &vec![
990 generate_test_key_1_metadata_event("fred"),
991 generate_test_key_1_relay_list_event(),
992 ],
993 )?;
994 Ok(())
995 }),
996 ),
997 Relay::new(8052, None, None),
998 Relay::new(8053, None, None),
999 Relay::new(
1000 8055,
1001 None,
1002 Some(&|relay, client_id, subscription_id, _| -> Result<()> {
1003 relay.respond_events(
1004 client_id,
1005 &subscription_id,
1006 &vec![generate_repo_ref_event()],
1007 )?;
1008 Ok(())
1009 }),
1010 ),
1011 Relay::new(8056, None, None),
1012 );
1013
1014 // // check relay had the right number of events
1015 let cli_tester_handle = std::thread::spawn(move || -> Result<()> {
1016 let mut p = cli_tester_create_pr(&git_repo, false);
1017
1018 expect_msgs_first(&mut p, false)?;
1019 relay::expect_send_with_progress(
1020 &mut p,
1021 vec![
1022 (" [my-relay] [repo-relay] ws://localhost:8055", true, ""),
1023 (" [my-relay] ws://localhost:8053", true, ""),
1024 (" [repo-relay] ws://localhost:8056", true, ""),
1025 ],
1026 2,
1027 )?;
1028 p.expect_end_with_whitespace()?;
1029 for p in [51, 52, 53, 55, 56] {
1030 relay::shutdown_relay(8000 + p)?;
1031 }
1032 Ok(())
1033 });
1034
1035 // launch relay
1036 let _ = join!(
1037 r51.listen_until_close(),
1038 r52.listen_until_close(),
1039 r53.listen_until_close(),
1040 r55.listen_until_close(),
1041 r56.listen_until_close(),
1042 );
1043 cli_tester_handle.join().unwrap()?;
1044 Ok(())
1045 }
1046
1047 #[tokio::test]
1048 #[serial]
1049 async fn check_cli_output() -> Result<()> {
1050 run_test_async().await?;
1051 Ok(())
1052 }
1053 }
1054
1055 #[tokio::test]
1056 #[serial]
1057 async fn no_cover_letter_event() -> Result<()> {
1058 let (_, _, r53, r55, r56) = prep_run_create_pr(false).await?;
1059 for relay in [&r53, &r55, &r56] {
1060 assert_eq!(
1061 relay.events.iter().filter(|e| is_cover_letter(e)).count(),
1062 0,
1063 );
1064 }
1065 Ok(())
1066 }
1067
1068 #[tokio::test]
1069 #[serial]
1070 async fn two_patch_events() -> Result<()> {
1071 let (_, _, r53, r55, r56) = prep_run_create_pr(false).await?;
1072 for relay in [&r53, &r55, &r56] {
1073 assert_eq!(relay.events.iter().filter(|e| is_patch(e)).count(), 2);
1074 }
1075 Ok(())
1076 }
1077
1078 #[tokio::test]
1079 #[serial]
1080 // TODO check this is the ancestor
1081 async fn first_patch_with_root_t_tag() -> Result<()> {
1082 let (_, _, r53, r55, r56) = prep_run_create_pr(false).await?;
1083 for relay in [&r53, &r55, &r56] {
1084 let patch_events = relay
1085 .events
1086 .iter()
1087 .filter(|e| is_patch(e))
1088 .collect::<Vec<&nostr::Event>>();
1089
1090 // first patch tagged as root
1091 assert!(
1092 patch_events[0]
1093 .iter_tags()
1094 .any(|t| t.as_vec()[0].eq("t") && t.as_vec()[1].eq("root"))
1095 );
1096 // second patch not tagged as root
1097 assert!(
1098 !patch_events[1]
1099 .iter_tags()
1100 .any(|t| t.as_vec()[0].eq("t") && t.as_vec()[1].eq("root"))
1101 );
1102 }
1103 Ok(())
1104 }
1105
1106 #[tokio::test]
1107 #[serial]
1108 async fn second_patch_lists_first_as_root() -> Result<()> {
1109 let (_, _, r53, r55, r56) = prep_run_create_pr(false).await?;
1110 for relay in [&r53, &r55, &r56] {
1111 let patch_events = relay
1112 .events
1113 .iter()
1114 .filter(|e| is_patch(e))
1115 .collect::<Vec<&nostr::Event>>();
1116
1117 assert_eq!(
1118 patch_events[1]
1119 .iter_tags()
1120 .find(|t| t.as_vec()[0].eq("e")
1121 && t.as_vec().len().eq(&4)
1122 && t.as_vec()[3].eq("root"))
1123 .unwrap()
1124 .as_vec()[1],
1125 patch_events[0].id.to_string(),
1126 );
1127 }
1128 Ok(())
1129 }
921} 1130}
diff --git a/tests/prs_list.rs b/tests/prs_list.rs
index 75704f6..7c0d8ec 100644
--- a/tests/prs_list.rs
+++ b/tests/prs_list.rs
@@ -6,6 +6,7 @@ use test_utils::{git::GitTestRepo, relay::Relay, *};
6static FEATURE_BRANCH_NAME_1: &str = "feature-example-t"; 6static FEATURE_BRANCH_NAME_1: &str = "feature-example-t";
7static FEATURE_BRANCH_NAME_2: &str = "feature-example-f"; 7static FEATURE_BRANCH_NAME_2: &str = "feature-example-f";
8static FEATURE_BRANCH_NAME_3: &str = "feature-example-c"; 8static FEATURE_BRANCH_NAME_3: &str = "feature-example-c";
9static FEATURE_BRANCH_NAME_4: &str = "feature-example-d";
9 10
10static PR_TITLE_1: &str = "pr a"; 11static PR_TITLE_1: &str = "pr a";
11static PR_TITLE_2: &str = "pr b"; 12static PR_TITLE_2: &str = "pr b";
@@ -18,22 +19,19 @@ fn cli_tester_create_prs() -> Result<GitTestRepo> {
18 &git_repo, 19 &git_repo,
19 FEATURE_BRANCH_NAME_1, 20 FEATURE_BRANCH_NAME_1,
20 "a", 21 "a",
21 PR_TITLE_1, 22 Some((PR_TITLE_1, "pr a description")),
22 "pr a description",
23 )?; 23 )?;
24 cli_tester_create_pr( 24 cli_tester_create_pr(
25 &git_repo, 25 &git_repo,
26 FEATURE_BRANCH_NAME_2, 26 FEATURE_BRANCH_NAME_2,
27 "b", 27 "b",
28 PR_TITLE_2, 28 Some((PR_TITLE_2, "pr b description")),
29 "pr b description",
30 )?; 29 )?;
31 cli_tester_create_pr( 30 cli_tester_create_pr(
32 &git_repo, 31 &git_repo,
33 FEATURE_BRANCH_NAME_3, 32 FEATURE_BRANCH_NAME_3,
34 "c", 33 "c",
35 PR_TITLE_3, 34 Some((PR_TITLE_3, "pr c description")),
36 "pr c description",
37 )?; 35 )?;
38 Ok(git_repo) 36 Ok(git_repo)
39} 37}
@@ -66,28 +64,44 @@ fn cli_tester_create_pr(
66 test_repo: &GitTestRepo, 64 test_repo: &GitTestRepo,
67 branch_name: &str, 65 branch_name: &str,
68 prefix: &str, 66 prefix: &str,
69 title: &str, 67 cover_letter_title_and_description: Option<(&str, &str)>,
70 description: &str,
71) -> Result<()> { 68) -> Result<()> {
72 create_and_populate_branch(test_repo, branch_name, prefix, false)?; 69 create_and_populate_branch(test_repo, branch_name, prefix, false)?;
73 70
74 let mut p = CliTester::new_from_dir( 71 if let Some((title, description)) = cover_letter_title_and_description {
75 &test_repo.dir, 72 let mut p = CliTester::new_from_dir(
76 [ 73 &test_repo.dir,
77 "--nsec", 74 [
78 TEST_KEY_1_NSEC, 75 "--nsec",
79 "--password", 76 TEST_KEY_1_NSEC,
80 TEST_PASSWORD, 77 "--password",
81 "--disable-cli-spinners", 78 TEST_PASSWORD,
82 "prs", 79 "--disable-cli-spinners",
83 "create", 80 "prs",
84 "--title", 81 "create",
85 format!("\"{title}\"").as_str(), 82 "--title",
86 "--description", 83 format!("\"{title}\"").as_str(),
87 format!("\"{description}\"").as_str(), 84 "--description",
88 ], 85 format!("\"{description}\"").as_str(),
89 ); 86 ],
90 p.expect_end_eventually()?; 87 );
88 p.expect_end_eventually()?;
89 } else {
90 let mut p = CliTester::new_from_dir(
91 &test_repo.dir,
92 [
93 "--nsec",
94 TEST_KEY_1_NSEC,
95 "--password",
96 TEST_PASSWORD,
97 "--disable-cli-spinners",
98 "prs",
99 "create",
100 "--no-cover-letter",
101 ],
102 );
103 p.expect_end_eventually()?;
104 }
91 Ok(()) 105 Ok(())
92} 106}
93 107
@@ -432,6 +446,183 @@ mod when_main_branch_is_uptodate {
432 Ok(()) 446 Ok(())
433 } 447 }
434 } 448 }
449 mod when_forth_pr_has_no_cover_letter {
450 use super::*;
451
452 async fn prep_and_run() -> Result<(GitTestRepo, GitTestRepo)> {
453 // fallback (51,52) user write (53, 55) repo (55, 56)
454 let (mut r51, mut r52, mut r53, mut r55, mut r56) = (
455 Relay::new(8051, None, None),
456 Relay::new(8052, None, None),
457 Relay::new(8053, None, None),
458 Relay::new(8055, None, None),
459 Relay::new(8056, None, None),
460 );
461
462 r51.events.push(generate_test_key_1_relay_list_event());
463 r51.events.push(generate_test_key_1_metadata_event("fred"));
464 r51.events.push(generate_repo_ref_event());
465
466 r55.events.push(generate_repo_ref_event());
467 r55.events.push(generate_test_key_1_metadata_event("fred"));
468 r55.events.push(generate_test_key_1_relay_list_event());
469
470 let cli_tester_handle =
471 std::thread::spawn(move || -> Result<(GitTestRepo, GitTestRepo)> {
472 let originating_repo = cli_tester_create_prs()?;
473 cli_tester_create_pr(
474 &originating_repo,
475 FEATURE_BRANCH_NAME_4,
476 "d",
477 None,
478 )?;
479 let test_repo = GitTestRepo::default();
480 test_repo.populate()?;
481 let mut p = CliTester::new_from_dir(&test_repo.dir, ["prs", "list"]);
482
483 p.expect("finding PRs...\r\n")?;
484 let mut c = p.expect_choice(
485 "All PRs",
486 vec![
487 format!("\"{PR_TITLE_1}\""),
488 format!("\"{PR_TITLE_2}\""),
489 format!("\"{PR_TITLE_3}\""),
490 format!("add d3.md"), // commit msg title
491 ],
492 )?;
493 c.succeeds_with(3, true)?;
494 let mut confirm =
495 p.expect_confirm_eventually("check out branch?", Some(true))?;
496 confirm.succeeds_with(None)?;
497 p.expect_end_eventually_and_print()?;
498
499 for p in [51, 52, 53, 55, 56] {
500 relay::shutdown_relay(8000 + p)?;
501 }
502 Ok((originating_repo, test_repo))
503 });
504
505 // launch relay
506 let _ = join!(
507 r51.listen_until_close(),
508 r52.listen_until_close(),
509 r53.listen_until_close(),
510 r55.listen_until_close(),
511 r56.listen_until_close(),
512 );
513 let res = cli_tester_handle.join().unwrap()?;
514
515 Ok(res)
516 }
517
518 mod cli_prompts {
519 use super::*;
520 async fn run_async_prompts_to_choose_from_pr_titles() -> Result<()> {
521 let (mut r51, mut r52, mut r53, mut r55, mut r56) = (
522 Relay::new(8051, None, None),
523 Relay::new(8052, None, None),
524 Relay::new(8053, None, None),
525 Relay::new(8055, None, None),
526 Relay::new(8056, None, None),
527 );
528
529 r51.events.push(generate_test_key_1_relay_list_event());
530 r51.events.push(generate_test_key_1_metadata_event("fred"));
531 r51.events.push(generate_repo_ref_event());
532
533 r55.events.push(generate_repo_ref_event());
534 r55.events.push(generate_test_key_1_metadata_event("fred"));
535 r55.events.push(generate_test_key_1_relay_list_event());
536
537 let cli_tester_handle = std::thread::spawn(move || -> Result<()> {
538 let originating_repo = cli_tester_create_prs()?;
539 cli_tester_create_pr(
540 &originating_repo,
541 FEATURE_BRANCH_NAME_4,
542 "d",
543 None,
544 )?;
545 let test_repo = GitTestRepo::default();
546 test_repo.populate()?;
547 let mut p = CliTester::new_from_dir(&test_repo.dir, ["prs", "list"]);
548
549 p.expect("finding PRs...\r\n")?;
550 let mut c = p.expect_choice(
551 "All PRs",
552 vec![
553 format!("\"{PR_TITLE_1}\""),
554 format!("\"{PR_TITLE_2}\""),
555 format!("\"{PR_TITLE_3}\""),
556 format!("add d3.md"), // commit msg title
557 ],
558 )?;
559 c.succeeds_with(3, true)?;
560 p.expect("finding commits...\r\n")?;
561 let mut confirm = p.expect_confirm("check out branch?", Some(true))?;
562 confirm.succeeds_with(None)?;
563 p.expect("checked out PR branch. pulled 2 new commits\r\n")?;
564 p.expect_end()?;
565
566 for p in [51, 52, 53, 55, 56] {
567 relay::shutdown_relay(8000 + p)?;
568 }
569 Ok(())
570 });
571
572 // launch relay
573 let _ = join!(
574 r51.listen_until_close(),
575 r52.listen_until_close(),
576 r53.listen_until_close(),
577 r55.listen_until_close(),
578 r56.listen_until_close(),
579 );
580 cli_tester_handle.join().unwrap()?;
581 println!("{:?}", r55.events);
582 Ok(())
583 }
584
585 #[tokio::test]
586 #[serial]
587 async fn prompts_to_choose_from_pr_titles() -> Result<()> {
588 let _ = run_async_prompts_to_choose_from_pr_titles().await;
589 Ok(())
590 }
591 }
592
593 #[tokio::test]
594 #[serial]
595 async fn pr_branch_created_with_correct_name() -> Result<()> {
596 let (_, test_repo) = prep_and_run().await?;
597 assert_eq!(
598 vec![FEATURE_BRANCH_NAME_4, "main"],
599 test_repo.get_local_branch_names()?
600 );
601 Ok(())
602 }
603
604 #[tokio::test]
605 #[serial]
606 async fn pr_branch_checked_out() -> Result<()> {
607 let (_, test_repo) = prep_and_run().await?;
608 assert_eq!(
609 FEATURE_BRANCH_NAME_4,
610 test_repo.get_checked_out_branch_name()?,
611 );
612 Ok(())
613 }
614
615 #[tokio::test]
616 #[serial]
617 async fn pr_branch_tip_is_most_recent_patch() -> Result<()> {
618 let (originating_repo, test_repo) = prep_and_run().await?;
619 assert_eq!(
620 originating_repo.get_tip_of_local_branch(FEATURE_BRANCH_NAME_4)?,
621 test_repo.get_tip_of_local_branch(FEATURE_BRANCH_NAME_4)?,
622 );
623 Ok(())
624 }
625 }
435 } 626 }
436 } 627 }
437 628