/*
* Copyright (c) 2009-2010 Lockheed Martin Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.eurekastreams.server.search.stream;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
/**
* Test fixture for SortedListIntersector.
*/
public class SearchResultSecurityScoperTest
{
/**
* I (heart) checkstyle.
*/
private static final long TWENTY = 20L;
/**
* I (heart) checkstyle.
*/
private static final long EIGHTEEN = 18L;
/**
* I (heart) checkstyle.
*/
private static final long SEVENTEEN = 17L;
/**
* I (heart) checkstyle.
*/
private static final long FIFTEEN = 15L;
/**
* I (heart) checkstyle.
*/
private static final long ELEVEN = 11L;
/**
* I (heart) checkstyle.
*/
private static final int TEN = 10;
/**
* Test fetching a page of data when a full page does exist, but requires
* multiple calls to the first list.
*/
@SuppressWarnings("unchecked")
@Test
public void testFetchPageWhenFullPageExistsAndMultipleRequestsToListA()
{
ArrayList<Long> listA = new ArrayList<Long>();
ArrayList<Long> listB = new ArrayList<Long>();
listA.addAll(Arrays.asList(new Long[] { TWENTY, EIGHTEEN, FIFTEEN,
ELEVEN, 9L, 8L }));
listB.addAll(Arrays.asList(new Long[] { TWENTY, SEVENTEEN, FIFTEEN,
ELEVEN, 9L, 8L, 5L }));
ListOfLongsFetcher searchResultsPageFetcher = new ListOfLongsFetcher(
listA);
ListOfLongsFetcher availableIDsListFetcher = new ListOfLongsFetcher(
listB);
SearchResultListScoper sut = buildSearchResultSecurityScoper(
searchResultsPageFetcher, availableIDsListFetcher, 3);
// perform SUT
List<Long> results = sut.fetchPage(0, 4);
// make sure we got the right values
assertArrayEquals(new Long[] { TWENTY, FIFTEEN, ELEVEN, 9L }, results
.toArray(new Long[results.size()]));
// make sure it took the expected number of page hits to list A
assertEquals(2, searchResultsPageFetcher.getRequestedPageCount());
}
/**
* Test fetching a page of data when a full page does exist, and only
* requires one hit to the first list.
*/
@SuppressWarnings("unchecked")
@Test
public void testFetchPageWhenFullPageExistsAndSingleRequestsToListA()
{
ArrayList<Long> listA = new ArrayList<Long>();
ArrayList<Long> listB = new ArrayList<Long>();
listA.addAll(Arrays.asList(new Long[] { TWENTY, EIGHTEEN, FIFTEEN,
ELEVEN, 9L, 8L }));
listB.addAll(Arrays.asList(new Long[] { TWENTY, SEVENTEEN, FIFTEEN,
ELEVEN, 9L, 8L, 5L }));
ListOfLongsFetcher searchResultsPageFetcher = new ListOfLongsFetcher(
listA);
ListOfLongsFetcher availableIDsListFetcher = new ListOfLongsFetcher(
listB);
SearchResultListScoper sut = buildSearchResultSecurityScoper(
searchResultsPageFetcher, availableIDsListFetcher, TEN * 2);
// perform SUT
List<Long> results = sut.fetchPage(0, 4);
// make sure we got the right values
assertArrayEquals(new Long[] { TWENTY, FIFTEEN, ELEVEN, 9L }, results
.toArray(new Long[results.size()]));
// make sure it took the expected number of page hits to list A
assertEquals(1, searchResultsPageFetcher.getRequestedPageCount());
}
/**
* Test fetching a page of data when there's not enough matches, requiring
* only one hit to the first list.
*/
@SuppressWarnings("unchecked")
@Test
public void testFetchPageWhenNotEnoughResultsAndSingleRequestsToListA()
{
ArrayList<Long> listA = new ArrayList<Long>();
ArrayList<Long> listB = new ArrayList<Long>();
listA.addAll(Arrays.asList(new Long[] { TWENTY, EIGHTEEN, FIFTEEN,
ELEVEN, 9L, 8L }));
listB.addAll(Arrays.asList(new Long[] { TWENTY, SEVENTEEN, FIFTEEN,
ELEVEN, 9L, 8L, 5L }));
ListOfLongsFetcher searchResultsPageFetcher = new ListOfLongsFetcher(
listA);
ListOfLongsFetcher availableIDsListFetcher = new ListOfLongsFetcher(
listB);
SearchResultListScoper sut = buildSearchResultSecurityScoper(
searchResultsPageFetcher, availableIDsListFetcher, TEN * 2);
// perform SUT
List<Long> results = sut.fetchPage(0, TEN);
// make sure we got the right values
assertArrayEquals(new Long[] { TWENTY, FIFTEEN, ELEVEN, 9L, 8L },
results.toArray(new Long[results.size()]));
// make sure it took the expected number of page hits to list A
assertEquals(1, searchResultsPageFetcher.getRequestedPageCount());
}
/**
* Test fetching a page of data when there's not enough in the first list,
* requiring only one hit to the first list.
*/
@SuppressWarnings("unchecked")
@Test
public void testFetchPageWhenNotEnoughResultsAndSingleRequestsToListA2()
{
ArrayList<Long> listA = new ArrayList<Long>();
ArrayList<Long> listB = new ArrayList<Long>();
listA.addAll(Arrays.asList(new Long[] { TWENTY }));
listB.addAll(Arrays.asList(new Long[] { TWENTY, SEVENTEEN, FIFTEEN,
ELEVEN, 9L, 8L, 5L }));
ListOfLongsFetcher searchResultsPageFetcher = new ListOfLongsFetcher(
listA);
ListOfLongsFetcher availableIDsListFetcher = new ListOfLongsFetcher(
listB);
SearchResultListScoper sut = buildSearchResultSecurityScoper(
searchResultsPageFetcher, availableIDsListFetcher, TEN * 2);
// perform SUT
List<Long> results = sut.fetchPage(0, TEN);
// make sure we got the right values
assertArrayEquals(new Long[] { TWENTY }, results
.toArray(new Long[results.size()]));
// make sure it took the expected number of page hits to list A
assertEquals(1, searchResultsPageFetcher.getRequestedPageCount());
}
/**
* Test fetching a page when there are no results, and we know this without
* looping to the bottom of the first list.
*/
@SuppressWarnings("unchecked")
@Test
public void testFetchPageWhenNoResultsAndOptimizedEndOfLooping()
{
ArrayList<Long> listA = new ArrayList<Long>();
ArrayList<Long> listB = new ArrayList<Long>();
listA.addAll(Arrays.asList(new Long[] { TWENTY, EIGHTEEN, FIFTEEN,
ELEVEN, 9L, 8L }));
listB.addAll(Arrays.asList(new Long[] { TWENTY * 2 }));
ListOfLongsFetcher searchResultsPageFetcher = new ListOfLongsFetcher(
listA);
ListOfLongsFetcher availableIDsListFetcher = new ListOfLongsFetcher(
listB);
SearchResultListScoper sut = buildSearchResultSecurityScoper(
searchResultsPageFetcher, availableIDsListFetcher, 1);
// perform SUT
List<Long> results = sut.fetchPage(0, TEN);
// make sure we got the right values
assertEquals(0, results.size());
// make sure it took the expected number of page hits to list A - this
// is an optimization - the code should
// realize that there's no point in continuing
assertEquals(1, searchResultsPageFetcher.getRequestedPageCount());
}
/**
* Test fetching a page of data when there is a full page, but we have to
* loop through the first list until we find it.
*/
@SuppressWarnings("unchecked")
@Test
public void testFetchPageWhenFullPageExistsAtEndOfSourceListMultipleSourcePages()
{
ArrayList<Long> listA = new ArrayList<Long>();
ArrayList<Long> listB = new ArrayList<Long>();
listA.addAll(Arrays.asList(new Long[] { TWENTY, EIGHTEEN, FIFTEEN,
ELEVEN, 9L, 8L, 7L, 3L, 1L }));
listB.addAll(Arrays.asList(new Long[] { 3L, 2L, 1L }));
ListOfLongsFetcher searchResultsPageFetcher = new ListOfLongsFetcher(
listA);
ListOfLongsFetcher availableIDsListFetcher = new ListOfLongsFetcher(
listB);
SearchResultListScoper sut = buildSearchResultSecurityScoper(
searchResultsPageFetcher, availableIDsListFetcher, 1);
// perform SUT
List<Long> results = sut.fetchPage(0, 2);
// make sure we got the right values
assertArrayEquals(new Long[] { 3L, 1L }, results
.toArray(new Long[results.size()]));
// this should have taken 9 requests to the source list
assertEquals(9, searchResultsPageFetcher.getRequestedPageCount());
}
/**
* Test fetching a page when there is a full page, but only at the end of
* the two lists, and we make one big paged request.
*/
@SuppressWarnings("unchecked")
@Test
public void testFetchPageWhenFullPageExistsAtEndOfSourceListSingleSourcePage()
{
ArrayList<Long> listA = new ArrayList<Long>();
ArrayList<Long> listB = new ArrayList<Long>();
listA.addAll(Arrays.asList(new Long[] { TWENTY, EIGHTEEN, FIFTEEN,
ELEVEN, 9L, 8L, 7L, 3L, 1L }));
listB.addAll(Arrays.asList(new Long[] { 3L, 2L, 1L }));
ListOfLongsFetcher searchResultsPageFetcher = new ListOfLongsFetcher(
listA);
ListOfLongsFetcher availableIDsListFetcher = new ListOfLongsFetcher(
listB);
SearchResultListScoper sut = buildSearchResultSecurityScoper(
searchResultsPageFetcher, availableIDsListFetcher, TEN * 2);
// perform SUT
List<Long> results = sut.fetchPage(0, 2);
// make sure we got the right values
assertArrayEquals(new Long[] { 3L, 1L }, results
.toArray(new Long[results.size()]));
// this should have taken 1 request to the source list
assertEquals(1, searchResultsPageFetcher.getRequestedPageCount());
}
/**
* Build a SearchResultsSecurityScoper using the factory.
*
* @param inSearchResultsFetcher
* the page fetcher for getting the search results
* @param inAvailableIdsFetcher
* the page fetcher for getting the available ids
* @param searchResultsPageSize
* the page size to use for search results
* @return a SearchResultSecurityScoper, using the factory
*/
private SearchResultListScoper buildSearchResultSecurityScoper(
final PageFetcher<Long> inSearchResultsFetcher,
final PageFetcher<Long> inAvailableIdsFetcher,
final int searchResultsPageSize)
{
SearchResultListScoperFactory factory = new SearchResultListScoperFactory(
searchResultsPageSize);
return factory.buildSearchResultSecurityScoper(inSearchResultsFetcher,
inAvailableIdsFetcher, Long.MAX_VALUE);
}
/**
* Helper PageFetcher that keeps track of how many pages of data are
* requested.
*/
private class ListOfLongsFetcher implements PageFetcher<Long>
{
/**
* Keeps track of the number of page requests.
*/
private int requestedPageCount = 0;
/**
* The list of Longs.
*/
private List<Long> data;
/**
* Constructor - takes the list of longs.
*
* @param inData
* the list of longs
*/
public ListOfLongsFetcher(final List<Long> inData)
{
data = inData;
}
/**
* Fetch a page of data.
*
* @param inStartIndex
* the starting index
* @param inPageSize
* the page size
* @return the page of data
*/
@Override
public List<Long> fetchPage(final int inStartIndex, final int inPageSize)
{
requestedPageCount++;
List<Long> results;
if (data.size() < inStartIndex)
{
results = new ArrayList<Long>();
}
else if (data.size() < inStartIndex + inPageSize)
{
results = data
.subList(inStartIndex, data.size() - inStartIndex);
}
else
{
results = data.subList(inStartIndex, inStartIndex + inPageSize);
}
return results;
}
/**
* @return the requestedPageCount
*/
public int getRequestedPageCount()
{
return requestedPageCount;
}
}
}