/** Make sure we can delete a search request that is in the cache. */
  @Test
  public void testDeleteInCache() {
    deletegateStore.getAllOwnedSearchRequests(adminUser);
    mockController.setReturnValue(EasyList.build(searchRequest1, searchRequest2));

    deletegateStore.delete(searchRequest2.getId());

    deletegateStore.getSearchRequest(searchRequest2.getId());
    mockController.setReturnValue(searchRequest2);

    mockController.replay();

    // prime the cache.
    cachingStore.getAllOwnedSearchRequests(adminUser);

    // execute the tests.
    cachingStore.delete(searchRequest2.getId());

    // these should be cached.
    assertEqualsNotSame(searchRequest1, cachingStore.getSearchRequest(searchRequest1.getId()));
    assertEqualsNotSame(
        EasyList.build(searchRequest1), cachingStore.getAllOwnedSearchRequests(adminUser));

    // this should not be cached.
    assertEqualsNotSame(searchRequest2, cachingStore.getSearchRequest(searchRequest2.getId()));

    mockController.verify();
  }
  /**
   * Make sure that the adjust favourite count works when wrapped store throws runtime exception.
   */
  @Test
  public void testAdjustFavouriteFailWithRuntimeException() {
    deletegateStore.getSearchRequest(searchRequest3.getId());
    mockController.setReturnValue(searchRequest3);

    deletegateStore.adjustFavouriteCount(searchRequest3.getId(), Integer.MAX_VALUE);
    mockController.setThrowable(
        new RuntimeException("testAdjustFavouriteFailWithRuntimeException"));

    deletegateStore.getSearchRequest(searchRequest3.getId());
    mockController.setReturnValue(searchRequest3);

    mockController.replay();

    // prime the cache for the test.
    deletegateStore.getSearchRequest(searchRequest3.getId());

    // adjust should fail.
    try {
      cachingStore.adjustFavouriteCount(searchRequest3.getId(), Integer.MAX_VALUE);
      fail("Exception should have been thrown.");
    } catch (Exception expected) {

    }

    // this call should not be cached.
    assertEqualsNotSame(searchRequest3, cachingStore.getSearchRequest(searchRequest3.getId()));

    mockController.verify();
  }
  /** Check what happens when the delegate store fails with null return. */
  @Test
  public void testUpdateFailsWithException() {
    deletegateStore.getSearchRequest(searchRequest1.getId());
    mockController.setReturnValue(searchRequest1);

    deletegateStore.update(searchRequest1);
    mockController.setThrowable(new RuntimeException("testUpdateFailsWithException"));

    deletegateStore.getSearchRequest(searchRequest1.getId());
    mockController.setReturnValue(null);

    mockController.replay();

    // put a value in the cache for the test.
    cachingStore.getSearchRequest(searchRequest1.getId());

    try {
      cachingStore.update(searchRequest1);
      fail("This exception should be thrown.");
    } catch (RuntimeException expected) {
    }

    // this call should not be cached.
    assertNull(cachingStore.getSearchRequest(searchRequest1.getId()));

    mockController.verify();
  }
  /** Check what happens when the portal page is not created by the store.. */
  @Test
  public void testCreateException() {
    deletegateStore.create(searchRequest1);
    mockController.setThrowable(new RuntimeException("testCreateException"));

    deletegateStore.getSearchRequest(searchRequest1.getId());
    mockController.setReturnValue(searchRequest1);

    mockController.replay();

    try {
      cachingStore.create(searchRequest1);
      fail("Expecting an exception to be thrown by the store.");
    } catch (RuntimeException expected) {

    }

    // this should not be cached.
    assertEqualsNotSame(searchRequest1, cachingStore.getSearchRequest(searchRequest1.getId()));

    // this should now be cached.
    assertEqualsNotSame(searchRequest1, cachingStore.getSearchRequest(searchRequest1.getId()));
    assertEqualsNotSame(searchRequest1, cachingStore.getSearchRequest(searchRequest1.getId()));

    mockController.verify();
  }
  /** Test the we can't get a particular request when it does exist. We don't */
  @Test
  public void testGetSearchRequestRuntimeException() {
    deletegateStore.getSearchRequest(searchRequest1.getId());
    mockController.setThrowable(new RuntimeException());
    deletegateStore.getSearchRequest(searchRequest2.getId());
    mockController.setReturnValue(searchRequest2);
    deletegateStore.getSearchRequest(searchRequest1.getId());
    mockController.setReturnValue(searchRequest1);

    mockController.replay();

    try {
      cachingStore.getSearchRequest(searchRequest1.getId());
      fail("Expecting an exception to be thrown by the store.");
    } catch (RuntimeException expected) {
      // ignored.
    }

    // this should call through because it is not in the cache.
    assertEqualsNotSame(searchRequest2, cachingStore.getSearchRequest(searchRequest2.getId()));

    // this should call through because it is not in the cache.
    assertEqualsNotSame(searchRequest1, cachingStore.getSearchRequest(searchRequest1.getId()));

    // these calls should be cached.
    assertEqualsNotSame(searchRequest2, cachingStore.getSearchRequest(searchRequest2.getId()));
    assertEqualsNotSame(searchRequest2, cachingStore.getSearchRequest(searchRequest2.getId()));
    assertEqualsNotSame(searchRequest2, cachingStore.getSearchRequest(searchRequest2.getId()));
    assertEqualsNotSame(searchRequest2, cachingStore.getSearchRequest(searchRequest2.getId()));
    assertEqualsNotSame(searchRequest1, cachingStore.getSearchRequest(searchRequest1.getId()));
    assertEqualsNotSame(searchRequest1, cachingStore.getSearchRequest(searchRequest1.getId()));
    assertEqualsNotSame(searchRequest1, cachingStore.getSearchRequest(searchRequest1.getId()));

    mockController.verify();
  }
  /** Check that we can cache the owned search. */
  @Test
  public void testGetAllOwnedSearchRequest() {
    final List expectedRequests = EasyList.build(searchRequest1, searchRequest2, searchRequest3);

    deletegateStore.getSearchRequest(searchRequest1.getId());
    mockController.setReturnValue(searchRequest1);

    deletegateStore.getSearchRequest(searchRequest4.getId());
    mockController.setReturnValue(searchRequest4);

    deletegateStore.getAllOwnedSearchRequests(adminUser);
    mockController.setReturnValue(expectedRequests);

    mockController.replay();

    // put a value in the cache for the test.
    cachingStore.getSearchRequest(searchRequest1.getId());
    cachingStore.getSearchRequest(searchRequest4.getId());

    // this first call should not be cached and should delegate to getAllOwnedSearchRequests.
    assertEqualsNotSame(expectedRequests, cachingStore.getAllOwnedSearchRequests(adminUser));

    // these calls will now be cached.
    assertEqualsNotSame(expectedRequests, cachingStore.getAllOwnedSearchRequests(adminUser));
    assertEqualsNotSame(expectedRequests, cachingStore.getAllOwnedSearchRequests(adminUser));
    assertEqualsNotSame(expectedRequests, cachingStore.getAllOwnedSearchRequests(adminUser));

    // these should not also be cached.
    assertEqualsNotSame(searchRequest2, cachingStore.getSearchRequest(searchRequest2.getId()));
    assertEqualsNotSame(searchRequest3, cachingStore.getSearchRequest(searchRequest3.getId()));

    mockController.verify();
  }
  /** Make sure we can delete a search request that is not in the cache. */
  @Test
  public void testDeleteNotInCache() {
    deletegateStore.delete(searchRequest4.getId());

    deletegateStore.getSearchRequest(searchRequest4.getId());
    mockController.setReturnValue(searchRequest4);

    mockController.replay();

    cachingStore.delete(searchRequest4.getId());

    // this should not be cached.
    assertEqualsNotSame(searchRequest4, cachingStore.getSearchRequest(searchRequest4.getId()));
  }
  /** Test the update when the page is not in the cache. */
  @Test
  public void testUpdateNotInCache() {
    deletegateStore.update(searchRequest1);
    mockController.setReturnValue(searchRequest3);

    mockController.replay();

    // add the search request. Should now be in the cache.
    assertEqualsNotSame(searchRequest3, cachingStore.update(searchRequest1));

    // all of these calls should be cached.
    assertEqualsNotSame(searchRequest3, cachingStore.getSearchRequest(searchRequest3.getId()));
    assertEqualsNotSame(searchRequest3, cachingStore.getSearchRequest(searchRequest3.getId()));
    assertEqualsNotSame(searchRequest3, cachingStore.getSearchRequest(searchRequest3.getId()));

    mockController.verify();
  }
  /** Make sure that the adjust favourite count works when entity is in the cache. */
  @Test
  public void testAdjustFavouriteCountInCache() {
    deletegateStore.adjustFavouriteCount(searchRequest2.getId(), 10);
    mockController.setReturnValue(searchRequest2);

    mockController.replay();

    // adjust the search request.
    assertEqualsNotSame(
        searchRequest2, cachingStore.adjustFavouriteCount(searchRequest2.getId(), 10));

    // all of these calls should be cached.
    assertEqualsNotSame(searchRequest2, cachingStore.getSearchRequest(searchRequest2.getId()));
    assertEqualsNotSame(searchRequest2, cachingStore.getSearchRequest(searchRequest2.getId()));
    assertEqualsNotSame(searchRequest2, cachingStore.getSearchRequest(searchRequest2.getId()));

    mockController.verify();
  }
  /** Check what happens when the portal page is not created by the store.. */
  @Test
  public void testCreateNullReturn() {
    deletegateStore.create(searchRequest1);
    mockController.setReturnValue(null);

    deletegateStore.getSearchRequest(searchRequest1.getId());
    mockController.setReturnValue(searchRequest1);

    mockController.replay();

    // add the search request. Should not be in he cache because of failure.
    assertNull(cachingStore.create(searchRequest1));

    // this call goes to the cache.
    assertEqualsNotSame(searchRequest1, cachingStore.getSearchRequest(searchRequest1.getId()));

    // these should be cached.
    assertEqualsNotSame(searchRequest1, cachingStore.getSearchRequest(searchRequest1.getId()));
    assertEqualsNotSame(searchRequest1, cachingStore.getSearchRequest(searchRequest1.getId()));

    mockController.verify();
  }
  /** Check what happens when try to save a search whose user has changed. */
  @Test
  public void testUpdateChangedUserName() {
    SearchRequest expectedRequest = new SearchRequest(searchRequest1);
    expectedRequest.setOwnerUserName(fredUser.getName());

    deletegateStore.getAllOwnedSearchRequests(adminUser);
    mockController.setReturnValue(EasyList.build(searchRequest1, searchRequest2, searchRequest3));

    deletegateStore.getAllOwnedSearchRequests(fredUser);
    mockController.setReturnValue(EasyList.build(searchRequest4));

    deletegateStore.update(expectedRequest);
    mockController.setReturnValue(expectedRequest);

    mockController.replay();

    // put a value in the cache for the test.
    cachingStore.getAllOwnedSearchRequests(adminUser);
    cachingStore.getAllOwnedSearchRequests(fredUser);

    // this call should work.
    assertEqualsNotSame(expectedRequest, cachingStore.update(expectedRequest));

    // all of these calls should be cache.
    assertEqualsNotSame(searchRequest2, cachingStore.getSearchRequest(searchRequest2.getId()));
    assertEqualsNotSame(searchRequest3, cachingStore.getSearchRequest(searchRequest3.getId()));
    assertEqualsNotSame(searchRequest4, cachingStore.getSearchRequest(searchRequest4.getId()));
    assertEqualsNotSame(expectedRequest, cachingStore.getSearchRequest(expectedRequest.getId()));

    assertEqualsNotSame(
        EasyList.build(searchRequest2, searchRequest3),
        cachingStore.getAllOwnedSearchRequests(adminUser));
    assertEqualsNotSame(
        EasyList.build(expectedRequest, searchRequest4),
        cachingStore.getAllOwnedSearchRequests(fredUser));

    mockController.verify();
  }
  /** Make sure that the adjust favourite count works when wrapped store returns null. */
  @Test
  public void testAdjustFavouriteFailWithNull() {
    deletegateStore.getSearchRequest(searchRequest3.getId());
    mockController.setReturnValue(searchRequest3);

    deletegateStore.adjustFavouriteCount(searchRequest3.getId(), Integer.MAX_VALUE);
    mockController.setReturnValue(null);

    deletegateStore.getSearchRequest(searchRequest3.getId());
    mockController.setReturnValue(searchRequest3);

    mockController.replay();

    // prime the cache for the test.
    deletegateStore.getSearchRequest(searchRequest3.getId());

    // adjust should fail.
    assertNull(cachingStore.adjustFavouriteCount(searchRequest3.getId(), Integer.MAX_VALUE));

    // this call should not be cached.
    assertEqualsNotSame(searchRequest3, cachingStore.getSearchRequest(searchRequest3.getId()));

    mockController.verify();
  }
  /** Check what happens when the delegate store fails with null return. */
  @Test
  public void testUpdateFailsWithNull() {
    deletegateStore.getSearchRequest(searchRequest1.getId());
    mockController.setReturnValue(searchRequest1);

    deletegateStore.update(searchRequest1);
    mockController.setReturnValue(null);

    deletegateStore.getSearchRequest(searchRequest1.getId());
    mockController.setReturnValue(null);

    mockController.replay();

    // put a value in the cache for the test.
    cachingStore.getSearchRequest(searchRequest1.getId());

    // this call should fail.
    assertNull(cachingStore.update(searchRequest1));

    // this call should not be cached.
    assertNull(cachingStore.getSearchRequest(searchRequest1.getId()));

    mockController.verify();
  }
  /** Test the we can't get a particular request when it does exist. We don't */
  @Test
  public void testGetSearchRequestDoesNotExist() {
    deletegateStore.getSearchRequest(searchRequest1.getId());
    mockController.setReturnValue(null);
    deletegateStore.getSearchRequest(searchRequest2.getId());
    mockController.setReturnValue(searchRequest2);
    deletegateStore.getSearchRequest(searchRequest4.getId());
    mockController.setReturnValue(searchRequest4);
    deletegateStore.getSearchRequest(searchRequest1.getId());
    mockController.setReturnValue(null);

    mockController.replay();

    // this should call through because it is not in the cache.
    assertNull(null, cachingStore.getSearchRequest(searchRequest1.getId()));

    // this should call through because it is not in the cache.
    assertEqualsNotSame(searchRequest2, cachingStore.getSearchRequest(searchRequest2.getId()));

    // these calls should be cached.
    assertEqualsNotSame(searchRequest2, cachingStore.getSearchRequest(searchRequest2.getId()));
    assertEqualsNotSame(searchRequest2, cachingStore.getSearchRequest(searchRequest2.getId()));
    assertEqualsNotSame(searchRequest2, cachingStore.getSearchRequest(searchRequest2.getId()));
    assertEqualsNotSame(searchRequest2, cachingStore.getSearchRequest(searchRequest2.getId()));

    // this call should be direct through.
    assertEqualsNotSame(searchRequest4, cachingStore.getSearchRequest(searchRequest4.getId()));

    // these should be cached.
    assertEqualsNotSame(searchRequest4, cachingStore.getSearchRequest(searchRequest4.getId()));
    assertEqualsNotSame(searchRequest4, cachingStore.getSearchRequest(searchRequest4.getId()));
    assertEqualsNotSame(searchRequest4, cachingStore.getSearchRequest(searchRequest4.getId()));
    assertEqualsNotSame(searchRequest2, cachingStore.getSearchRequest(searchRequest2.getId()));

    // this will not be cached.
    assertNull(cachingStore.getSearchRequest(searchRequest1.getId()));

    mockController.verify();
  }