diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2025-11-26 08:45:16 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2025-11-26 09:56:44 +0000 |
| commit | a6edb42dfc653b6826b59b7f296e0d0c4ee74557 (patch) | |
| tree | 4355445d8d51672cbf1dd86af0a4bd2ffcde1a7a /grasp-audit/src/audit.rs | |
| parent | 30411a938d072a59d68815c975735d40366ad874 (diff) | |
fix: parsing maintainers from announcement event
Diffstat (limited to 'grasp-audit/src/audit.rs')
| -rw-r--r-- | grasp-audit/src/audit.rs | 78 |
1 files changed, 75 insertions, 3 deletions
diff --git a/grasp-audit/src/audit.rs b/grasp-audit/src/audit.rs index 5e84409..b97ddb6 100644 --- a/grasp-audit/src/audit.rs +++ b/grasp-audit/src/audit.rs | |||
| @@ -129,6 +129,7 @@ pub struct AuditEventBuilder { | |||
| 129 | content: String, | 129 | content: String, |
| 130 | tags: Vec<Tag>, | 130 | tags: Vec<Tag>, |
| 131 | config: AuditConfig, | 131 | config: AuditConfig, |
| 132 | custom_timestamp: Option<Timestamp>, | ||
| 132 | } | 133 | } |
| 133 | 134 | ||
| 134 | impl AuditEventBuilder { | 135 | impl AuditEventBuilder { |
| @@ -139,6 +140,7 @@ impl AuditEventBuilder { | |||
| 139 | content: content.into(), | 140 | content: content.into(), |
| 140 | tags: Vec::new(), | 141 | tags: Vec::new(), |
| 141 | config, | 142 | config, |
| 143 | custom_timestamp: None, | ||
| 142 | } | 144 | } |
| 143 | } | 145 | } |
| 144 | 146 | ||
| @@ -154,14 +156,49 @@ impl AuditEventBuilder { | |||
| 154 | self | 156 | self |
| 155 | } | 157 | } |
| 156 | 158 | ||
| 159 | /// Set a custom timestamp for the event | ||
| 160 | /// | ||
| 161 | /// By default, events use the current time. Use this method to create | ||
| 162 | /// events with a specific timestamp, which is useful for testing | ||
| 163 | /// timestamp-based prioritization logic. | ||
| 164 | /// | ||
| 165 | /// # Example | ||
| 166 | /// | ||
| 167 | /// ```rust | ||
| 168 | /// use nostr_sdk::prelude::*; | ||
| 169 | /// use grasp_audit::{AuditConfig, AuditEventBuilder}; | ||
| 170 | /// | ||
| 171 | /// let config = AuditConfig::ci(); | ||
| 172 | /// let keys = Keys::generate(); | ||
| 173 | /// | ||
| 174 | /// // Create an event with a past timestamp | ||
| 175 | /// let past_event = AuditEventBuilder::new(Kind::TextNote, "test", config) | ||
| 176 | /// .custom_time(Timestamp::from(1700000000)) | ||
| 177 | /// .build(&keys) | ||
| 178 | /// .unwrap(); | ||
| 179 | /// | ||
| 180 | /// assert_eq!(past_event.created_at, Timestamp::from(1700000000)); | ||
| 181 | /// ``` | ||
| 182 | pub fn custom_time(mut self, timestamp: Timestamp) -> Self { | ||
| 183 | self.custom_timestamp = Some(timestamp); | ||
| 184 | self | ||
| 185 | } | ||
| 186 | |||
| 157 | /// Build the event with audit tags | 187 | /// Build the event with audit tags |
| 158 | pub fn build(self, keys: &Keys) -> anyhow::Result<Event> { | 188 | pub fn build(self, keys: &Keys) -> anyhow::Result<Event> { |
| 159 | let mut all_tags = self.tags; | 189 | let mut all_tags = self.tags; |
| 160 | all_tags.extend(self.config.audit_tags()); | 190 | all_tags.extend(self.config.audit_tags()); |
| 161 | 191 | ||
| 162 | let event = EventBuilder::new(self.kind, self.content) | 192 | let builder = EventBuilder::new(self.kind, self.content).tags(all_tags); |
| 163 | .tags(all_tags) | 193 | |
| 164 | .sign_with_keys(keys)?; | 194 | // Apply custom timestamp if set |
| 195 | let builder = if let Some(timestamp) = self.custom_timestamp { | ||
| 196 | builder.custom_created_at(timestamp) | ||
| 197 | } else { | ||
| 198 | builder | ||
| 199 | }; | ||
| 200 | |||
| 201 | let event = builder.sign_with_keys(keys)?; | ||
| 165 | 202 | ||
| 166 | Ok(event) | 203 | Ok(event) |
| 167 | } | 204 | } |
| @@ -243,4 +280,39 @@ mod tests { | |||
| 243 | // Verify event is valid | 280 | // Verify event is valid |
| 244 | assert!(event.verify().is_ok()); | 281 | assert!(event.verify().is_ok()); |
| 245 | } | 282 | } |
| 283 | |||
| 284 | #[test] | ||
| 285 | fn test_custom_timestamp_applied() { | ||
| 286 | let config = AuditConfig::ci(); | ||
| 287 | let keys = Keys::generate(); | ||
| 288 | let custom_ts = Timestamp::from(1700000000); | ||
| 289 | |||
| 290 | // Build event with custom timestamp | ||
| 291 | let event = AuditEventBuilder::new(Kind::TextNote, "test with custom time", config.clone()) | ||
| 292 | .custom_time(custom_ts) | ||
| 293 | .build(&keys) | ||
| 294 | .unwrap(); | ||
| 295 | |||
| 296 | // Verify the custom timestamp was applied | ||
| 297 | assert_eq!(event.created_at, custom_ts); | ||
| 298 | |||
| 299 | // Verify event is still valid | ||
| 300 | assert!(event.verify().is_ok()); | ||
| 301 | } | ||
| 302 | |||
| 303 | #[test] | ||
| 304 | fn test_default_timestamp_uses_current_time() { | ||
| 305 | let config = AuditConfig::ci(); | ||
| 306 | let keys = Keys::generate(); | ||
| 307 | |||
| 308 | let before = Timestamp::now(); | ||
| 309 | let event = AuditEventBuilder::new(Kind::TextNote, "test default time", config.clone()) | ||
| 310 | .build(&keys) | ||
| 311 | .unwrap(); | ||
| 312 | let after = Timestamp::now(); | ||
| 313 | |||
| 314 | // Event timestamp should be between before and after (inclusive) | ||
| 315 | assert!(event.created_at.as_u64() >= before.as_u64()); | ||
| 316 | assert!(event.created_at.as_u64() <= after.as_u64()); | ||
| 317 | } | ||
| 246 | } | 318 | } |