diff options
Diffstat (limited to 'tests/common/purgatory_helpers.rs')
| -rw-r--r-- | tests/common/purgatory_helpers.rs | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/tests/common/purgatory_helpers.rs b/tests/common/purgatory_helpers.rs index 7d8e908..fa1be73 100644 --- a/tests/common/purgatory_helpers.rs +++ b/tests/common/purgatory_helpers.rs | |||
| @@ -271,6 +271,60 @@ pub fn create_pr_event( | |||
| 271 | .map_err(|e| format!("Failed to sign PR event: {}", e)) | 271 | .map_err(|e| format!("Failed to sign PR event: {}", e)) |
| 272 | } | 272 | } |
| 273 | 273 | ||
| 274 | /// Create a PR event (kind 1618) with clone URLs. | ||
| 275 | /// | ||
| 276 | /// Creates a properly formatted NIP-34 PR event that references a repository | ||
| 277 | /// via an `a` tag, includes the commit hash via a `c` tag, and specifies | ||
| 278 | /// clone URLs where the PR commit can be fetched from. | ||
| 279 | /// | ||
| 280 | /// Per NIP-34, PR events can include a `clone` tag: | ||
| 281 | /// ```jsonc | ||
| 282 | /// { | ||
| 283 | /// "kind": 1618, | ||
| 284 | /// "tags": [ | ||
| 285 | /// ["c", "<current-commit-id>"], | ||
| 286 | /// ["clone", "<clone-url>", ...], // at least one git clone url where commit can be downloaded | ||
| 287 | /// // ... | ||
| 288 | /// ] | ||
| 289 | /// } | ||
| 290 | /// ``` | ||
| 291 | /// | ||
| 292 | /// # Arguments | ||
| 293 | /// * `keys` - Keys for signing | ||
| 294 | /// * `repo_coord` - Repository coordinate (format: "30617:pubkey_hex:identifier") | ||
| 295 | /// * `commit_hash` - The commit hash (c-tag) | ||
| 296 | /// * `title` - PR title (used as content) | ||
| 297 | /// * `clone_urls` - Clone URLs where the PR commit can be fetched | ||
| 298 | /// | ||
| 299 | /// # Returns | ||
| 300 | /// * `Ok(Event)` - Signed PR event ready to send | ||
| 301 | /// * `Err(String)` - If signing fails | ||
| 302 | pub fn create_pr_event_with_clone( | ||
| 303 | keys: &Keys, | ||
| 304 | repo_coord: &str, | ||
| 305 | commit_hash: &str, | ||
| 306 | title: &str, | ||
| 307 | clone_urls: &[&str], | ||
| 308 | ) -> Result<Event, String> { | ||
| 309 | let mut tags = vec![ | ||
| 310 | // a-tag referencing the repository | ||
| 311 | Tag::custom(TagKind::custom("a"), vec![repo_coord.to_string()]), | ||
| 312 | // c-tag with the commit hash | ||
| 313 | Tag::custom(TagKind::custom("c"), vec![commit_hash.to_string()]), | ||
| 314 | ]; | ||
| 315 | |||
| 316 | // Add clone URLs if provided | ||
| 317 | if !clone_urls.is_empty() { | ||
| 318 | let urls: Vec<String> = clone_urls.iter().map(|s| s.to_string()).collect(); | ||
| 319 | tags.push(Tag::custom(TagKind::Clone, urls)); | ||
| 320 | } | ||
| 321 | |||
| 322 | EventBuilder::new(Kind::Custom(KIND_PR), title) | ||
| 323 | .tags(tags) | ||
| 324 | .sign_with_keys(keys) | ||
| 325 | .map_err(|e| format!("Failed to sign PR event: {}", e)) | ||
| 326 | } | ||
| 327 | |||
| 274 | /// Build a repository coordinate string for use in 'a' tags. | 328 | /// Build a repository coordinate string for use in 'a' tags. |
| 275 | /// | 329 | /// |
| 276 | /// Format: `30617:pubkey_hex:identifier` | 330 | /// Format: `30617:pubkey_hex:identifier` |
| @@ -738,4 +792,65 @@ mod tests { | |||
| 738 | let branch_commit = String::from_utf8_lossy(&output.stdout).trim().to_string(); | 792 | let branch_commit = String::from_utf8_lossy(&output.stdout).trim().to_string(); |
| 739 | assert_eq!(branch_commit, commit_hash); | 793 | assert_eq!(branch_commit, commit_hash); |
| 740 | } | 794 | } |
| 795 | |||
| 796 | #[test] | ||
| 797 | fn test_create_pr_event_with_clone_has_correct_tags() { | ||
| 798 | let keys = Keys::generate(); | ||
| 799 | let repo_coord = build_repo_coord(&keys, "test-repo"); | ||
| 800 | let event = create_pr_event_with_clone( | ||
| 801 | &keys, | ||
| 802 | &repo_coord, | ||
| 803 | "abc123def456", | ||
| 804 | "Test PR with clone", | ||
| 805 | &["http://fork-server.com/repo.git", "http://another-server.com/repo.git"], | ||
| 806 | ) | ||
| 807 | .expect("Failed to create PR event with clone"); | ||
| 808 | |||
| 809 | assert_eq!(event.kind.as_u16(), KIND_PR); | ||
| 810 | |||
| 811 | // Check a-tag | ||
| 812 | let has_a_tag = event.tags.iter().any(|tag| { | ||
| 813 | let slice = tag.as_slice(); | ||
| 814 | slice.first().is_some_and(|t| t == "a") && slice.get(1).is_some_and(|v| v == &repo_coord) | ||
| 815 | }); | ||
| 816 | assert!(has_a_tag, "Event should have 'a' tag"); | ||
| 817 | |||
| 818 | // Check c-tag | ||
| 819 | let has_c_tag = event.tags.iter().any(|tag| { | ||
| 820 | let slice = tag.as_slice(); | ||
| 821 | slice.first().is_some_and(|t| t == "c") | ||
| 822 | && slice.get(1).is_some_and(|v| v == "abc123def456") | ||
| 823 | }); | ||
| 824 | assert!(has_c_tag, "Event should have 'c' tag with commit"); | ||
| 825 | |||
| 826 | // Check clone tag with both URLs | ||
| 827 | let has_clone_tag = event.tags.iter().any(|tag| { | ||
| 828 | let slice = tag.as_slice(); | ||
| 829 | slice.first().is_some_and(|t| t == "clone") | ||
| 830 | && slice.get(1).is_some_and(|v| v == "http://fork-server.com/repo.git") | ||
| 831 | && slice.get(2).is_some_and(|v| v == "http://another-server.com/repo.git") | ||
| 832 | }); | ||
| 833 | assert!(has_clone_tag, "Event should have 'clone' tag with URLs"); | ||
| 834 | } | ||
| 835 | |||
| 836 | #[test] | ||
| 837 | fn test_create_pr_event_with_clone_empty_urls() { | ||
| 838 | let keys = Keys::generate(); | ||
| 839 | let repo_coord = build_repo_coord(&keys, "test-repo"); | ||
| 840 | let event = create_pr_event_with_clone( | ||
| 841 | &keys, | ||
| 842 | &repo_coord, | ||
| 843 | "abc123def456", | ||
| 844 | "Test PR without clone URLs", | ||
| 845 | &[], // Empty clone URLs | ||
| 846 | ) | ||
| 847 | .expect("Failed to create PR event"); | ||
| 848 | |||
| 849 | // Should not have clone tag when no URLs provided | ||
| 850 | let has_clone_tag = event.tags.iter().any(|tag| { | ||
| 851 | let slice = tag.as_slice(); | ||
| 852 | slice.first().is_some_and(|t| t == "clone") | ||
| 853 | }); | ||
| 854 | assert!(!has_clone_tag, "Event should not have 'clone' tag when no URLs provided"); | ||
| 855 | } | ||
| 741 | } | 856 | } |