damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

VideoCacheTests.swift (6047B)


      1 //
      2 //  VideoCacheTests.swift
      3 //  damusTests
      4 //
      5 //  Created by Daniel D’Aquino on 2024-04-03.
      6 //
      7 
      8 import Foundation
      9 import XCTest
     10 @testable import damus
     11 
     12 // TODO: Reduce test dependency on external factors such as external URLs.
     13 let TEST_VIDEO_URL = "http://cdn.jb55.com/s/zaps-build.mp4"
     14 let LONG_TEST_EXPIRY_TIME: TimeInterval = 60 * 60 * 24    // A long expiry time for a video (in seconds).
     15 let SHORT_TEST_EXPIRY_TIME: TimeInterval = 15             // A short expiry time for a video (in seconds). Must be as short as possible but large enough to allow some test operations to occur
     16 let CACHE_SAVE_TIME_TIMEOUT: TimeInterval = 8             // How long the test will wait for the cache to save a file (in seconds)
     17 let EXPIRY_TIME_MARGIN: TimeInterval = 3                  // The extra time we will wait after expected expiry, to avoid test timing issues. (in seconds)
     18 
     19 final class VideoCacheTests: XCTestCase {
     20     
     21     func testCachedURLForExistingVideo() throws {
     22         // Create a temporary directory for the cache
     23         let test_cache_directory = FileManager.default.temporaryDirectory.appendingPathComponent("test_video_cache")
     24         
     25         // Create a test video file
     26         let original_video_url = URL(string: TEST_VIDEO_URL)!
     27         FileManager.default.createFile(atPath: original_video_url.path, contents: Data(), attributes: nil)
     28         
     29         // Create a VideoCache instance with the temporary cache directory
     30         let test_expiry_time: TimeInterval = 10
     31         let video_cache = try VideoCache(cache_url: test_cache_directory, expiry_time: test_expiry_time)!
     32         
     33         // Call the maybe_cached_url_for method with the test video URL
     34         let expected_cache_url = video_cache.url_to_cached_url(url: original_video_url)
     35         let maybe_cached_url = try video_cache.maybe_cached_url_for(video_url: original_video_url)
     36         
     37         // Assert that the returned URL is the same as the original
     38         XCTAssertEqual(maybe_cached_url, original_video_url, "Returned URL should be the same as the original video URL on the first time we download it")
     39 
     40         // Check that next time we get this video, we get the cached URL.
     41         let cached_url_expectation = XCTestExpectation(description: "On second time we get a video, the cached URL should be returned")
     42         let start_time = Date()
     43         while Date().timeIntervalSince(start_time) < CACHE_SAVE_TIME_TIMEOUT {
     44             let maybe_cached_url = try video_cache.maybe_cached_url_for(video_url: original_video_url)
     45             if maybe_cached_url == expected_cache_url {
     46                 cached_url_expectation.fulfill()
     47                 break
     48             }
     49             sleep(1)
     50         }
     51         wait(for: [cached_url_expectation], timeout: CACHE_SAVE_TIME_TIMEOUT)
     52 
     53         // Now wait for the remaining time until the expiry time + a margin
     54         let remaining_time = test_expiry_time + EXPIRY_TIME_MARGIN - Date().timeIntervalSince(start_time)
     55 
     56         // Wait for the expiry time to pass
     57         sleep(UInt32(max(remaining_time, 0)))
     58         
     59         // Call the periodic_purge method to purge expired video items
     60         video_cache.periodic_purge()
     61 
     62         // Call the maybe_cached_url_for method again
     63         let maybe_cached_url_after_expiry = try video_cache.maybe_cached_url_for(video_url: original_video_url)
     64 
     65         // Assert that the returned URL is the same as the original video URL, since the cache should have expired.
     66         XCTAssertEqual(maybe_cached_url_after_expiry, original_video_url, "Video cache should expire after expiry time")
     67         
     68         // Clean up the temporary files and directory
     69         try FileManager.default.removeItem(at: test_cache_directory)
     70     }
     71     
     72     func testClearCache() throws {
     73         // Create a temporary directory for the cache
     74         let test_cache_directory = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!.appendingPathComponent("test_video_cache")
     75         try FileManager.default.createDirectory(at: test_cache_directory, withIntermediateDirectories: true, attributes: nil)
     76         
     77         // Create a test video file
     78         let original_video_url = URL(string: TEST_VIDEO_URL)!
     79         FileManager.default.createFile(atPath: original_video_url.path, contents: Data(), attributes: nil)
     80         
     81         // Create a VideoCache instance with the temporary cache directory and a longer expiry time
     82         let expiry_time: TimeInterval = LONG_TEST_EXPIRY_TIME
     83         let video_cache = try VideoCache(cache_url: test_cache_directory, expiry_time: expiry_time)!
     84 
     85         // Request the cached URL for the test video to create the cached file
     86         let expected_cache_url = video_cache.url_to_cached_url(url: original_video_url)
     87         let _ = try video_cache.maybe_cached_url_for(video_url: original_video_url)
     88 
     89         // Check that next time we get this video, we get the cached URL.
     90         let cached_url_expectation = XCTestExpectation(description: "On second time we get a video, the cached URL should be returned")
     91         let start_time = Date()
     92         while Date().timeIntervalSince(start_time) < CACHE_SAVE_TIME_TIMEOUT {
     93             let maybe_cached_url = try video_cache.maybe_cached_url_for(video_url: original_video_url)
     94             if maybe_cached_url == expected_cache_url {
     95                 cached_url_expectation.fulfill()
     96                 break
     97             }
     98             sleep(1)
     99         }
    100         wait(for: [cached_url_expectation], timeout: CACHE_SAVE_TIME_TIMEOUT)
    101 
    102         // Call the periodic_purge method
    103         DamusCacheManager.shared.clear_cache(damus_state: test_damus_state, completion: {
    104             // Assert that fetching the cached URL after clearing cache will
    105             let maybe_cached_url_after_purge = try? video_cache.maybe_cached_url_for(video_url: original_video_url)
    106             XCTAssertEqual(maybe_cached_url_after_purge, original_video_url)
    107             
    108             // Clean up the temporary directory
    109             try? FileManager.default.removeItem(at: test_cache_directory)
    110         })
    111     }
    112 }