diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2026-01-08 00:50:54 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2026-01-08 00:50:54 +0000 |
| commit | f75e1c59aacf5ce668fd327e4e3d827511661c2a (patch) | |
| tree | 867926c7503e7c587e86c67896a9e7347600447b /tests | |
| parent | 3f14f998d64b5fa15bdddd7570b4f72874eb9f29 (diff) | |
chore: cargo fmt
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/common/git_server.rs | 98 | ||||
| -rw-r--r-- | tests/common/mock_relay.rs | 23 | ||||
| -rw-r--r-- | tests/common/purgatory_helpers.rs | 29 | ||||
| -rw-r--r-- | tests/common/relay.rs | 5 |
4 files changed, 99 insertions, 56 deletions
diff --git a/tests/common/git_server.rs b/tests/common/git_server.rs index adf66b5..d0d727e 100644 --- a/tests/common/git_server.rs +++ b/tests/common/git_server.rs | |||
| @@ -301,7 +301,10 @@ fn find_free_port() -> u16 { | |||
| 301 | use std::net::TcpListener; | 301 | use std::net::TcpListener; |
| 302 | 302 | ||
| 303 | let listener = TcpListener::bind("127.0.0.1:0").expect("Failed to bind to random port"); | 303 | let listener = TcpListener::bind("127.0.0.1:0").expect("Failed to bind to random port"); |
| 304 | let port = listener.local_addr().expect("Failed to get local addr").port(); | 304 | let port = listener |
| 305 | .local_addr() | ||
| 306 | .expect("Failed to get local addr") | ||
| 307 | .port(); | ||
| 305 | drop(listener); | 308 | drop(listener); |
| 306 | port | 309 | port |
| 307 | } | 310 | } |
| @@ -320,7 +323,10 @@ async fn wait_for_server_ready(port: u16) { | |||
| 320 | } | 323 | } |
| 321 | Err(_) => { | 324 | Err(_) => { |
| 322 | if attempt == max_attempts - 1 { | 325 | if attempt == max_attempts - 1 { |
| 323 | panic!("SimpleGitServer failed to start after {} attempts", max_attempts); | 326 | panic!( |
| 327 | "SimpleGitServer failed to start after {} attempts", | ||
| 328 | max_attempts | ||
| 329 | ); | ||
| 324 | } | 330 | } |
| 325 | tokio::time::sleep(delay).await; | 331 | tokio::time::sleep(delay).await; |
| 326 | } | 332 | } |
| @@ -366,10 +372,13 @@ mod tests { | |||
| 366 | .await | 372 | .await |
| 367 | .expect("Failed to fetch info/refs"); | 373 | .expect("Failed to fetch info/refs"); |
| 368 | 374 | ||
| 369 | assert!(response.status().is_success(), "info/refs should be accessible"); | 375 | assert!( |
| 376 | response.status().is_success(), | ||
| 377 | "info/refs should be accessible" | ||
| 378 | ); | ||
| 370 | 379 | ||
| 371 | let body = response.text().await.expect("Failed to read response body"); | 380 | let body = response.text().await.expect("Failed to read response body"); |
| 372 | 381 | ||
| 373 | // Should contain at least one ref (HEAD or refs/heads/main) | 382 | // Should contain at least one ref (HEAD or refs/heads/main) |
| 374 | assert!( | 383 | assert!( |
| 375 | body.contains("refs/heads/main") || body.contains("HEAD"), | 384 | body.contains("refs/heads/main") || body.contains("HEAD"), |
| @@ -404,7 +413,7 @@ mod tests { | |||
| 404 | ); | 413 | ); |
| 405 | 414 | ||
| 406 | let stdout = String::from_utf8_lossy(&output.stdout); | 415 | let stdout = String::from_utf8_lossy(&output.stdout); |
| 407 | 416 | ||
| 408 | // Should list the main branch with the correct commit | 417 | // Should list the main branch with the correct commit |
| 409 | assert!( | 418 | assert!( |
| 410 | stdout.contains(&commit_hash), | 419 | stdout.contains(&commit_hash), |
| @@ -433,7 +442,7 @@ mod tests { | |||
| 433 | 442 | ||
| 434 | // Create a destination repo to fetch into | 443 | // Create a destination repo to fetch into |
| 435 | let dest_dir = tempfile::tempdir().expect("Failed to create dest dir"); | 444 | let dest_dir = tempfile::tempdir().expect("Failed to create dest dir"); |
| 436 | 445 | ||
| 437 | // Initialize empty repo (using tokio::process::Command) | 446 | // Initialize empty repo (using tokio::process::Command) |
| 438 | let output = tokio::process::Command::new("git") | 447 | let output = tokio::process::Command::new("git") |
| 439 | .args(["init"]) | 448 | .args(["init"]) |
| @@ -487,14 +496,23 @@ mod tests { | |||
| 487 | #[test] | 496 | #[test] |
| 488 | fn test_is_safe_path_blocks_traversal() { | 497 | fn test_is_safe_path_blocks_traversal() { |
| 489 | let repo_path = Path::new("/tmp/repo"); | 498 | let repo_path = Path::new("/tmp/repo"); |
| 490 | 499 | ||
| 491 | // Safe paths | 500 | // Safe paths |
| 492 | assert!(is_safe_path(Path::new("/tmp/repo/info/refs"), repo_path)); | 501 | assert!(is_safe_path(Path::new("/tmp/repo/info/refs"), repo_path)); |
| 493 | assert!(is_safe_path(Path::new("/tmp/repo/objects/pack/file.pack"), repo_path)); | 502 | assert!(is_safe_path( |
| 494 | 503 | Path::new("/tmp/repo/objects/pack/file.pack"), | |
| 504 | repo_path | ||
| 505 | )); | ||
| 506 | |||
| 495 | // Unsafe paths (path traversal) | 507 | // Unsafe paths (path traversal) |
| 496 | assert!(!is_safe_path(Path::new("/tmp/repo/../etc/passwd"), repo_path)); | 508 | assert!(!is_safe_path( |
| 497 | assert!(!is_safe_path(Path::new("/tmp/repo/../../etc/passwd"), repo_path)); | 509 | Path::new("/tmp/repo/../etc/passwd"), |
| 510 | repo_path | ||
| 511 | )); | ||
| 512 | assert!(!is_safe_path( | ||
| 513 | Path::new("/tmp/repo/../../etc/passwd"), | ||
| 514 | repo_path | ||
| 515 | )); | ||
| 498 | } | 516 | } |
| 499 | } | 517 | } |
| 500 | 518 | ||
| @@ -563,17 +581,19 @@ impl SmartGitServer { | |||
| 563 | } | 581 | } |
| 564 | 582 | ||
| 565 | // 3. Create and bind listener (eliminates port race condition) | 583 | // 3. Create and bind listener (eliminates port race condition) |
| 566 | let std_listener = std::net::TcpListener::bind("127.0.0.1:0") | 584 | let std_listener = |
| 567 | .expect("Failed to bind to random port"); | 585 | std::net::TcpListener::bind("127.0.0.1:0").expect("Failed to bind to random port"); |
| 568 | let port = std_listener.local_addr() | 586 | let port = std_listener |
| 587 | .local_addr() | ||
| 569 | .expect("Failed to get local addr") | 588 | .expect("Failed to get local addr") |
| 570 | .port(); | 589 | .port(); |
| 571 | 590 | ||
| 572 | // Convert to tokio listener (keeps port bound) | 591 | // Convert to tokio listener (keeps port bound) |
| 573 | std_listener.set_nonblocking(true) | 592 | std_listener |
| 593 | .set_nonblocking(true) | ||
| 574 | .expect("Failed to set non-blocking"); | 594 | .expect("Failed to set non-blocking"); |
| 575 | let listener = TcpListener::from_std(std_listener) | 595 | let listener = |
| 576 | .expect("Failed to convert to tokio listener"); | 596 | TcpListener::from_std(std_listener).expect("Failed to convert to tokio listener"); |
| 577 | 597 | ||
| 578 | // 4. Create shutdown channel | 598 | // 4. Create shutdown channel |
| 579 | let (shutdown_tx, mut shutdown_rx) = oneshot::channel::<()>(); | 599 | let (shutdown_tx, mut shutdown_rx) = oneshot::channel::<()>(); |
| @@ -690,15 +710,13 @@ async fn handle_smart_request( | |||
| 690 | // Route: GET /info/refs?service=git-upload-pack | 710 | // Route: GET /info/refs?service=git-upload-pack |
| 691 | if method == hyper::Method::GET && path.ends_with("/info/refs") { | 711 | if method == hyper::Method::GET && path.ends_with("/info/refs") { |
| 692 | // Parse service from query string | 712 | // Parse service from query string |
| 693 | let service = query | 713 | let service = query.split('&').find_map(|param| { |
| 694 | .split('&') | 714 | let mut parts = param.splitn(2, '='); |
| 695 | .find_map(|param| { | 715 | match (parts.next(), parts.next()) { |
| 696 | let mut parts = param.splitn(2, '='); | 716 | (Some("service"), Some(svc)) => Some(svc), |
| 697 | match (parts.next(), parts.next()) { | 717 | _ => None, |
| 698 | (Some("service"), Some(svc)) => Some(svc), | 718 | } |
| 699 | _ => None, | 719 | }); |
| 700 | } | ||
| 701 | }); | ||
| 702 | 720 | ||
| 703 | match service { | 721 | match service { |
| 704 | Some("git-upload-pack") => { | 722 | Some("git-upload-pack") => { |
| @@ -714,7 +732,9 @@ async fn handle_smart_request( | |||
| 714 | _ => { | 732 | _ => { |
| 715 | return Ok(Response::builder() | 733 | return Ok(Response::builder() |
| 716 | .status(StatusCode::BAD_REQUEST) | 734 | .status(StatusCode::BAD_REQUEST) |
| 717 | .body(Full::new(Bytes::from("Missing or invalid service parameter"))) | 735 | .body(Full::new(Bytes::from( |
| 736 | "Missing or invalid service parameter", | ||
| 737 | ))) | ||
| 718 | .unwrap()); | 738 | .unwrap()); |
| 719 | } | 739 | } |
| 720 | } | 740 | } |
| @@ -740,8 +760,8 @@ async fn handle_info_refs_upload_pack( | |||
| 740 | git_protocol_version: Option<&str>, | 760 | git_protocol_version: Option<&str>, |
| 741 | ) -> Result<Response<Full<Bytes>>, hyper::Error> { | 761 | ) -> Result<Response<Full<Bytes>>, hyper::Error> { |
| 742 | use std::process::Stdio; | 762 | use std::process::Stdio; |
| 743 | use tokio::process::Command as TokioCommand; | ||
| 744 | use tokio::io::AsyncReadExt; | 763 | use tokio::io::AsyncReadExt; |
| 764 | use tokio::process::Command as TokioCommand; | ||
| 745 | 765 | ||
| 746 | // Spawn git upload-pack --advertise-refs | 766 | // Spawn git upload-pack --advertise-refs |
| 747 | let mut cmd = TokioCommand::new("git"); | 767 | let mut cmd = TokioCommand::new("git"); |
| @@ -763,8 +783,7 @@ async fn handle_info_refs_upload_pack( | |||
| 763 | .stdout(Stdio::piped()) | 783 | .stdout(Stdio::piped()) |
| 764 | .stderr(Stdio::piped()); | 784 | .stderr(Stdio::piped()); |
| 765 | 785 | ||
| 766 | let mut child = match cmd.spawn() | 786 | let mut child = match cmd.spawn() { |
| 767 | { | ||
| 768 | Ok(child) => child, | 787 | Ok(child) => child, |
| 769 | Err(e) => { | 788 | Err(e) => { |
| 770 | eprintln!("Failed to spawn git upload-pack: {}", e); | 789 | eprintln!("Failed to spawn git upload-pack: {}", e); |
| @@ -800,7 +819,7 @@ async fn handle_info_refs_upload_pack( | |||
| 800 | let len = service_line.len() + 4; | 819 | let len = service_line.len() + 4; |
| 801 | response_body.extend_from_slice(format!("{:04x}", len).as_bytes()); | 820 | response_body.extend_from_slice(format!("{:04x}", len).as_bytes()); |
| 802 | response_body.extend_from_slice(service_line.as_bytes()); | 821 | response_body.extend_from_slice(service_line.as_bytes()); |
| 803 | 822 | ||
| 804 | // Flush packet | 823 | // Flush packet |
| 805 | response_body.extend_from_slice(b"0000"); | 824 | response_body.extend_from_slice(b"0000"); |
| 806 | 825 | ||
| @@ -809,7 +828,10 @@ async fn handle_info_refs_upload_pack( | |||
| 809 | 828 | ||
| 810 | Ok(Response::builder() | 829 | Ok(Response::builder() |
| 811 | .status(StatusCode::OK) | 830 | .status(StatusCode::OK) |
| 812 | .header("Content-Type", "application/x-git-upload-pack-advertisement") | 831 | .header( |
| 832 | "Content-Type", | ||
| 833 | "application/x-git-upload-pack-advertisement", | ||
| 834 | ) | ||
| 813 | .header("Cache-Control", "no-cache") | 835 | .header("Cache-Control", "no-cache") |
| 814 | .body(Full::new(Bytes::from(response_body))) | 836 | .body(Full::new(Bytes::from(response_body))) |
| 815 | .unwrap()) | 837 | .unwrap()) |
| @@ -850,8 +872,7 @@ async fn handle_upload_pack( | |||
| 850 | .stdout(Stdio::piped()) | 872 | .stdout(Stdio::piped()) |
| 851 | .stderr(Stdio::piped()); | 873 | .stderr(Stdio::piped()); |
| 852 | 874 | ||
| 853 | let mut child = match cmd.spawn() | 875 | let mut child = match cmd.spawn() { |
| 854 | { | ||
| 855 | Ok(child) => child, | 876 | Ok(child) => child, |
| 856 | Err(e) => { | 877 | Err(e) => { |
| 857 | eprintln!("Failed to spawn git upload-pack: {}", e); | 878 | eprintln!("Failed to spawn git upload-pack: {}", e); |
| @@ -957,7 +978,10 @@ mod smart_git_server_tests { | |||
| 957 | content_type | 978 | content_type |
| 958 | ); | 979 | ); |
| 959 | 980 | ||
| 960 | let body = response.bytes().await.expect("Failed to read response body"); | 981 | let body = response |
| 982 | .bytes() | ||
| 983 | .await | ||
| 984 | .expect("Failed to read response body"); | ||
| 961 | 985 | ||
| 962 | // Should start with service advertisement pkt-line | 986 | // Should start with service advertisement pkt-line |
| 963 | let body_str = String::from_utf8_lossy(&body); | 987 | let body_str = String::from_utf8_lossy(&body); |
| @@ -1077,7 +1101,7 @@ mod smart_git_server_tests { | |||
| 1077 | #[tokio::test] | 1101 | #[tokio::test] |
| 1078 | async fn test_smart_git_server_shallow_fetch() { | 1102 | async fn test_smart_git_server_shallow_fetch() { |
| 1079 | // This is the KEY test - shallow fetch requires smart HTTP protocol | 1103 | // This is the KEY test - shallow fetch requires smart HTTP protocol |
| 1080 | 1104 | ||
| 1081 | // Create a source repo with a commit | 1105 | // Create a source repo with a commit |
| 1082 | let source_dir = tempfile::tempdir().expect("Failed to create source dir"); | 1106 | let source_dir = tempfile::tempdir().expect("Failed to create source dir"); |
| 1083 | let commit_hash = create_test_repo_with_commit(source_dir.path(), CommitVariant::StateTest) | 1107 | let commit_hash = create_test_repo_with_commit(source_dir.path(), CommitVariant::StateTest) |
diff --git a/tests/common/mock_relay.rs b/tests/common/mock_relay.rs index b6376a7..e81c453 100644 --- a/tests/common/mock_relay.rs +++ b/tests/common/mock_relay.rs | |||
| @@ -73,8 +73,8 @@ impl MockRelay { | |||
| 73 | /// in an in-memory database. | 73 | /// in an in-memory database. |
| 74 | pub async fn start() -> Self { | 74 | pub async fn start() -> Self { |
| 75 | // Create and bind listener (eliminates port race condition) | 75 | // Create and bind listener (eliminates port race condition) |
| 76 | let std_listener = std::net::TcpListener::bind("127.0.0.1:0") | 76 | let std_listener = |
| 77 | .expect("Failed to bind to random port"); | 77 | std::net::TcpListener::bind("127.0.0.1:0").expect("Failed to bind to random port"); |
| 78 | let port = std_listener | 78 | let port = std_listener |
| 79 | .local_addr() | 79 | .local_addr() |
| 80 | .expect("Failed to get local addr") | 80 | .expect("Failed to get local addr") |
| @@ -84,8 +84,8 @@ impl MockRelay { | |||
| 84 | std_listener | 84 | std_listener |
| 85 | .set_nonblocking(true) | 85 | .set_nonblocking(true) |
| 86 | .expect("Failed to set non-blocking"); | 86 | .expect("Failed to set non-blocking"); |
| 87 | let listener = TcpListener::from_std(std_listener) | 87 | let listener = |
| 88 | .expect("Failed to convert to tokio listener"); | 88 | TcpListener::from_std(std_listener).expect("Failed to convert to tokio listener"); |
| 89 | 89 | ||
| 90 | Self::start_with_listener(listener, port).await | 90 | Self::start_with_listener(listener, port).await |
| 91 | } | 91 | } |
| @@ -258,7 +258,10 @@ fn derive_accept_key(request_key: &[u8]) -> String { | |||
| 258 | engine.input(request_key); | 258 | engine.input(request_key); |
| 259 | engine.input(WS_GUID); | 259 | engine.input(WS_GUID); |
| 260 | let hash = Sha1Hash::from_engine(engine); | 260 | let hash = Sha1Hash::from_engine(engine); |
| 261 | base64::Engine::encode(&base64::engine::general_purpose::STANDARD, hash.as_byte_array()) | 261 | base64::Engine::encode( |
| 262 | &base64::engine::general_purpose::STANDARD, | ||
| 263 | hash.as_byte_array(), | ||
| 264 | ) | ||
| 262 | } | 265 | } |
| 263 | 266 | ||
| 264 | /// Wait for the server to be ready to accept connections. | 267 | /// Wait for the server to be ready to accept connections. |
| @@ -275,10 +278,7 @@ async fn wait_for_server_ready(port: u16) { | |||
| 275 | } | 278 | } |
| 276 | Err(_) => { | 279 | Err(_) => { |
| 277 | if attempt == max_attempts - 1 { | 280 | if attempt == max_attempts - 1 { |
| 278 | panic!( | 281 | panic!("MockRelay failed to start after {} attempts", max_attempts); |
| 279 | "MockRelay failed to start after {} attempts", | ||
| 280 | max_attempts | ||
| 281 | ); | ||
| 282 | } | 282 | } |
| 283 | tokio::time::sleep(delay).await; | 283 | tokio::time::sleep(delay).await; |
| 284 | } | 284 | } |
| @@ -309,7 +309,10 @@ mod tests { | |||
| 309 | // Create a client and connect | 309 | // Create a client and connect |
| 310 | let keys = Keys::generate(); | 310 | let keys = Keys::generate(); |
| 311 | let client = Client::new(keys.clone()); | 311 | let client = Client::new(keys.clone()); |
| 312 | client.add_relay(mock.url()).await.expect("Failed to add relay"); | 312 | client |
| 313 | .add_relay(mock.url()) | ||
| 314 | .await | ||
| 315 | .expect("Failed to add relay"); | ||
| 313 | client.connect().await; | 316 | client.connect().await; |
| 314 | 317 | ||
| 315 | // Wait for connection | 318 | // Wait for connection |
diff --git a/tests/common/purgatory_helpers.rs b/tests/common/purgatory_helpers.rs index 125f485..b39982e 100644 --- a/tests/common/purgatory_helpers.rs +++ b/tests/common/purgatory_helpers.rs | |||
| @@ -51,7 +51,7 @@ pub fn create_test_repo_with_commit(path: &Path, variant: CommitVariant) -> Resu | |||
| 51 | // Configure git user for commits | 51 | // Configure git user for commits |
| 52 | run_git(path, &["config", "user.email", "test@example.com"])?; | 52 | run_git(path, &["config", "user.email", "test@example.com"])?; |
| 53 | run_git(path, &["config", "user.name", "Test User"])?; | 53 | run_git(path, &["config", "user.name", "Test User"])?; |
| 54 | 54 | ||
| 55 | // Disable GPG signing for tests (prevents yubikey prompts) | 55 | // Disable GPG signing for tests (prevents yubikey prompts) |
| 56 | run_git(path, &["config", "commit.gpgsign", "false"])?; | 56 | run_git(path, &["config", "commit.gpgsign", "false"])?; |
| 57 | run_git(path, &["config", "tag.gpgsign", "false"])?; | 57 | run_git(path, &["config", "tag.gpgsign", "false"])?; |
| @@ -710,7 +710,8 @@ mod tests { | |||
| 710 | // Check d-tag | 710 | // Check d-tag |
| 711 | let has_d_tag = event.tags.iter().any(|tag| { | 711 | let has_d_tag = event.tags.iter().any(|tag| { |
| 712 | let slice = tag.as_slice(); | 712 | let slice = tag.as_slice(); |
| 713 | slice.first().is_some_and(|t| t == "d") && slice.get(1).is_some_and(|v| v == "test-repo") | 713 | slice.first().is_some_and(|t| t == "d") |
| 714 | && slice.get(1).is_some_and(|v| v == "test-repo") | ||
| 714 | }); | 715 | }); |
| 715 | assert!(has_d_tag, "Event should have 'd' tag with identifier"); | 716 | assert!(has_d_tag, "Event should have 'd' tag with identifier"); |
| 716 | 717 | ||
| @@ -751,7 +752,8 @@ mod tests { | |||
| 751 | // Check a-tag | 752 | // Check a-tag |
| 752 | let has_a_tag = event.tags.iter().any(|tag| { | 753 | let has_a_tag = event.tags.iter().any(|tag| { |
| 753 | let slice = tag.as_slice(); | 754 | let slice = tag.as_slice(); |
| 754 | slice.first().is_some_and(|t| t == "a") && slice.get(1).is_some_and(|v| v == &repo_coord) | 755 | slice.first().is_some_and(|t| t == "a") |
| 756 | && slice.get(1).is_some_and(|v| v == &repo_coord) | ||
| 755 | }); | 757 | }); |
| 756 | assert!(has_a_tag, "Event should have 'a' tag"); | 758 | assert!(has_a_tag, "Event should have 'a' tag"); |
| 757 | 759 | ||
| @@ -806,7 +808,10 @@ mod tests { | |||
| 806 | &repo_coord, | 808 | &repo_coord, |
| 807 | "abc123def456", | 809 | "abc123def456", |
| 808 | "Test PR with clone", | 810 | "Test PR with clone", |
| 809 | &["http://fork-server.com/repo.git", "http://another-server.com/repo.git"], | 811 | &[ |
| 812 | "http://fork-server.com/repo.git", | ||
| 813 | "http://another-server.com/repo.git", | ||
| 814 | ], | ||
| 810 | ) | 815 | ) |
| 811 | .expect("Failed to create PR event with clone"); | 816 | .expect("Failed to create PR event with clone"); |
| 812 | 817 | ||
| @@ -815,7 +820,8 @@ mod tests { | |||
| 815 | // Check a-tag | 820 | // Check a-tag |
| 816 | let has_a_tag = event.tags.iter().any(|tag| { | 821 | let has_a_tag = event.tags.iter().any(|tag| { |
| 817 | let slice = tag.as_slice(); | 822 | let slice = tag.as_slice(); |
| 818 | slice.first().is_some_and(|t| t == "a") && slice.get(1).is_some_and(|v| v == &repo_coord) | 823 | slice.first().is_some_and(|t| t == "a") |
| 824 | && slice.get(1).is_some_and(|v| v == &repo_coord) | ||
| 819 | }); | 825 | }); |
| 820 | assert!(has_a_tag, "Event should have 'a' tag"); | 826 | assert!(has_a_tag, "Event should have 'a' tag"); |
| 821 | 827 | ||
| @@ -831,8 +837,12 @@ mod tests { | |||
| 831 | let has_clone_tag = event.tags.iter().any(|tag| { | 837 | let has_clone_tag = event.tags.iter().any(|tag| { |
| 832 | let slice = tag.as_slice(); | 838 | let slice = tag.as_slice(); |
| 833 | slice.first().is_some_and(|t| t == "clone") | 839 | slice.first().is_some_and(|t| t == "clone") |
| 834 | && slice.get(1).is_some_and(|v| v == "http://fork-server.com/repo.git") | 840 | && slice |
| 835 | && slice.get(2).is_some_and(|v| v == "http://another-server.com/repo.git") | 841 | .get(1) |
| 842 | .is_some_and(|v| v == "http://fork-server.com/repo.git") | ||
| 843 | && slice | ||
| 844 | .get(2) | ||
| 845 | .is_some_and(|v| v == "http://another-server.com/repo.git") | ||
| 836 | }); | 846 | }); |
| 837 | assert!(has_clone_tag, "Event should have 'clone' tag with URLs"); | 847 | assert!(has_clone_tag, "Event should have 'clone' tag with URLs"); |
| 838 | } | 848 | } |
| @@ -855,6 +865,9 @@ mod tests { | |||
| 855 | let slice = tag.as_slice(); | 865 | let slice = tag.as_slice(); |
| 856 | slice.first().is_some_and(|t| t == "clone") | 866 | slice.first().is_some_and(|t| t == "clone") |
| 857 | }); | 867 | }); |
| 858 | assert!(!has_clone_tag, "Event should not have 'clone' tag when no URLs provided"); | 868 | assert!( |
| 869 | !has_clone_tag, | ||
| 870 | "Event should not have 'clone' tag when no URLs provided" | ||
| 871 | ); | ||
| 859 | } | 872 | } |
| 860 | } | 873 | } |
diff --git a/tests/common/relay.rs b/tests/common/relay.rs index 8d20da6..fb5d421 100644 --- a/tests/common/relay.rs +++ b/tests/common/relay.rs | |||
| @@ -144,7 +144,10 @@ impl TestRelay { | |||
| 144 | .env("NGIT_SYNC_STARTUP_JITTER_MS", "0") // No jitter for tests | 144 | .env("NGIT_SYNC_STARTUP_JITTER_MS", "0") // No jitter for tests |
| 145 | .env("NGIT_SYNC_DISCONNECT_CHECK_INTERVAL_SECS", "1") // Fast reconnect attempts for tests | 145 | .env("NGIT_SYNC_DISCONNECT_CHECK_INTERVAL_SECS", "1") // Fast reconnect attempts for tests |
| 146 | .env("NGIT_SYNC_BASE_BACKOFF_SECS", "1") // Fast backoff for tests (1s instead of 5s default) | 146 | .env("NGIT_SYNC_BASE_BACKOFF_SECS", "1") // Fast backoff for tests (1s instead of 5s default) |
| 147 | .env("RUST_LOG", std::env::var("RUST_LOG").unwrap_or_else(|_| "info".to_string())) // Use RUST_LOG from environment or default to info | 147 | .env( |
| 148 | "RUST_LOG", | ||
| 149 | std::env::var("RUST_LOG").unwrap_or_else(|_| "info".to_string()), | ||
| 150 | ) // Use RUST_LOG from environment or default to info | ||
| 148 | .stdout(Stdio::null()) // Suppress stdout for cleaner test output | 151 | .stdout(Stdio::null()) // Suppress stdout for cleaner test output |
| 149 | .stderr(Stdio::null()); // Suppress stderr for cleaner test output | 152 | .stderr(Stdio::null()); // Suppress stderr for cleaner test output |
| 150 | 153 | ||