/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.xoai.tests.unit.services.impl.database;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.dspace.core.Constants;
import org.dspace.xoai.filter.DSpaceMetadataExistsFilter;
import org.dspace.xoai.filter.DSpaceSetSpecFilter;
import org.dspace.xoai.filter.DateFromFilter;
import org.dspace.xoai.filter.DateUntilFilter;
import org.dspace.xoai.services.api.database.DatabaseQuery;
import org.dspace.xoai.services.impl.database.DSpaceDatabaseQueryResolver;
import org.dspace.xoai.tests.unit.services.impl.AbstractQueryResolverTest;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.lyncode.builder.DateBuilder;
import com.lyncode.xoai.dataprovider.data.Filter;
import com.lyncode.xoai.dataprovider.filter.Scope;
import com.lyncode.xoai.dataprovider.filter.ScopedFilter;
import com.lyncode.xoai.dataprovider.filter.conditions.AndCondition;
import com.lyncode.xoai.dataprovider.filter.conditions.Condition;
import com.lyncode.xoai.dataprovider.xml.xoaiconfig.parameters.ParameterList;
import com.lyncode.xoai.dataprovider.xml.xoaiconfig.parameters.ParameterMap;
import com.lyncode.xoai.dataprovider.xml.xoaiconfig.parameters.StringValue;
public class DSpaceDatabaseQueryResolverTest extends AbstractQueryResolverTest {
private static final Date DATE = new Date();
private static final String SET = "col_testSet";
private static final String FIELD_1 = "dc.title";
private static final String FIELD_2 = "dc.type";
private static final int START = 0;
private static final int LENGTH = 100;
private DSpaceDatabaseQueryResolver underTest = new DSpaceDatabaseQueryResolver();;
@Before
public void autowire () {
autowire(underTest);
}
@After
public void cleanup() {
underTest = null;
}
@Test
public void fromFilterQuery() throws Exception {
List<ScopedFilter> scopedFilters = new ArrayList<ScopedFilter>();
scopedFilters.add(new ScopedFilter(new Condition() {
@Override
public Filter getFilter() {
return new DateFromFilter(DATE);
}
}, Scope.Query));
DatabaseQuery result = underTest.buildQuery(scopedFilters, START, LENGTH);
assertThat(result.getQuery(), is("SELECT i.* FROM item i WHERE i.in_archive=true AND (i.last_modified >= ?) ORDER BY i.item_id OFFSET ? LIMIT ?"));
assertThat(((java.sql.Date)result.getParameters().get(0)).getTime(), is(fromDate(DATE).getTime()));
assertThat((Integer) result.getParameters().get(1), is(START));
assertThat((Integer) result.getParameters().get(2), is(LENGTH));
}
@Test
public void fromAndUntilFilterQuery() throws Exception {
List<ScopedFilter> scopedFilters = new ArrayList<ScopedFilter>();
Condition fromCondition = new Condition() {
@Override
public Filter getFilter() {
return new DateFromFilter(DATE);
}
};
Condition untilCondition = new Condition() {
@Override
public Filter getFilter() {
return new DateUntilFilter(DATE);
}
};
scopedFilters.add(new ScopedFilter(new AndCondition(getFilterResolver(),
fromCondition, untilCondition), Scope.Query));
DatabaseQuery result = underTest.buildQuery(scopedFilters, START, LENGTH);
assertThat(result.getQuery(), is("SELECT i.* FROM item i WHERE i.in_archive=true AND ((i.last_modified >= ?) AND (i.last_modified <= ?)) ORDER BY i.item_id OFFSET ? LIMIT ?"));
assertThat(((java.sql.Date)result.getParameters().get(0)).getTime(), is(fromDate(DATE).getTime()));
assertThat(((java.sql.Date)result.getParameters().get(1)).getTime(), is(untilDate(DATE).getTime()));
assertThat((Integer) result.getParameters().get(2), is(START));
assertThat((Integer) result.getParameters().get(3), is(LENGTH));
}
@Test
public void customConditionForMetadataExistsFilterWithOneSingleValue() throws Exception {
theFieldResolver().hasField(FIELD_1, 1);
List<ScopedFilter> scopedFilters = new ArrayList<ScopedFilter>();
ParameterMap filterConfiguration = new ParameterMap().withValues(new StringValue()
.withValue(FIELD_1)
.withName("fields"));
final DSpaceMetadataExistsFilter metadataExistsFilter = new DSpaceMetadataExistsFilter();
metadataExistsFilter.setConfiguration(filterConfiguration);
metadataExistsFilter.setFieldResolver(theFieldResolver());
scopedFilters.add(new ScopedFilter(new Condition()
{
@Override
public Filter getFilter()
{
return metadataExistsFilter;
}
}, Scope.Query));
DatabaseQuery result = underTest.buildQuery(scopedFilters, START, LENGTH);
assertThat(result.getQuery(), is("SELECT i.* FROM item i WHERE i.in_archive=true AND ((EXISTS (SELECT tmp.* FROM metadatavalue tmp WHERE tmp.resource_id=i.item_id AND tmp.resource_type_id=" + Constants.ITEM + " AND tmp.metadata_field_id=?))) ORDER BY i.item_id OFFSET ? LIMIT ?"));
assertThat(((Integer) result.getParameters().get(0)), is(1));
assertThat((Integer) result.getParameters().get(1), is(START));
assertThat((Integer) result.getParameters().get(2), is(LENGTH));
}
@Test
public void customConditionForMetadataExistsFilterWithMultipleValues() throws Exception {
theFieldResolver().hasField(FIELD_1, 1).hasField(FIELD_2, 2);
List<ScopedFilter> scopedFilters = new ArrayList<ScopedFilter>();
ParameterMap filterConfiguration = new ParameterMap().withValues(new ParameterList()
.withValues(
new StringValue().withValue(FIELD_1),
new StringValue().withValue(FIELD_2)
)
.withName("fields"));
final DSpaceMetadataExistsFilter metadataExistsFilter = new DSpaceMetadataExistsFilter();
metadataExistsFilter.setConfiguration(filterConfiguration);
metadataExistsFilter.setFieldResolver(theFieldResolver());
scopedFilters.add(new ScopedFilter(new Condition()
{
@Override
public Filter getFilter()
{
return metadataExistsFilter;
}
}, Scope.Query));
DatabaseQuery result = underTest.buildQuery(scopedFilters, START, LENGTH);
assertThat(result.getQuery(), is("SELECT i.* FROM item i WHERE i.in_archive=true AND ((EXISTS (SELECT tmp.* FROM metadatavalue tmp WHERE tmp.resource_id=i.item_id AND tmp.resource_type_id=" + Constants.ITEM + " AND tmp.metadata_field_id=?) OR EXISTS (SELECT tmp.* FROM metadatavalue tmp WHERE tmp.resource_id=i.item_id AND tmp.resource_type_id=" + Constants.ITEM + " AND tmp.metadata_field_id=?))) ORDER BY i.item_id OFFSET ? LIMIT ?"));
assertThat(((Integer) result.getParameters().get(0)), is(1));
assertThat(((Integer) result.getParameters().get(1)), is(2));
assertThat((Integer) result.getParameters().get(2), is(START));
assertThat((Integer) result.getParameters().get(3), is(LENGTH));
}
@Test
public void fromFilterInMetadataFormatScope() throws Exception {
List<ScopedFilter> scopedFilters = new ArrayList<ScopedFilter>();
scopedFilters.add(new ScopedFilter(new Condition() {
@Override
public Filter getFilter() {
return new DateFromFilter(DATE);
}
}, Scope.MetadataFormat));
DatabaseQuery result = underTest.buildQuery(scopedFilters, START, LENGTH);
assertThat(result.getQuery(), is("SELECT i.* FROM item i WHERE i.in_archive=true AND (item.deleted:true OR (i.last_modified >= ?)) ORDER BY i.item_id OFFSET ? LIMIT ?"));
assertThat(((java.sql.Date)result.getParameters().get(0)).getTime(), is(fromDate(DATE).getTime()));
assertThat((Integer) result.getParameters().get(1), is(START));
assertThat((Integer) result.getParameters().get(2), is(LENGTH));
}
@Test
public void fromAndSetFilterQuery() throws Exception {
List<ScopedFilter> scopedFilters = new ArrayList<ScopedFilter>();
scopedFilters.add(new ScopedFilter(new Condition() {
@Override
public Filter getFilter() {
return new DateFromFilter(DATE);
}
}, Scope.Query));
scopedFilters.add(new ScopedFilter(new Condition() {
@Override
public Filter getFilter() {
return new DSpaceSetSpecFilter(collectionsService, handleResolver, SET);
}
}, Scope.Query));
DatabaseQuery result = underTest.buildQuery(scopedFilters, START, LENGTH);
assertThat(result.getQuery(), is("SELECT i.* FROM item i WHERE i.in_archive=true AND (i.last_modified >= ?) AND true ORDER BY i.item_id OFFSET ? LIMIT ?"));
assertThat(((java.sql.Date)result.getParameters().get(0)).getTime(), is(fromDate(DATE).getTime()));
assertThat((Integer) result.getParameters().get(1), is(START));
assertThat((Integer) result.getParameters().get(2), is(LENGTH));
}
private Date fromDate(Date date) {
return new DateBuilder(date).setMinMilliseconds().build();
}
private Date untilDate(Date date) {
return new DateBuilder(date).setMaxMilliseconds().build();
}
}