diff options
Diffstat (limited to 'src/nostr/events.rs')
| -rw-r--r-- | src/nostr/events.rs | 113 |
1 files changed, 111 insertions, 2 deletions
diff --git a/src/nostr/events.rs b/src/nostr/events.rs index 66808cc..9d43ca3 100644 --- a/src/nostr/events.rs +++ b/src/nostr/events.rs | |||
| @@ -143,14 +143,29 @@ impl RepositoryAnnouncement { | |||
| 143 | }) | 143 | }) |
| 144 | } | 144 | } |
| 145 | 145 | ||
| 146 | /// Normalize a URL by removing trailing slashes for consistent comparison | ||
| 147 | /// | ||
| 148 | /// See test_validate_announcement_with_trailing_slash_in_relay for why we need this | ||
| 149 | fn normalize_url_for_comparison(url: &str) -> &str { | ||
| 150 | url.trim_end_matches('/') | ||
| 151 | } | ||
| 152 | |||
| 146 | /// Check if this announcement lists the given domain in clone URLs | 153 | /// Check if this announcement lists the given domain in clone URLs |
| 147 | pub fn has_clone_url(&self, domain: &str) -> bool { | 154 | pub fn has_clone_url(&self, domain: &str) -> bool { |
| 148 | self.clone_urls.iter().any(|url| url.contains(domain)) | 155 | let normalized_domain = Self::normalize_url_for_comparison(domain); |
| 156 | self.clone_urls.iter().any(|url| { | ||
| 157 | let normalized_url = Self::normalize_url_for_comparison(url); | ||
| 158 | normalized_url.contains(normalized_domain) | ||
| 159 | }) | ||
| 149 | } | 160 | } |
| 150 | 161 | ||
| 151 | /// Check if this announcement lists the given relay | 162 | /// Check if this announcement lists the given relay |
| 152 | pub fn has_relay(&self, relay: &str) -> bool { | 163 | pub fn has_relay(&self, relay: &str) -> bool { |
| 153 | self.relays.iter().any(|r| r.contains(relay)) | 164 | let normalized_relay = Self::normalize_url_for_comparison(relay); |
| 165 | self.relays.iter().any(|r| { | ||
| 166 | let normalized_r = Self::normalize_url_for_comparison(r); | ||
| 167 | normalized_r.contains(normalized_relay) | ||
| 168 | }) | ||
| 154 | } | 169 | } |
| 155 | 170 | ||
| 156 | /// Check if this announcement lists the service (both clone and relay) | 171 | /// Check if this announcement lists the service (both clone and relay) |
| @@ -787,4 +802,98 @@ mod tests { | |||
| 787 | // HEAD points to develop but only main branch exists in state | 802 | // HEAD points to develop but only main branch exists in state |
| 788 | assert!(!state.head_commit_available()); | 803 | assert!(!state.head_commit_available()); |
| 789 | } | 804 | } |
| 805 | |||
| 806 | #[test] | ||
| 807 | fn test_validate_announcement_with_trailing_slash_in_relay() { | ||
| 808 | let keys = create_test_keys(); | ||
| 809 | let event = create_announcement_event( | ||
| 810 | &keys, | ||
| 811 | "test-repo", | ||
| 812 | vec!["https://git.shakespeare.diy/alice/test-repo.git"], | ||
| 813 | vec!["wss://git.shakespeare.diy/"], // Trailing slash in relay | ||
| 814 | ); | ||
| 815 | |||
| 816 | // Should accept despite trailing slash mismatch | ||
| 817 | let result = validate_announcement(&event, "git.shakespeare.diy"); | ||
| 818 | assert!(result.is_ok()); | ||
| 819 | } | ||
| 820 | |||
| 821 | #[test] | ||
| 822 | fn test_validate_announcement_with_trailing_slash_in_clone_url() { | ||
| 823 | let keys = create_test_keys(); | ||
| 824 | let event = create_announcement_event( | ||
| 825 | &keys, | ||
| 826 | "test-repo", | ||
| 827 | vec!["https://git.shakespeare.diy/"], // Trailing slash in clone URL | ||
| 828 | vec!["wss://git.shakespeare.diy"], | ||
| 829 | ); | ||
| 830 | |||
| 831 | // Should accept despite trailing slash mismatch | ||
| 832 | let result = validate_announcement(&event, "git.shakespeare.diy"); | ||
| 833 | assert!(result.is_ok()); | ||
| 834 | } | ||
| 835 | |||
| 836 | #[test] | ||
| 837 | fn test_validate_announcement_with_trailing_slash_in_both() { | ||
| 838 | let keys = create_test_keys(); | ||
| 839 | let event = create_announcement_event( | ||
| 840 | &keys, | ||
| 841 | "test-repo", | ||
| 842 | vec!["https://git.shakespeare.diy/alice/test-repo.git/"], // Trailing slash | ||
| 843 | vec!["wss://git.shakespeare.diy/"], // Trailing slash | ||
| 844 | ); | ||
| 845 | |||
| 846 | // Should accept with trailing slashes in both | ||
| 847 | let result = validate_announcement(&event, "git.shakespeare.diy"); | ||
| 848 | assert!(result.is_ok()); | ||
| 849 | } | ||
| 850 | |||
| 851 | #[test] | ||
| 852 | fn test_validate_announcement_domain_with_trailing_slash() { | ||
| 853 | let keys = create_test_keys(); | ||
| 854 | let event = create_announcement_event( | ||
| 855 | &keys, | ||
| 856 | "test-repo", | ||
| 857 | vec!["https://gitnostr.com/alice/test-repo.git"], | ||
| 858 | vec!["wss://gitnostr.com"], | ||
| 859 | ); | ||
| 860 | |||
| 861 | // Should accept even when domain parameter has trailing slash | ||
| 862 | let result = validate_announcement(&event, "gitnostr.com/"); | ||
| 863 | assert!(result.is_ok()); | ||
| 864 | } | ||
| 865 | |||
| 866 | #[test] | ||
| 867 | fn test_has_clone_url_with_trailing_slashes() { | ||
| 868 | let keys = create_test_keys(); | ||
| 869 | let event = create_announcement_event( | ||
| 870 | &keys, | ||
| 871 | "test-repo", | ||
| 872 | vec!["https://example.com/repo.git/"], | ||
| 873 | vec!["wss://example.com"], | ||
| 874 | ); | ||
| 875 | |||
| 876 | let announcement = RepositoryAnnouncement::from_event(event).unwrap(); | ||
| 877 | |||
| 878 | // Should match with or without trailing slash | ||
| 879 | assert!(announcement.has_clone_url("example.com")); | ||
| 880 | assert!(announcement.has_clone_url("example.com/")); | ||
| 881 | } | ||
| 882 | |||
| 883 | #[test] | ||
| 884 | fn test_has_relay_with_trailing_slashes() { | ||
| 885 | let keys = create_test_keys(); | ||
| 886 | let event = create_announcement_event( | ||
| 887 | &keys, | ||
| 888 | "test-repo", | ||
| 889 | vec!["https://example.com/repo.git"], | ||
| 890 | vec!["wss://example.com/"], | ||
| 891 | ); | ||
| 892 | |||
| 893 | let announcement = RepositoryAnnouncement::from_event(event).unwrap(); | ||
| 894 | |||
| 895 | // Should match with or without trailing slash | ||
| 896 | assert!(announcement.has_relay("example.com")); | ||
| 897 | assert!(announcement.has_relay("example.com/")); | ||
| 898 | } | ||
| 790 | } | 899 | } |