1use crate::utils::LruCache;
7use chie_shared::{ContentCategory, ContentMetadata};
8use std::path::PathBuf;
9
10#[derive(Debug)]
12pub struct ContentManager {
13 metadata_cache: LruCache<String, ContentMetadata>,
15
16 storage_path: PathBuf,
18
19 stats: ContentManagerStats,
21}
22
23#[derive(Debug, Default, Clone)]
25pub struct ContentManagerStats {
26 pub cache_hits: u64,
28
29 pub cache_misses: u64,
31
32 pub total_cached: u64,
34
35 pub total_searches: u64,
37}
38
39impl ContentManagerStats {
40 #[inline]
42 #[must_use]
43 pub fn hit_rate(&self) -> f64 {
44 let total = self.cache_hits + self.cache_misses;
45 if total == 0 {
46 0.0
47 } else {
48 self.cache_hits as f64 / total as f64
49 }
50 }
51}
52
53impl Default for ContentManager {
54 fn default() -> Self {
55 Self::new(PathBuf::from("."))
56 }
57}
58
59impl ContentManager {
60 #[must_use]
62 pub fn new(storage_path: PathBuf) -> Self {
63 Self::with_capacity(storage_path, 1000)
64 }
65
66 #[must_use]
68 pub fn with_capacity(storage_path: PathBuf, capacity: usize) -> Self {
69 Self {
70 metadata_cache: LruCache::new(capacity),
71 storage_path,
72 stats: ContentManagerStats::default(),
73 }
74 }
75
76 #[inline]
78 pub fn storage_path(&self) -> &std::path::Path {
79 &self.storage_path
80 }
81
82 #[inline]
84 pub fn cache_metadata(&mut self, cid: String, metadata: ContentMetadata) {
85 self.metadata_cache.put(cid, metadata);
86 self.stats.total_cached += 1;
87 }
88
89 #[inline]
91 pub fn get_metadata(&mut self, cid: &str) -> Option<&ContentMetadata> {
92 let result = self.metadata_cache.get(&cid.to_string());
93 if result.is_some() {
94 self.stats.cache_hits += 1;
95 } else {
96 self.stats.cache_misses += 1;
97 }
98 result
99 }
100
101 #[inline]
103 pub fn peek_metadata(&self, cid: &str) -> Option<&ContentMetadata> {
104 self.metadata_cache.peek(&cid.to_string())
105 }
106
107 #[inline]
109 pub fn remove_metadata(&mut self, cid: &str) -> Option<ContentMetadata> {
110 self.metadata_cache.remove(&cid.to_string())
111 }
112
113 #[inline]
115 pub fn clear_cache(&mut self) {
116 self.metadata_cache.clear();
117 }
118
119 #[inline]
121 pub fn cached_count(&self) -> usize {
122 self.metadata_cache.len()
123 }
124
125 #[inline]
127 pub fn total_storage_used(&self) -> u64 {
128 self.metadata_cache.iter().map(|(_, m)| m.size_bytes).sum()
129 }
130
131 #[inline]
133 pub fn stats(&self) -> &ContentManagerStats {
134 &self.stats
135 }
136
137 #[inline]
139 pub fn reset_stats(&mut self) {
140 self.stats = ContentManagerStats::default();
141 }
142
143 #[inline]
145 pub fn search_by_category(&mut self, category: ContentCategory) -> Vec<&ContentMetadata> {
146 self.stats.total_searches += 1;
147 self.metadata_cache
148 .iter()
149 .filter(|(_, metadata)| metadata.category == category)
150 .map(|(_, metadata)| metadata)
151 .collect()
152 }
153
154 #[inline]
156 pub fn search_by_tag(&mut self, tag: &str) -> Vec<&ContentMetadata> {
157 self.stats.total_searches += 1;
158 self.metadata_cache
159 .iter()
160 .filter(|(_, metadata)| metadata.tags.iter().any(|t| t == tag))
161 .map(|(_, metadata)| metadata)
162 .collect()
163 }
164
165 #[inline]
167 pub fn search_by_text(&mut self, query: &str) -> Vec<&ContentMetadata> {
168 self.stats.total_searches += 1;
169 let query_lower = query.to_lowercase();
170 self.metadata_cache
171 .iter()
172 .filter(|(_, metadata)| {
173 metadata.title.to_lowercase().contains(&query_lower)
174 || metadata.description.to_lowercase().contains(&query_lower)
175 })
176 .map(|(_, metadata)| metadata)
177 .collect()
178 }
179
180 pub fn get_largest_content(&self, limit: usize) -> Vec<&ContentMetadata> {
182 let mut content: Vec<_> = self.metadata_cache.iter().map(|(_, m)| m).collect();
183 content.sort_by(|a, b| b.size_bytes.cmp(&a.size_bytes));
184 content.into_iter().take(limit).collect()
185 }
186
187 pub fn get_newest_content(&self, limit: usize) -> Vec<&ContentMetadata> {
189 let mut content: Vec<_> = self.metadata_cache.iter().map(|(_, m)| m).collect();
190 content.sort_by(|a, b| b.created_at.cmp(&a.created_at));
191 content.into_iter().take(limit).collect()
192 }
193
194 #[inline]
196 pub fn has_metadata(&self, cid: &str) -> bool {
197 self.metadata_cache.peek(&cid.to_string()).is_some()
198 }
199
200 pub fn get_multiple(&mut self, cids: &[String]) -> Vec<String> {
204 cids.iter()
205 .filter(|cid| self.get_metadata(cid).is_some())
206 .cloned()
207 .collect()
208 }
209
210 pub fn cache_batch(&mut self, items: Vec<(String, ContentMetadata)>) {
214 let count = items.len() as u64;
215 for (cid, metadata) in items {
216 self.metadata_cache.put(cid, metadata);
217 }
218 self.stats.total_cached += count;
219 }
220
221 pub fn remove_batch(&mut self, cids: &[String]) -> usize {
225 cids.iter()
226 .filter_map(|cid| self.metadata_cache.remove(&cid.to_string()))
227 .count()
228 }
229
230 pub fn search_filtered(
234 &mut self,
235 category: Option<ContentCategory>,
236 tag: Option<&str>,
237 min_size: Option<u64>,
238 max_size: Option<u64>,
239 ) -> Vec<&ContentMetadata> {
240 self.stats.total_searches += 1;
241 self.metadata_cache
242 .iter()
243 .filter(|(_, metadata)| {
244 if let Some(cat) = category {
246 if metadata.category != cat {
247 return false;
248 }
249 }
250
251 if let Some(t) = tag {
253 if !metadata.tags.iter().any(|tag| tag == t) {
254 return false;
255 }
256 }
257
258 if let Some(min) = min_size {
260 if metadata.size_bytes < min {
261 return false;
262 }
263 }
264 if let Some(max) = max_size {
265 if metadata.size_bytes > max {
266 return false;
267 }
268 }
269
270 true
271 })
272 .map(|(_, metadata)| metadata)
273 .collect()
274 }
275
276 pub fn search_by_price_range(
278 &mut self,
279 min_price: u64,
280 max_price: u64,
281 ) -> Vec<&ContentMetadata> {
282 self.stats.total_searches += 1;
283 self.metadata_cache
284 .iter()
285 .filter(|(_, metadata)| metadata.price >= min_price && metadata.price <= max_price)
286 .map(|(_, metadata)| metadata)
287 .collect()
288 }
289
290 pub fn search_by_size_range(
292 &mut self,
293 min_bytes: u64,
294 max_bytes: u64,
295 ) -> Vec<&ContentMetadata> {
296 self.stats.total_searches += 1;
297 self.metadata_cache
298 .iter()
299 .filter(|(_, metadata)| {
300 metadata.size_bytes >= min_bytes && metadata.size_bytes <= max_bytes
301 })
302 .map(|(_, metadata)| metadata)
303 .collect()
304 }
305
306 #[inline]
308 pub fn get_all_cids(&self) -> Vec<String> {
309 self.metadata_cache
310 .iter()
311 .map(|(cid, _)| cid.clone())
312 .collect()
313 }
314
315 pub fn count_by_category(&self, category: ContentCategory) -> usize {
317 self.metadata_cache
318 .iter()
319 .filter(|(_, metadata)| metadata.category == category)
320 .count()
321 }
322
323 #[inline]
325 pub fn total_content_size(&self) -> u64 {
326 self.total_storage_used()
327 }
328
329 pub fn average_content_size(&self) -> u64 {
331 let count = self.cached_count();
332 if count == 0 {
333 0
334 } else {
335 self.total_storage_used() / count as u64
336 }
337 }
338}
339
340#[cfg(test)]
341mod tests {
342 use super::*;
343 use chie_shared::{ContentCategory, ContentStatus};
344 use std::path::PathBuf;
345
346 fn create_test_metadata(cid: &str, size_bytes: u64, chunk_count: u64) -> ContentMetadata {
347 ContentMetadata {
348 id: uuid::Uuid::new_v4(),
349 cid: cid.to_string(),
350 title: format!("Test Content {}", cid),
351 description: "Test description".to_string(),
352 category: ContentCategory::ThreeDModels,
353 tags: vec!["test".to_string()],
354 size_bytes,
355 chunk_count,
356 price: 100,
357 creator_id: uuid::Uuid::new_v4(),
358 status: ContentStatus::Active,
359 preview_images: vec![],
360 created_at: chrono::Utc::now(),
361 updated_at: chrono::Utc::now(),
362 }
363 }
364
365 #[test]
366 fn test_content_manager_new() {
367 let path = PathBuf::from("/tmp/chie-test");
368 let manager = ContentManager::new(path.clone());
369
370 assert_eq!(manager.storage_path(), path.as_path());
371 assert_eq!(manager.total_storage_used(), 0);
372 }
373
374 #[test]
375 fn test_cache_and_get_metadata() {
376 let mut manager = ContentManager::new(PathBuf::from("/tmp/chie-test"));
377
378 let metadata = create_test_metadata("QmTest123", 1024, 1);
379
380 manager.cache_metadata("QmTest123".to_string(), metadata.clone());
381
382 let retrieved = manager.get_metadata("QmTest123");
383 assert!(retrieved.is_some());
384 assert_eq!(retrieved.unwrap().cid, "QmTest123");
385 assert_eq!(retrieved.unwrap().size_bytes, 1024);
386 assert_eq!(manager.stats().cache_hits, 1);
387 assert_eq!(manager.stats().cache_misses, 0);
388 }
389
390 #[test]
391 fn test_get_nonexistent_metadata() {
392 let mut manager = ContentManager::new(PathBuf::from("/tmp/chie-test"));
393
394 let result = manager.get_metadata("QmNonexistent");
395 assert!(result.is_none());
396 assert_eq!(manager.stats().cache_misses, 1);
397 }
398
399 #[test]
400 fn test_total_storage_used() {
401 let mut manager = ContentManager::new(PathBuf::from("/tmp/chie-test"));
402
403 let metadata1 = create_test_metadata("QmTest1", 1024, 1);
404 let metadata2 = create_test_metadata("QmTest2", 2048, 2);
405
406 manager.cache_metadata("QmTest1".to_string(), metadata1);
407 manager.cache_metadata("QmTest2".to_string(), metadata2);
408
409 assert_eq!(manager.total_storage_used(), 1024 + 2048);
410 }
411
412 #[test]
413 fn test_content_manager_default() {
414 let mut manager = ContentManager::default();
415
416 assert_eq!(manager.total_storage_used(), 0);
417 assert!(manager.get_metadata("any").is_none());
418 }
419
420 #[test]
421 fn test_lru_cache_eviction() {
422 let mut manager = ContentManager::with_capacity(PathBuf::from("/tmp/chie-test"), 2);
423
424 let metadata1 = create_test_metadata("QmTest1", 1024, 1);
425 let metadata2 = create_test_metadata("QmTest2", 2048, 2);
426 let metadata3 = create_test_metadata("QmTest3", 3072, 3);
427
428 manager.cache_metadata("QmTest1".to_string(), metadata1);
429 manager.cache_metadata("QmTest2".to_string(), metadata2);
430 manager.cache_metadata("QmTest3".to_string(), metadata3);
431
432 assert_eq!(manager.cached_count(), 2);
434 assert!(manager.peek_metadata("QmTest2").is_some());
435 assert!(manager.peek_metadata("QmTest3").is_some());
436 }
437
438 #[test]
439 fn test_stats_tracking() {
440 let mut manager = ContentManager::new(PathBuf::from("/tmp/chie-test"));
441
442 let metadata = create_test_metadata("QmTest", 1024, 1);
443 manager.cache_metadata("QmTest".to_string(), metadata);
444
445 assert_eq!(manager.stats().total_cached, 1);
446
447 manager.get_metadata("QmTest");
449 assert_eq!(manager.stats().cache_hits, 1);
450
451 manager.get_metadata("QmNonexistent");
453 assert_eq!(manager.stats().cache_misses, 1);
454
455 assert_eq!(manager.stats().hit_rate(), 0.5);
456
457 manager.reset_stats();
458 assert_eq!(manager.stats().cache_hits, 0);
459 assert_eq!(manager.stats().cache_misses, 0);
460 }
461
462 #[test]
463 fn test_search_by_category() {
464 let mut manager = ContentManager::new(PathBuf::from("/tmp/chie-test"));
465
466 let mut metadata1 = create_test_metadata("QmTest1", 1024, 1);
467 metadata1.category = ContentCategory::ThreeDModels;
468
469 let mut metadata2 = create_test_metadata("QmTest2", 2048, 2);
470 metadata2.category = ContentCategory::Audio;
471
472 let mut metadata3 = create_test_metadata("QmTest3", 3072, 3);
473 metadata3.category = ContentCategory::ThreeDModels;
474
475 manager.cache_metadata("QmTest1".to_string(), metadata1);
476 manager.cache_metadata("QmTest2".to_string(), metadata2);
477 manager.cache_metadata("QmTest3".to_string(), metadata3);
478
479 let results = manager.search_by_category(ContentCategory::ThreeDModels);
480 assert_eq!(results.len(), 2);
481 assert_eq!(manager.stats().total_searches, 1);
482 }
483
484 #[test]
485 fn test_search_by_tag() {
486 let mut manager = ContentManager::new(PathBuf::from("/tmp/chie-test"));
487
488 let mut metadata1 = create_test_metadata("QmTest1", 1024, 1);
489 metadata1.tags = vec!["rust".to_string(), "programming".to_string()];
490
491 let mut metadata2 = create_test_metadata("QmTest2", 2048, 2);
492 metadata2.tags = vec!["python".to_string(), "programming".to_string()];
493
494 let mut metadata3 = create_test_metadata("QmTest3", 3072, 3);
495 metadata3.tags = vec!["rust".to_string(), "web".to_string()];
496
497 manager.cache_metadata("QmTest1".to_string(), metadata1);
498 manager.cache_metadata("QmTest2".to_string(), metadata2);
499 manager.cache_metadata("QmTest3".to_string(), metadata3);
500
501 let rust_results = manager.search_by_tag("rust");
502 assert_eq!(rust_results.len(), 2);
503
504 let programming_results = manager.search_by_tag("programming");
505 assert_eq!(programming_results.len(), 2);
506 }
507
508 #[test]
509 fn test_search_by_text() {
510 let mut manager = ContentManager::new(PathBuf::from("/tmp/chie-test"));
511
512 let mut metadata1 = create_test_metadata("QmTest1", 1024, 1);
513 metadata1.title = "Rust Programming Tutorial".to_string();
514 metadata1.description = "Learn Rust from scratch".to_string();
515
516 let mut metadata2 = create_test_metadata("QmTest2", 2048, 2);
517 metadata2.title = "Python Data Science".to_string();
518 metadata2.description = "Data analysis with Python".to_string();
519
520 manager.cache_metadata("QmTest1".to_string(), metadata1);
521 manager.cache_metadata("QmTest2".to_string(), metadata2);
522
523 let rust_results = manager.search_by_text("rust");
524 assert_eq!(rust_results.len(), 1);
525 assert_eq!(rust_results[0].cid, "QmTest1");
526
527 let data_results = manager.search_by_text("data");
528 assert_eq!(data_results.len(), 1);
529 assert_eq!(data_results[0].cid, "QmTest2");
530 }
531
532 #[test]
533 fn test_get_largest_content() {
534 let mut manager = ContentManager::new(PathBuf::from("/tmp/chie-test"));
535
536 let metadata1 = create_test_metadata("QmTest1", 1024, 1);
537 let metadata2 = create_test_metadata("QmTest2", 3072, 3);
538 let metadata3 = create_test_metadata("QmTest3", 2048, 2);
539
540 manager.cache_metadata("QmTest1".to_string(), metadata1);
541 manager.cache_metadata("QmTest2".to_string(), metadata2);
542 manager.cache_metadata("QmTest3".to_string(), metadata3);
543
544 let largest = manager.get_largest_content(2);
545 assert_eq!(largest.len(), 2);
546 assert_eq!(largest[0].size_bytes, 3072);
547 assert_eq!(largest[1].size_bytes, 2048);
548 }
549
550 #[test]
551 fn test_get_newest_content() {
552 let mut manager = ContentManager::new(PathBuf::from("/tmp/chie-test"));
553
554 let mut metadata1 = create_test_metadata("QmTest1", 1024, 1);
555 metadata1.created_at = chrono::Utc::now() - chrono::Duration::days(2);
556
557 let mut metadata2 = create_test_metadata("QmTest2", 2048, 2);
558 metadata2.created_at = chrono::Utc::now();
559
560 let mut metadata3 = create_test_metadata("QmTest3", 3072, 3);
561 metadata3.created_at = chrono::Utc::now() - chrono::Duration::days(1);
562
563 manager.cache_metadata("QmTest1".to_string(), metadata1);
564 manager.cache_metadata("QmTest2".to_string(), metadata2);
565 manager.cache_metadata("QmTest3".to_string(), metadata3);
566
567 let newest = manager.get_newest_content(2);
568 assert_eq!(newest.len(), 2);
569 assert_eq!(newest[0].cid, "QmTest2");
570 assert_eq!(newest[1].cid, "QmTest3");
571 }
572
573 #[test]
574 fn test_remove_and_clear() {
575 let mut manager = ContentManager::new(PathBuf::from("/tmp/chie-test"));
576
577 let metadata1 = create_test_metadata("QmTest1", 1024, 1);
578 let metadata2 = create_test_metadata("QmTest2", 2048, 2);
579
580 manager.cache_metadata("QmTest1".to_string(), metadata1);
581 manager.cache_metadata("QmTest2".to_string(), metadata2);
582
583 assert_eq!(manager.cached_count(), 2);
584
585 let removed = manager.remove_metadata("QmTest1");
586 assert!(removed.is_some());
587 assert_eq!(manager.cached_count(), 1);
588
589 manager.clear_cache();
590 assert_eq!(manager.cached_count(), 0);
591 }
592
593 #[test]
594 fn test_has_metadata() {
595 let mut manager = ContentManager::new(PathBuf::from("/tmp/chie-test"));
596
597 let metadata = create_test_metadata("QmTest1", 1024, 1);
598 manager.cache_metadata("QmTest1".to_string(), metadata);
599
600 assert!(manager.has_metadata("QmTest1"));
601 assert!(!manager.has_metadata("QmNonexistent"));
602 }
603
604 #[test]
605 fn test_get_multiple() {
606 let mut manager = ContentManager::new(PathBuf::from("/tmp/chie-test"));
607
608 let metadata1 = create_test_metadata("QmTest1", 1024, 1);
609 let metadata2 = create_test_metadata("QmTest2", 2048, 2);
610
611 manager.cache_metadata("QmTest1".to_string(), metadata1);
612 manager.cache_metadata("QmTest2".to_string(), metadata2);
613
614 let cids = vec![
615 "QmTest1".to_string(),
616 "QmNonexistent".to_string(),
617 "QmTest2".to_string(),
618 ];
619 let found = manager.get_multiple(&cids);
620
621 assert_eq!(found.len(), 2);
623 assert!(found.contains(&"QmTest1".to_string()));
624 assert!(found.contains(&"QmTest2".to_string()));
625 }
626
627 #[test]
628 fn test_cache_batch() {
629 let mut manager = ContentManager::new(PathBuf::from("/tmp/chie-test"));
630
631 let items = vec![
632 (
633 "QmTest1".to_string(),
634 create_test_metadata("QmTest1", 1024, 1),
635 ),
636 (
637 "QmTest2".to_string(),
638 create_test_metadata("QmTest2", 2048, 2),
639 ),
640 (
641 "QmTest3".to_string(),
642 create_test_metadata("QmTest3", 3072, 3),
643 ),
644 ];
645
646 manager.cache_batch(items);
647
648 assert_eq!(manager.cached_count(), 3);
649 assert_eq!(manager.stats().total_cached, 3);
650 assert!(manager.has_metadata("QmTest1"));
651 assert!(manager.has_metadata("QmTest2"));
652 assert!(manager.has_metadata("QmTest3"));
653 }
654
655 #[test]
656 fn test_remove_batch() {
657 let mut manager = ContentManager::new(PathBuf::from("/tmp/chie-test"));
658
659 manager.cache_metadata(
660 "QmTest1".to_string(),
661 create_test_metadata("QmTest1", 1024, 1),
662 );
663 manager.cache_metadata(
664 "QmTest2".to_string(),
665 create_test_metadata("QmTest2", 2048, 2),
666 );
667 manager.cache_metadata(
668 "QmTest3".to_string(),
669 create_test_metadata("QmTest3", 3072, 3),
670 );
671
672 let to_remove = vec![
673 "QmTest1".to_string(),
674 "QmTest2".to_string(),
675 "QmNonexistent".to_string(),
676 ];
677 let removed_count = manager.remove_batch(&to_remove);
678
679 assert_eq!(removed_count, 2);
680 assert_eq!(manager.cached_count(), 1);
681 assert!(manager.has_metadata("QmTest3"));
682 assert!(!manager.has_metadata("QmTest1"));
683 }
684
685 #[test]
686 fn test_search_filtered() {
687 let mut manager = ContentManager::new(PathBuf::from("/tmp/chie-test"));
688
689 let mut metadata1 = create_test_metadata("QmTest1", 1024, 1);
690 metadata1.category = ContentCategory::ThreeDModels;
691 metadata1.tags = vec!["premium".to_string()];
692
693 let mut metadata2 = create_test_metadata("QmTest2", 2048 * 1024, 2);
694 metadata2.category = ContentCategory::ThreeDModels;
695 metadata2.tags = vec!["premium".to_string()];
696
697 let mut metadata3 = create_test_metadata("QmTest3", 5120 * 1024, 3);
698 metadata3.category = ContentCategory::Audio;
699 metadata3.tags = vec!["premium".to_string()];
700
701 manager.cache_metadata("QmTest1".to_string(), metadata1);
702 manager.cache_metadata("QmTest2".to_string(), metadata2);
703 manager.cache_metadata("QmTest3".to_string(), metadata3);
704
705 let results = manager.search_filtered(
707 Some(ContentCategory::ThreeDModels),
708 Some("premium"),
709 Some(1024 * 1024),
710 Some(10 * 1024 * 1024),
711 );
712
713 assert_eq!(results.len(), 1);
714 assert_eq!(results[0].cid, "QmTest2");
715 }
716
717 #[test]
718 fn test_search_by_price_range() {
719 let mut manager = ContentManager::new(PathBuf::from("/tmp/chie-test"));
720
721 let mut metadata1 = create_test_metadata("QmTest1", 1024, 1);
722 metadata1.price = 50;
723
724 let mut metadata2 = create_test_metadata("QmTest2", 2048, 2);
725 metadata2.price = 150;
726
727 let mut metadata3 = create_test_metadata("QmTest3", 3072, 3);
728 metadata3.price = 250;
729
730 manager.cache_metadata("QmTest1".to_string(), metadata1);
731 manager.cache_metadata("QmTest2".to_string(), metadata2);
732 manager.cache_metadata("QmTest3".to_string(), metadata3);
733
734 let results = manager.search_by_price_range(100, 200);
735 assert_eq!(results.len(), 1);
736 assert_eq!(results[0].cid, "QmTest2");
737 }
738
739 #[test]
740 fn test_search_by_size_range() {
741 let mut manager = ContentManager::new(PathBuf::from("/tmp/chie-test"));
742
743 manager.cache_metadata(
744 "QmTest1".to_string(),
745 create_test_metadata("QmTest1", 1024, 1),
746 );
747 manager.cache_metadata(
748 "QmTest2".to_string(),
749 create_test_metadata("QmTest2", 2048, 2),
750 );
751 manager.cache_metadata(
752 "QmTest3".to_string(),
753 create_test_metadata("QmTest3", 5120, 5),
754 );
755
756 let results = manager.search_by_size_range(2000, 3000);
757 assert_eq!(results.len(), 1);
758 assert_eq!(results[0].cid, "QmTest2");
759 }
760
761 #[test]
762 fn test_get_all_cids() {
763 let mut manager = ContentManager::new(PathBuf::from("/tmp/chie-test"));
764
765 manager.cache_metadata(
766 "QmTest1".to_string(),
767 create_test_metadata("QmTest1", 1024, 1),
768 );
769 manager.cache_metadata(
770 "QmTest2".to_string(),
771 create_test_metadata("QmTest2", 2048, 2),
772 );
773
774 let cids = manager.get_all_cids();
775 assert_eq!(cids.len(), 2);
776 assert!(cids.contains(&"QmTest1".to_string()));
777 assert!(cids.contains(&"QmTest2".to_string()));
778 }
779
780 #[test]
781 fn test_count_by_category() {
782 let mut manager = ContentManager::new(PathBuf::from("/tmp/chie-test"));
783
784 let mut metadata1 = create_test_metadata("QmTest1", 1024, 1);
785 metadata1.category = ContentCategory::ThreeDModels;
786
787 let mut metadata2 = create_test_metadata("QmTest2", 2048, 2);
788 metadata2.category = ContentCategory::ThreeDModels;
789
790 let mut metadata3 = create_test_metadata("QmTest3", 3072, 3);
791 metadata3.category = ContentCategory::Audio;
792
793 manager.cache_metadata("QmTest1".to_string(), metadata1);
794 manager.cache_metadata("QmTest2".to_string(), metadata2);
795 manager.cache_metadata("QmTest3".to_string(), metadata3);
796
797 assert_eq!(manager.count_by_category(ContentCategory::ThreeDModels), 2);
798 assert_eq!(manager.count_by_category(ContentCategory::Audio), 1);
799 assert_eq!(manager.count_by_category(ContentCategory::Scripts), 0);
800 }
801
802 #[test]
803 fn test_average_content_size() {
804 let mut manager = ContentManager::new(PathBuf::from("/tmp/chie-test"));
805
806 manager.cache_metadata(
807 "QmTest1".to_string(),
808 create_test_metadata("QmTest1", 1000, 1),
809 );
810 manager.cache_metadata(
811 "QmTest2".to_string(),
812 create_test_metadata("QmTest2", 2000, 2),
813 );
814 manager.cache_metadata(
815 "QmTest3".to_string(),
816 create_test_metadata("QmTest3", 3000, 3),
817 );
818
819 assert_eq!(manager.average_content_size(), 2000);
820 }
821
822 #[test]
823 fn test_average_content_size_empty() {
824 let manager = ContentManager::new(PathBuf::from("/tmp/chie-test"));
825 assert_eq!(manager.average_content_size(), 0);
826 }
827}