You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

217 lines
8.0 KiB

/**
* DailyNotificationTTLEnforcerTest.java
*
* Unit tests for TTL-at-fire enforcement functionality
* Tests freshness validation, TTL violation logging, and skip logic
*
* @author Matthew Raymer
* @version 1.0.0
*/
package com.timesafari.dailynotification;
import android.content.Context;
import android.test.AndroidTestCase;
import android.test.mock.MockContext;
import java.util.concurrent.TimeUnit;
/**
* Unit tests for DailyNotificationTTLEnforcer
*
* Tests the core TTL enforcement functionality including:
* - Freshness validation before arming
* - TTL violation detection and logging
* - Skip logic for stale content
* - Configuration retrieval from storage
*/
public class DailyNotificationTTLEnforcerTest extends AndroidTestCase {
private DailyNotificationTTLEnforcer ttlEnforcer;
private Context mockContext;
private DailyNotificationDatabase database;
@Override
protected void setUp() throws Exception {
super.setUp();
// Create mock context
mockContext = new MockContext() {
@Override
public android.content.SharedPreferences getSharedPreferences(String name, int mode) {
return getContext().getSharedPreferences(name, mode);
}
};
// Create database instance
database = new DailyNotificationDatabase(mockContext);
// Create TTL enforcer with SQLite storage
ttlEnforcer = new DailyNotificationTTLEnforcer(mockContext, database, true);
}
@Override
protected void tearDown() throws Exception {
if (database != null) {
database.close();
}
super.tearDown();
}
/**
* Test freshness validation with fresh content
*/
public void testFreshContentValidation() {
long currentTime = System.currentTimeMillis();
long scheduledTime = currentTime + TimeUnit.MINUTES.toMillis(30); // 30 minutes from now
long fetchedAt = currentTime - TimeUnit.MINUTES.toMillis(5); // 5 minutes ago
boolean isFresh = ttlEnforcer.isContentFresh("test_slot_1", scheduledTime, fetchedAt);
assertTrue("Content should be fresh (5 min old, scheduled 30 min from now)", isFresh);
}
/**
* Test freshness validation with stale content
*/
public void testStaleContentValidation() {
long currentTime = System.currentTimeMillis();
long scheduledTime = currentTime + TimeUnit.MINUTES.toMillis(30); // 30 minutes from now
long fetchedAt = currentTime - TimeUnit.HOURS.toMillis(2); // 2 hours ago
boolean isFresh = ttlEnforcer.isContentFresh("test_slot_2", scheduledTime, fetchedAt);
assertFalse("Content should be stale (2 hours old, exceeds 1 hour TTL)", isFresh);
}
/**
* Test TTL violation detection
*/
public void testTTLViolationDetection() {
long currentTime = System.currentTimeMillis();
long scheduledTime = currentTime + TimeUnit.MINUTES.toMillis(30);
long fetchedAt = currentTime - TimeUnit.HOURS.toMillis(2); // 2 hours ago
// This should trigger a TTL violation
boolean isFresh = ttlEnforcer.isContentFresh("test_slot_3", scheduledTime, fetchedAt);
assertFalse("Should detect TTL violation", isFresh);
// Check that violation was logged (we can't easily test the actual logging,
// but we can verify the method returns false as expected)
}
/**
* Test validateBeforeArming with fresh content
*/
public void testValidateBeforeArmingFresh() {
long currentTime = System.currentTimeMillis();
long scheduledTime = currentTime + TimeUnit.MINUTES.toMillis(30);
long fetchedAt = currentTime - TimeUnit.MINUTES.toMillis(5);
NotificationContent content = new NotificationContent();
content.setId("test_slot_4");
content.setScheduledTime(scheduledTime);
content.setFetchedAt(fetchedAt);
content.setTitle("Test Notification");
content.setBody("Test body");
boolean shouldArm = ttlEnforcer.validateBeforeArming(content);
assertTrue("Should arm fresh content", shouldArm);
}
/**
* Test validateBeforeArming with stale content
*/
public void testValidateBeforeArmingStale() {
long currentTime = System.currentTimeMillis();
long scheduledTime = currentTime + TimeUnit.MINUTES.toMillis(30);
long fetchedAt = currentTime - TimeUnit.HOURS.toMillis(2);
NotificationContent content = new NotificationContent();
content.setId("test_slot_5");
content.setScheduledTime(scheduledTime);
content.setFetchedAt(fetchedAt);
content.setTitle("Test Notification");
content.setBody("Test body");
boolean shouldArm = ttlEnforcer.validateBeforeArming(content);
assertFalse("Should not arm stale content", shouldArm);
}
/**
* Test edge case: content fetched exactly at TTL limit
*/
public void testTTLBoundaryCase() {
long currentTime = System.currentTimeMillis();
long scheduledTime = currentTime + TimeUnit.MINUTES.toMillis(30);
long fetchedAt = currentTime - TimeUnit.HOURS.toMillis(1); // Exactly 1 hour ago (TTL limit)
boolean isFresh = ttlEnforcer.isContentFresh("test_slot_6", scheduledTime, fetchedAt);
assertTrue("Content at TTL boundary should be considered fresh", isFresh);
}
/**
* Test edge case: content fetched just over TTL limit
*/
public void testTTLBoundaryCaseOver() {
long currentTime = System.currentTimeMillis();
long scheduledTime = currentTime + TimeUnit.MINUTES.toMillis(30);
long fetchedAt = currentTime - TimeUnit.HOURS.toMillis(1) - TimeUnit.SECONDS.toMillis(1); // 1 hour + 1 second ago
boolean isFresh = ttlEnforcer.isContentFresh("test_slot_7", scheduledTime, fetchedAt);
assertFalse("Content just over TTL limit should be considered stale", isFresh);
}
/**
* Test TTL violation statistics
*/
public void testTTLViolationStats() {
// Generate some TTL violations
long currentTime = System.currentTimeMillis();
long scheduledTime = currentTime + TimeUnit.MINUTES.toMillis(30);
long fetchedAt = currentTime - TimeUnit.HOURS.toMillis(2);
// Trigger TTL violations
ttlEnforcer.isContentFresh("test_slot_8", scheduledTime, fetchedAt);
ttlEnforcer.isContentFresh("test_slot_9", scheduledTime, fetchedAt);
String stats = ttlEnforcer.getTTLViolationStats();
assertNotNull("TTL violation stats should not be null", stats);
assertTrue("Stats should contain violation count", stats.contains("violations"));
}
/**
* Test error handling with invalid parameters
*/
public void testErrorHandling() {
// Test with null slot ID
boolean result = ttlEnforcer.isContentFresh(null, System.currentTimeMillis(), System.currentTimeMillis());
assertFalse("Should handle null slot ID gracefully", result);
// Test with invalid timestamps
result = ttlEnforcer.isContentFresh("test_slot_10", 0, 0);
assertTrue("Should handle invalid timestamps gracefully", result);
}
/**
* Test TTL configuration retrieval
*/
public void testTTLConfiguration() {
// Test that TTL enforcer can retrieve configuration
// This is indirectly tested through the freshness checks
long currentTime = System.currentTimeMillis();
long scheduledTime = currentTime + TimeUnit.MINUTES.toMillis(30);
long fetchedAt = currentTime - TimeUnit.MINUTES.toMillis(30); // 30 minutes ago
boolean isFresh = ttlEnforcer.isContentFresh("test_slot_11", scheduledTime, fetchedAt);
// Should be fresh (30 min < 1 hour TTL)
assertTrue("Should retrieve TTL configuration correctly", isFresh);
}
}