package com.mopub.common;
import android.app.Activity;
import com.mopub.common.test.support.SdkTestRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.util.concurrent.Semaphore;
import static com.mopub.common.CacheService.DiskLruCacheGetListener;
import static org.fest.assertions.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
@RunWith(SdkTestRunner.class)
public class CacheServiceTest {
private Activity context;
private String key1;
private String data1;
private String getKey;
private byte[] getBytes;
private DiskLruCacheGetListener diskCacheGetListener;
private Semaphore semaphore;
@Before
public void setUp() throws Exception {
context = new Activity();
key1 = "http://www.mopub.com/";
data1 = "image_data_1";
semaphore = new Semaphore(0);
diskCacheGetListener = mock(DiskLruCacheGetListener.class);
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
Object[] args = invocationOnMock.getArguments();
CacheServiceTest.this.getKey = (String)args[0];
CacheServiceTest.this.getBytes = (byte[])args[1];
semaphore.release();
return null;
}
}).when(diskCacheGetListener).onComplete(anyString(), any(byte[].class));
}
@Test
public void initializeCache_withValidContext_shouldCreateNewCachesIdempotently() throws Exception {
assertThat(CacheService.getDiskLruCache()).isNull();
CacheService.initialize(context);
DiskLruCache diskLruCache = CacheService.getDiskLruCache();
assertThat(diskLruCache).isNotNull();
CacheService.initialize(context);
assertThat(diskLruCache).isEqualTo(CacheService.getDiskLruCache());
}
@Test
public void getDiskLruCacheDirectory_shouldReturnValidCacheDirectory() throws Exception {
File file = CacheService.getDiskCacheDirectory(context);
String expectedPath = context.getCacheDir().toString() + "/mopub-cache";
assertThat(file.getAbsolutePath()).isEqualTo(expectedPath);
}
@Test
public void diskLruCacheGet_whenPopulated_shouldReturnValue() throws Exception {
CacheService.initialize(context);
CacheService.putToDiskCache(key1, data1.getBytes());
assertThat(CacheService.getFromDiskCache(key1)).isEqualTo(data1.getBytes());
}
@Test
public void diskLruCacheGet_whenEmpty_shouldReturnNull() throws Exception {
CacheService.initialize(context);
assertCachesAreEmpty();
assertThat(CacheService.getFromDiskCache(key1)).isNull();
}
@Test
public void diskLruCacheAsyncGet_whenPopulated_shouldReturnValue() throws Exception {
CacheService.initialize(context);
assertCachesAreEmpty();
CacheService.putToDiskCache(key1, data1.getBytes());
CacheService.getFromDiskCacheAsync(key1, diskCacheGetListener);
semaphore.acquire();
assertThat(getKey).isEqualTo(key1);
assertThat(getBytes).isEqualTo(data1.getBytes());
}
@Test
public void diskLruCacheAsyncGet_whenEmpty_shouldReturnNull() throws Exception {
CacheService.initialize(context);
CacheService.getFromDiskCacheAsync(key1, diskCacheGetListener);
semaphore.acquire();
assertThat(getKey).isEqualTo(key1);
assertThat(getBytes).isNull();
}
@Test
public void diskLruCachePut_withEmptyStringKey_shouldPutCorrectly() throws Exception {
// this works because an empty string sha1 hashes to a valid key
CacheService.initialize(context);
CacheService.putToDiskCache("", data1.getBytes());
assertThat(CacheService.getFromDiskCache("")).isEqualTo(data1.getBytes());
}
@Test
public void diskLruCachePut_withNullKey_shouldNotPut() throws Exception {
// null value produces empty string key which is invalid for disk lru cache
CacheService.initialize(context);
assertCachesAreEmpty();
CacheService.putToDiskCache(null, data1.getBytes());
assertCachesAreEmpty();
}
@Test
public void createValidDiskLruCacheKey_withNullValue_shouldReturnEmptyString() throws Exception {
CacheService.initialize(context);
assertThat(CacheService.createValidDiskCacheKey(null)).isEqualTo("");
}
@Test
public void diskLruCacheAsyncPut_whenEmpty_shouldReturnNull() throws Exception {
CacheService.initialize(context);
CacheService.putToDiskCacheAsync(key1, data1.getBytes());
Thread.sleep(500);
assertThat(CacheService.getFromDiskCache(key1)).isEqualTo(data1.getBytes());
}
private static InputStream getInputStreamFromString(final String string) {
return spy(new ByteArrayInputStream(string.getBytes()));
}
public static void assertDiskCacheIsUninitialized() {
assertThat(CacheService.getDiskLruCache()).isNull();
}
public static void assertDiskCacheIsEmpty() {
assertThat(CacheService.getDiskLruCache()).isNotNull();
assertThat(CacheService.getDiskLruCache().size()).isEqualTo(0);
}
public static void assertCachesAreEmpty() {
assertDiskCacheIsEmpty();
}
}