@Test
  public void contains() {
    final String url = "store://content/url.bin";

    Mockito.when(lookupTable.contains(Key.forUrl(url))).thenReturn(true);
    assertTrue(contentCache.contains(Key.forUrl(url)));
    assertTrue(contentCache.contains(url));

    Mockito.when(lookupTable.contains(Key.forUrl(url))).thenReturn(false);
    assertFalse(contentCache.contains(Key.forUrl(url)));
    assertFalse(contentCache.contains(url));
  }
  @Test(expected = CacheMissException.class)
  public void getReaderWhenItemNotInCache() {
    final String url = "store://content/url.bin";
    Mockito.when(lookupTable.contains(Key.forUrl(url))).thenReturn(false);

    contentCache.getReader(url);
  }
  @Test
  public void putForZeroLengthFile() {
    ContentReader contentReader = Mockito.mock(ContentReader.class);
    Mockito.when(contentReader.getSize()).thenReturn(0L);

    boolean putResult = contentCache.put("", contentReader);

    assertFalse("Zero length files should not be cached", putResult);
  }
  @Test
  public void putIntoLookup() {
    final Key key = Key.forUrl("store://some/url");
    final String value = "/some/path";

    contentCache.putIntoLookup(key, value);

    Mockito.verify(lookupTable).put(key, value);
  }
  @Test
  public void getContentUrl() {
    final File cacheFile = new File("/some/path");
    final String expectedUrl = "store://some/url";
    Mockito.when(lookupTable.get(Key.forCacheFile(cacheFile))).thenReturn(expectedUrl);

    String url = contentCache.getContentUrl(cacheFile);

    assertEquals("Content URLs should match", expectedUrl, url);
  }
  @Test
  public void getCacheFilePath() {
    final String url = "store://some/url.bin";
    final String expectedPath = "/some/cache/file/path";
    Mockito.when(lookupTable.get(Key.forUrl(url))).thenReturn(expectedPath);

    String path = contentCache.getCacheFilePath(url);

    assertEquals("Paths must match", expectedPath, path);
  }
  @Test
  public void remove() {
    final String url = "store://some/url.bin";
    final String path = "/some/path";
    Mockito.when(lookupTable.get(Key.forUrl(url))).thenReturn(path);

    contentCache.remove(url);

    Mockito.verify(lookupTable).remove(Key.forUrl(url));
    Mockito.verify(lookupTable).remove(Key.forCacheFile(path));
  }
  @Test
  public void getWriter() {
    final String url = "store://some/url.bin";

    FileContentWriter writer = (FileContentWriter) contentCache.getWriter(url);
    writer.putContent("Some test content for " + getClass().getName());

    assertEquals(url, writer.getContentUrl());
    // Check cached item is recorded properly in ehcache
    Mockito.verify(lookupTable).put(Key.forUrl(url), writer.getFile().getAbsolutePath());
    Mockito.verify(lookupTable).put(Key.forCacheFile(writer.getFile().getAbsolutePath()), url);
  }
  @Test(expected = CacheMissException.class)
  public void getReaderForItemInCacheButMissingContentFile() {
    final String url = "store://content/url.bin";
    Mockito.when(lookupTable.contains(Key.forUrl(url))).thenReturn(true);
    final String path = "/no/content/file/at/this/path.bin";
    Mockito.when(lookupTable.get(Key.forUrl(url))).thenReturn(path);

    try {
      contentCache.getReader(url);
    } finally {
      // Important the get(path) was called, so that the timeToIdle is reset
      // for the 'reverse lookup' as well as the URL to path mapping.
      Mockito.verify(lookupTable).get(Key.forCacheFile(path));
    }
  }
  @Test
  public void putForNonEmptyFile() {
    ContentReader contentReader = Mockito.mock(ContentReader.class);
    Mockito.when(contentReader.getSize()).thenReturn(999000L);
    final String url = "store://some/url.bin";
    boolean putResult = contentCache.put(url, contentReader);

    assertTrue("Non-empty files should be cached", putResult);
    ArgumentCaptor<File> cacheFileArg = ArgumentCaptor.forClass(File.class);
    Mockito.verify(contentReader).getContent(cacheFileArg.capture());
    // Check cached item is recorded properly in ehcache
    Mockito.verify(lookupTable).put(Key.forUrl(url), cacheFileArg.getValue().getAbsolutePath());
    Mockito.verify(lookupTable)
        .put(Key.forCacheFile(cacheFileArg.getValue().getAbsolutePath()), url);
  }
  @Test
  public void canGetReaderForItemInCacheHavingLiveFile() {
    final String url = "store://content/url.bin";
    Mockito.when(lookupTable.contains(Key.forUrl(url))).thenReturn(true);
    final String path = tempfile().getAbsolutePath();
    Mockito.when(lookupTable.get(Key.forUrl(url))).thenReturn(path);

    FileContentReader reader = (FileContentReader) contentCache.getReader(url);

    assertEquals("Reader should have correct URL", url, reader.getContentUrl());
    assertEquals(
        "Reader should be for correct cached content file",
        path,
        reader.getFile().getAbsolutePath());
    // Important the get(path) was called, so that the timeToIdle is reset
    // for the 'reverse lookup' as well as the URL to path mapping.
    Mockito.verify(lookupTable).get(Key.forCacheFile(path));
  }
 @Before
 public void setUp() throws Exception {
   contentCache = new ContentCacheImpl();
   contentCache.setMemoryStore(lookupTable);
   contentCache.setCacheRoot(TempFileProvider.getTempDir());
 }