From addab94fff380439560eb03999cc4c8d2c33c582 Mon Sep 17 00:00:00 2001 From: Nishant Kumar Date: Fri, 12 Jul 2024 17:05:45 +0530 Subject: [PATCH] - Fixes files expiry time not updated when it is reused for PE File vars. - Fixes expired files were not deleted when downloadFiles is not called. --- CleverTapSDK/FileDownload/CTFileDownloader.h | 2 +- CleverTapSDK/FileDownload/CTFileDownloader.m | 16 ++++- CleverTapSDK/ProductExperiences/CTVarCache.m | 6 +- .../FileDownload/CTFileDownloaderTests.m | 62 +++++++++++++++---- 4 files changed, 69 insertions(+), 17 deletions(-) diff --git a/CleverTapSDK/FileDownload/CTFileDownloader.h b/CleverTapSDK/FileDownload/CTFileDownloader.h index 4a1d1466..97886581 100644 --- a/CleverTapSDK/FileDownload/CTFileDownloader.h +++ b/CleverTapSDK/FileDownload/CTFileDownloader.h @@ -10,7 +10,7 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)init NS_UNAVAILABLE; - (instancetype)initWithConfig:(CleverTapInstanceConfig *)config; - (void)downloadFiles:(NSArray *)fileURLs withCompletionBlock:(void (^ _Nullable)(NSDictionary *status))completion; -- (BOOL)isFileAlreadyPresent:(NSString *)url; +- (BOOL)isFileAlreadyPresent:(NSString *)url andUpdateExpiryTime:(BOOL)updateExpiryTime; - (void)clearFileAssets:(BOOL)expiredOnly; - (nullable NSString *)fileDownloadPath:(NSString *)url; - (nullable UIImage *)loadImageFromDisk:(NSString *)imageURL; diff --git a/CleverTapSDK/FileDownload/CTFileDownloader.m b/CleverTapSDK/FileDownload/CTFileDownloader.m index 5e2db57d..78b4cbd1 100644 --- a/CleverTapSDK/FileDownload/CTFileDownloader.m +++ b/CleverTapSDK/FileDownload/CTFileDownloader.m @@ -48,9 +48,17 @@ - (void)downloadFiles:(NSArray *)fileURLs withCompletionBlock:(void }]; } -- (BOOL)isFileAlreadyPresent:(NSString *)url { +- (BOOL)isFileAlreadyPresent:(NSString *)url + andUpdateExpiryTime:(BOOL)updateExpiryTime { NSURL *fileUrl = [NSURL URLWithString:url]; BOOL fileExists = [self.fileDownloadManager isFileAlreadyPresent:fileUrl]; + + // For PE File vars when fileExists returns true, we are not calling downloadFiles for existing files + // so we need to update file expiry time for those existing files. + if (fileExists && updateExpiryTime) { + [self updateFilesExpiry:@{url:@1}]; + [self updateFilesExpiryInPreference]; + } return fileExists; } @@ -66,7 +74,7 @@ - (void)clearFileAssets:(BOOL)expiredOnly { } - (nullable NSString *)fileDownloadPath:(NSString *)url { - if ([self isFileAlreadyPresent:url]) { + if ([self isFileAlreadyPresent:url andUpdateExpiryTime:NO]) { NSURL *fileURL = [NSURL URLWithString:url]; return [self.fileDownloadManager filePath:fileURL]; } else { @@ -103,6 +111,10 @@ - (void)setup { self.urlsExpiry = [NSMutableDictionary new]; } } + + // Check for expired files and delete them at every start of session. + long lastDeletedTime = [self lastDeletedTimestamp]; + [self removeInactiveExpiredAssets:lastDeletedTime]; } - (void)removeInactiveExpiredAssets:(long)lastDeletedTime { diff --git a/CleverTapSDK/ProductExperiences/CTVarCache.m b/CleverTapSDK/ProductExperiences/CTVarCache.m index 318a5658..3b5a1a9e 100644 --- a/CleverTapSDK/ProductExperiences/CTVarCache.m +++ b/CleverTapSDK/ProductExperiences/CTVarCache.m @@ -314,7 +314,7 @@ - (nullable NSString *)fileDownloadPath:(NSString *)fileURL { } - (BOOL)isFileAlreadyPresent:(NSString *)fileURL { - return [self.fileDownloader isFileAlreadyPresent:fileURL]; + return [self.fileDownloader isFileAlreadyPresent:fileURL andUpdateExpiryTime:YES]; } - (NSMutableArray *)fileURLs:(NSArray *)fileVars { @@ -323,7 +323,7 @@ - (BOOL)isFileAlreadyPresent:(NSString *)fileURL { if (var.fileURL) { // If file is already present, call fileIsReady // else download the file and call fileIsReady when downloaded - if ([self.fileDownloader isFileAlreadyPresent:var.fileURL]) { + if ([self isFileAlreadyPresent:var.fileURL]) { [var triggerFileIsReady]; } else { [downloadURLs addObject:var.fileURL]; @@ -362,7 +362,7 @@ - (void)fileVarUpdated:(CTVar *)fileVar { return; } - if ([self.fileDownloader isFileAlreadyPresent:url]) { + if ([self isFileAlreadyPresent:url]) { [fileVar triggerFileIsReady]; } else { [self.fileDownloader downloadFiles:@[url] withCompletionBlock:^(NSDictionary * _Nonnull status) { diff --git a/CleverTapSDKTests/FileDownload/CTFileDownloaderTests.m b/CleverTapSDKTests/FileDownload/CTFileDownloaderTests.m index 85d1e4e3..3d714d18 100644 --- a/CleverTapSDKTests/FileDownload/CTFileDownloaderTests.m +++ b/CleverTapSDKTests/FileDownload/CTFileDownloaderTests.m @@ -131,13 +131,13 @@ - (void)testDefaultExpiryTime { - (void)testFileAlreadyPresent { NSArray *urls = [self.helper generateFileURLStrings:2]; - XCTAssertFalse([self.fileDownloader isFileAlreadyPresent:urls[0]]); - XCTAssertFalse([self.fileDownloader isFileAlreadyPresent:urls[1]]); + XCTAssertFalse([self.fileDownloader isFileAlreadyPresent:urls[0] andUpdateExpiryTime:NO]); + XCTAssertFalse([self.fileDownloader isFileAlreadyPresent:urls[1] andUpdateExpiryTime:NO]); [self downloadFiles:@[urls[0]]]; - XCTAssertTrue([self.fileDownloader isFileAlreadyPresent:urls[0]]); - XCTAssertFalse([self.fileDownloader isFileAlreadyPresent:urls[1]]); + XCTAssertTrue([self.fileDownloader isFileAlreadyPresent:urls[0] andUpdateExpiryTime:NO]); + XCTAssertFalse([self.fileDownloader isFileAlreadyPresent:urls[1] andUpdateExpiryTime:NO]); } - (void)testImageLoadedFromDisk { @@ -424,7 +424,7 @@ - (void)testDownloadAndClearAllFileAssets { NSMutableArray *paths = [NSMutableArray array]; for (NSString *url in urls) { // Assert the files are downloaded - XCTAssertTrue([self.fileDownloader isFileAlreadyPresent:url]); + XCTAssertTrue([self.fileDownloader isFileAlreadyPresent:url andUpdateExpiryTime:NO]); [paths addObject:[self.fileDownloader fileDownloadPath:url]]; } @@ -441,7 +441,7 @@ - (void)testDownloadAndClearAllFileAssets { } // Assert the files no longer exist for (NSString *url in urls) { - XCTAssertFalse([weakSelf.fileDownloader isFileAlreadyPresent:url]); + XCTAssertFalse([weakSelf.fileDownloader isFileAlreadyPresent:url andUpdateExpiryTime:NO]); } // Assert urlsExpiry is cleared XCTAssertEqual(0, weakSelf.fileDownloader.urlsExpiry.count); @@ -464,19 +464,59 @@ - (void)testFileDownloadCallbacksWhenFileIsAlreadyDownloading { NSArray *urls = [self.helper generateFileURLStrings:3]; [self.fileDownloader downloadFiles:@[urls[0], urls[1], urls[2]] withCompletionBlock:^(NSDictionary * _Nullable status) { - XCTAssertTrue([self.fileDownloader isFileAlreadyPresent:urls[0]]); - XCTAssertTrue([self.fileDownloader isFileAlreadyPresent:urls[1]]); - XCTAssertTrue([self.fileDownloader isFileAlreadyPresent:urls[2]]); + XCTAssertTrue([self.fileDownloader isFileAlreadyPresent:urls[0] andUpdateExpiryTime:NO]); + XCTAssertTrue([self.fileDownloader isFileAlreadyPresent:urls[1] andUpdateExpiryTime:NO]); + XCTAssertTrue([self.fileDownloader isFileAlreadyPresent:urls[2] andUpdateExpiryTime:NO]); [expectation1 fulfill]; }]; [self.fileDownloader downloadFiles:@[urls[0], urls[1]] withCompletionBlock:^(NSDictionary * _Nullable status) { - XCTAssertTrue([self.fileDownloader isFileAlreadyPresent:urls[0]]); - XCTAssertTrue([self.fileDownloader isFileAlreadyPresent:urls[1]]); + XCTAssertTrue([self.fileDownloader isFileAlreadyPresent:urls[0] andUpdateExpiryTime:NO]); + XCTAssertTrue([self.fileDownloader isFileAlreadyPresent:urls[1] andUpdateExpiryTime:NO]); [expectation2 fulfill]; }]; [self waitForExpectations:@[expectation2, expectation1] timeout:2.0 enforceOrder:YES]; } +- (void)testFileAlreadyPresentUpdatesFileExpiryTime { + // This test checks that file expiry time is updated when file is already present + // and `isFileAlreadyPresent:` method is called with andUpdateExpiryTime YES. + + // Mock currentTimeInterval + long ts = (long)[[NSDate date] timeIntervalSince1970]; + self.fileDownloader.mockCurrentTimeInterval = ts; + + NSString *url = [self.helper generateFileURLStrings:1][0]; + [self downloadFiles:@[url]]; + long expiryDate = ts + self.fileDownloader.fileExpiryTime; + // Ensure url has correct expiry set + XCTAssertEqualObjects(@(expiryDate), self.fileDownloader.urlsExpiry[url]); + + self.fileDownloader.mockCurrentTimeInterval = ts + 100; + [self.fileDownloader isFileAlreadyPresent:url andUpdateExpiryTime:YES]; + // Ensure url expiry is updated + XCTAssertEqualObjects(@(expiryDate + 100), self.fileDownloader.urlsExpiry[url]); +} + +- (void)testFileAlreadyPresentDoesNotUpdatesFileExpiryTime { + // This test checks that file expiry time is not updated when file is already present + // and `isFileAlreadyPresent:` method is called with andUpdateExpiryTime NO. + + // Mock currentTimeInterval + long ts = (long)[[NSDate date] timeIntervalSince1970]; + self.fileDownloader.mockCurrentTimeInterval = ts; + + NSString *url = [self.helper generateFileURLStrings:1][0]; + [self downloadFiles:@[url]]; + long expiryDate = ts + self.fileDownloader.fileExpiryTime; + // Ensure url has correct expiry set + XCTAssertEqualObjects(@(expiryDate), self.fileDownloader.urlsExpiry[url]); + + self.fileDownloader.mockCurrentTimeInterval = ts + 100; + [self.fileDownloader isFileAlreadyPresent:url andUpdateExpiryTime:NO]; + // Ensure url expiry is not updated + XCTAssertEqualObjects(@(expiryDate), self.fileDownloader.urlsExpiry[url]); +} + #pragma mark Private methods - (void)downloadFiles:(NSArray *)urls {