package org.socialsignin.spring.data.dynamodb.repository.query; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.io.Serializable; import java.lang.reflect.Field; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TimeZone; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; import org.socialsignin.spring.data.dynamodb.core.DynamoDBOperations; import org.socialsignin.spring.data.dynamodb.domain.sample.DynamoDBYearMarshaller; import org.socialsignin.spring.data.dynamodb.domain.sample.Playlist; import org.socialsignin.spring.data.dynamodb.domain.sample.PlaylistId; import org.socialsignin.spring.data.dynamodb.domain.sample.User; import org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBEntityInformation; import org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBIdIsHashAndRangeKeyEntityInformation; import org.springframework.data.repository.query.Parameter; import org.springframework.data.repository.query.Parameters; import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.util.ClassUtils; import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMarshaller; import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBQueryExpression; import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBScanExpression; import com.amazonaws.services.dynamodbv2.datamodeling.PaginatedQueryList; import com.amazonaws.services.dynamodbv2.datamodeling.PaginatedScanList; import com.amazonaws.services.dynamodbv2.model.ComparisonOperator; import com.amazonaws.services.dynamodbv2.model.Condition; import com.amazonaws.services.dynamodbv2.model.QueryRequest; @RunWith(MockitoJUnitRunner.class) public class PartTreeDynamoDBQueryUnitTest { private RepositoryQuery partTreeDynamoDBQuery; @Mock private DynamoDBOperations mockDynamoDBOperations; @Mock private DynamoDBQueryMethod<User, String> mockDynamoDBUserQueryMethod; @Mock private DynamoDBEntityInformation<User,String> mockUserEntityMetadata; @Mock private DynamoDBQueryMethod<Playlist, PlaylistId> mockDynamoDBPlaylistQueryMethod; @Mock private DynamoDBIdIsHashAndRangeKeyEntityInformation<Playlist,PlaylistId> mockPlaylistEntityMetadata; @Mock @SuppressWarnings("rawtypes") private Parameters mockParameters; @Mock private User mockUser; @Mock private Playlist mockPlaylist; @SuppressWarnings("rawtypes") @Mock private PaginatedScanList mockUserScanResults; @SuppressWarnings("rawtypes") @Mock private PaginatedScanList mockPlaylistScanResults; @SuppressWarnings("rawtypes") @Mock private PaginatedQueryList mockPlaylistQueryResults; @SuppressWarnings("rawtypes") @Mock private PaginatedQueryList mockUserQueryResults; @SuppressWarnings("rawtypes") @Mock private DynamoDBQueryCriteria mockCriteria; @SuppressWarnings("unchecked") @Before public void setUp() { Mockito.when(mockPlaylistEntityMetadata.isCompositeHashAndRangeKeyProperty("playlistId")).thenReturn(true); Mockito.when(mockPlaylistEntityMetadata.getHashKeyPropertyName()).thenReturn("userName"); Mockito.when(mockPlaylistEntityMetadata.isHashKeyProperty("userName")).thenReturn(true); Mockito.when(mockPlaylistEntityMetadata.getJavaType()).thenReturn(Playlist.class); Mockito.when(mockPlaylistEntityMetadata.getRangeKeyPropertyName()).thenReturn("playlistName"); Mockito.when(mockPlaylistEntityMetadata.getIndexRangeKeyPropertyNames()).thenReturn(new HashSet<String>()); Mockito.when(mockDynamoDBUserQueryMethod.getEntityInformation()).thenReturn(mockUserEntityMetadata); Mockito.when(mockDynamoDBUserQueryMethod.getParameters()).thenReturn(mockParameters); Mockito.when(mockDynamoDBPlaylistQueryMethod.getEntityInformation()).thenReturn(mockPlaylistEntityMetadata); Mockito.when(mockDynamoDBPlaylistQueryMethod.getParameters()).thenReturn(mockParameters); Mockito.when(mockUserEntityMetadata.getHashKeyPropertyName()).thenReturn("id"); Mockito.when(mockUserEntityMetadata.isHashKeyProperty("id")).thenReturn(true); Mockito.when(mockUserEntityMetadata.getJavaType()).thenReturn(User.class); Mockito.when(mockDynamoDBUserQueryMethod.isScanEnabled()).thenReturn(true); Mockito.when(mockDynamoDBPlaylistQueryMethod.isScanEnabled()).thenReturn(true); } @SuppressWarnings({ "rawtypes", "unchecked" }) private <T, ID extends Serializable> void setupCommonMocksForThisRepositoryMethod( DynamoDBEntityInformation<T, ID> mockEntityMetadata, DynamoDBQueryMethod<T, ID> mockDynamoDBQueryMethod, Class<T> clazz, String repositoryMethodName, int numberOfParameters, String hashKeyProperty, String rangeKeyProperty) { if (rangeKeyProperty != null) { Mockito.when(mockEntityMetadata.isRangeKeyAware()).thenReturn(true); } // Dirty Harry 9 3/4: In recent versions of spring-data-commons, a lot of methods within // org.springframework.data.repository.query.QueryMethod have become final. Thus they can't // be mocked by Mockito anymore https://github.com/mockito/mockito/wiki/FAQ#what-are-the-limitations-of-mockito // Therefore setting the field explicitly that is used by all the isXXX methods try { Field unwrappedReturnTypeField = mockDynamoDBQueryMethod.getClass() // Mockito-generated class .getSuperclass() // org.socialsignin.spring.data.dynamodb.repository.query.DynamoDBQueryMethod .getSuperclass() // org.springframework.data.repository.query.QueryMethod .getDeclaredField("unwrappedReturnType"); unwrappedReturnTypeField.setAccessible(true); // It's final therefore unlocking the field unwrappedReturnTypeField.set(mockDynamoDBQueryMethod, clazz); } catch (Exception e) { // There is little we can and want do if it fails - Aborting the whole test is fine throw new RuntimeException(e); } Class returnedObjectClass = clazz; Mockito.when(mockDynamoDBQueryMethod.getEntityType()).thenReturn(clazz); Mockito.when(mockDynamoDBQueryMethod.getName()).thenReturn(repositoryMethodName); Mockito.when(mockParameters.getNumberOfParameters()).thenReturn(numberOfParameters); Mockito.when(mockDynamoDBQueryMethod.getReturnedObjectType()).thenReturn(returnedObjectClass); if (hashKeyProperty != null) { Mockito.when(mockEntityMetadata.isHashKeyProperty(hashKeyProperty)).thenReturn(true); } for (int i = 0; i < numberOfParameters; i++) { Parameter mockParameter = Mockito.mock(Parameter.class); Mockito.when(mockParameter.getIndex()).thenReturn(i); Mockito.when(mockParameters.getBindableParameter(i)).thenReturn(mockParameter); } partTreeDynamoDBQuery = new PartTreeDynamoDBQuery(mockDynamoDBOperations, mockDynamoDBQueryMethod); } @Test public void testGetQueryMethod() { setupCommonMocksForThisRepositoryMethod(mockUserEntityMetadata, mockDynamoDBUserQueryMethod, User.class, "findById", 1, "id", null); assertEquals(mockDynamoDBUserQueryMethod, partTreeDynamoDBQuery.getQueryMethod()); } @Test public void testExecute_WhenFinderMethodIsFindingSingleEntity_WithSingleStringParameter_WhenFindingByHashKey() { setupCommonMocksForThisRepositoryMethod(mockUserEntityMetadata, mockDynamoDBUserQueryMethod, User.class, "findById", 1, "id", null); // Mock out specific DynamoDBOperations behavior expected by this method Mockito.when(mockDynamoDBOperations.load(User.class, "someId")).thenReturn(mockUser); // Execute the query Object[] parameters = new Object[] { "someId" }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected single result assertEquals(o, mockUser); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).load(User.class, "someId"); } @Test public void testExecute_WhenFinderMethodIsFindingSingleEntityWithCompositeId_WithSingleStringParameter_WhenFindingByHashAndRangeKey() { setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByUserNameAndPlaylistName", 2, "userName", "playlistName"); // Mock out specific DynamoDBOperations behavior expected by this method Mockito.when(mockDynamoDBOperations.load(Playlist.class, "someUserName", "somePlaylistName")).thenReturn( mockPlaylist); // Execute the query Object[] parameters = new Object[] { "someUserName", "somePlaylistName" }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected single result assertEquals(o, mockPlaylist); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).load(Playlist.class, "someUserName", "somePlaylistName"); } @Test public void testExecute_WhenFinderMethodIsFindingSingleEntityWithCompositeId_WhenFindingByCompositeId() { PlaylistId playlistId = new PlaylistId(); playlistId.setUserName("someUserName"); playlistId.setPlaylistName("somePlaylistName"); setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByPlaylistId", 1, "userName", "playlistName"); Mockito.when(mockPlaylistEntityMetadata.getHashKey(playlistId)).thenReturn("someUserName"); Mockito.when(mockPlaylistEntityMetadata.getRangeKey(playlistId)).thenReturn("somePlaylistName"); // Mock out specific DynamoDBOperations behavior expected by this method Mockito.when(mockDynamoDBOperations.load(Playlist.class, "someUserName", "somePlaylistName")).thenReturn( mockPlaylist); // Execute the query Object[] parameters = new Object[] { playlistId }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected single result assertEquals(o, mockPlaylist); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).load(Playlist.class, "someUserName", "somePlaylistName"); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test(expected=UnsupportedOperationException.class) public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeIdList_WhenFindingByNotCompositeId() { PlaylistId playlistId = new PlaylistId(); playlistId.setUserName("someUserName"); playlistId.setPlaylistName("somePlaylistName"); setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByPlaylistIdNot", 1, "userName", "playlistName"); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Mockito.when(mockPlaylistEntityMetadata.getHashKey(playlistId)).thenReturn("someUserName"); Mockito.when(mockPlaylistEntityMetadata.getRangeKey(playlistId)).thenReturn("somePlaylistName"); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBScanExpression> scanCaptor = ArgumentCaptor.forClass(DynamoDBScanExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockPlaylistScanResults.get(0)).thenReturn(mockPlaylist); Mockito.when(mockPlaylistScanResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.scan(classCaptor.capture(), scanCaptor.capture())).thenReturn( mockPlaylistScanResults); // Execute the query Object[] parameters = new Object[] { playlistId }; partTreeDynamoDBQuery.execute(parameters); } @Test @SuppressWarnings({ "unchecked", "rawtypes" }) public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeIdList_WhenFindingByRangeKeyOnly() { setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByPlaylistName", 1, "userName", "playlistName"); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBScanExpression> scanCaptor = ArgumentCaptor.forClass(DynamoDBScanExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockPlaylistScanResults.get(0)).thenReturn(mockPlaylist); Mockito.when(mockPlaylistScanResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.scan(classCaptor.capture(), scanCaptor.capture())).thenReturn( mockPlaylistScanResults); // Execute the query Object[] parameters = new Object[] { "somePlaylistName" }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(mockPlaylistScanResults, o); assertEquals(1, mockPlaylistScanResults.size()); assertEquals(mockPlaylist, mockPlaylistScanResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), Playlist.class); // Assert that we only one filter condition for the one property Map<String, Condition> filterConditions = scanCaptor.getValue().getScanFilter(); assertEquals(1, filterConditions.size()); Condition filterCondition = filterConditions.get("playlistName"); assertNotNull(filterCondition); assertEquals(ComparisonOperator.EQ.name(), filterCondition.getComparisonOperator()); // Assert we only have one attribute value for the filter condition assertEquals(1, filterCondition.getAttributeValueList().size()); // Assert that there the attribute value type for this attribute value // is String, // and its value is the parameter expected assertEquals("somePlaylistName", filterCondition.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(filterCondition.getAttributeValueList().get(0).getSS()); assertNull(filterCondition.getAttributeValueList().get(0).getN()); assertNull(filterCondition.getAttributeValueList().get(0).getNS()); assertNull(filterCondition.getAttributeValueList().get(0).getB()); assertNull(filterCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).scan(classCaptor.getValue(), scanCaptor.getValue()); } @Test @SuppressWarnings({ "unchecked", "rawtypes" }) public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeIdList_WhenFindingByCompositeIdWithRangeKeyOnly() { PlaylistId playlistId = new PlaylistId(); playlistId.setPlaylistName("somePlaylistName"); setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByPlaylistId", 1, "userName", "playlistName"); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Mockito.when(mockPlaylistEntityMetadata.getHashKey(playlistId)).thenReturn(null); Mockito.when(mockPlaylistEntityMetadata.getRangeKey(playlistId)).thenReturn("somePlaylistName"); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBScanExpression> scanCaptor = ArgumentCaptor.forClass(DynamoDBScanExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockPlaylistScanResults.get(0)).thenReturn(mockPlaylist); Mockito.when(mockPlaylistScanResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.scan(classCaptor.capture(), scanCaptor.capture())).thenReturn( mockPlaylistScanResults); // Execute the query Object[] parameters = new Object[] { playlistId }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(mockPlaylistScanResults, o); assertEquals(1, mockPlaylistScanResults.size()); assertEquals(mockPlaylist, mockPlaylistScanResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), Playlist.class); // Assert that we only one filter condition for the one property Map<String, Condition> filterConditions = scanCaptor.getValue().getScanFilter(); assertEquals(1, filterConditions.size()); Condition filterCondition = filterConditions.get("playlistName"); assertNotNull(filterCondition); assertEquals(ComparisonOperator.EQ.name(), filterCondition.getComparisonOperator()); // Assert we only have one attribute value for the filter condition assertEquals(1, filterCondition.getAttributeValueList().size()); // Assert that there the attribute value type for this attribute value // is String, // and its value is the parameter expected assertEquals("somePlaylistName", filterCondition.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(filterCondition.getAttributeValueList().get(0).getSS()); assertNull(filterCondition.getAttributeValueList().get(0).getN()); assertNull(filterCondition.getAttributeValueList().get(0).getNS()); assertNull(filterCondition.getAttributeValueList().get(0).getB()); assertNull(filterCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).scan(classCaptor.getValue(), scanCaptor.getValue()); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeIdList_WithSingleStringParameter_WhenFindingByHashKeyOnly() { setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByUserName", 1, "userName", "playlistName"); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Playlist prototypeHashKey = new Playlist(); prototypeHashKey.setUserName("someUserName"); Mockito.when(mockPlaylistEntityMetadata.getHashKeyPropotypeEntityForHashKey("someUserName")).thenReturn( prototypeHashKey); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBQueryExpression> queryCaptor = ArgumentCaptor.forClass(DynamoDBQueryExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockPlaylistQueryResults.get(0)).thenReturn(mockPlaylist); Mockito.when(mockPlaylistQueryResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.query(classCaptor.capture(), queryCaptor.capture())).thenReturn( mockPlaylistQueryResults); // Execute the query Object[] parameters = new Object[] { "someUserName" }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(mockPlaylistQueryResults, o); assertEquals(1, mockPlaylistQueryResults.size()); assertEquals(mockPlaylist, mockPlaylistQueryResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), Playlist.class); // Assert that we have only one filter condition, for the name of the // property Object hashKeyPrototypeObject = queryCaptor.getValue().getHashKeyValues(); assertTrue(hashKeyPrototypeObject instanceof Playlist); Playlist hashKeyPropertyPlaylist = (Playlist) hashKeyPrototypeObject; assertEquals("someUserName", hashKeyPropertyPlaylist.getUserName()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).query(classCaptor.getValue(), queryCaptor.getValue()); } @SuppressWarnings("unchecked") @Test public void testExecute_WhenFinderMethodIsCountingEntityWithCompositeIdList_WhenFindingByRangeKeyOnly_ScanCountEnabled() { setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "countByPlaylistName", 1, "userName", "playlistName"); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(false); Mockito.when(mockDynamoDBPlaylistQueryMethod.isScanCountEnabled()).thenReturn(true); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBScanExpression> scanCaptor = ArgumentCaptor.forClass(DynamoDBScanExpression.class); @SuppressWarnings("rawtypes") ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockDynamoDBOperations.count(classCaptor.capture(), scanCaptor.capture())).thenReturn( 100); // Execute the query Object[] parameters = new Object[] { "somePlaylistName" }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(100l, o); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), Playlist.class); // Assert that we only one filter condition for the one property Map<String, Condition> filterConditions = scanCaptor.getValue().getScanFilter(); assertEquals(1, filterConditions.size()); Condition filterCondition = filterConditions.get("playlistName"); assertNotNull(filterCondition); assertEquals(ComparisonOperator.EQ.name(), filterCondition.getComparisonOperator()); // Assert we only have one attribute value for the filter condition assertEquals(1, filterCondition.getAttributeValueList().size()); // Assert that there the attribute value type for this attribute value // is String, // and its value is the parameter expected assertEquals("somePlaylistName", filterCondition.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(filterCondition.getAttributeValueList().get(0).getSS()); assertNull(filterCondition.getAttributeValueList().get(0).getN()); assertNull(filterCondition.getAttributeValueList().get(0).getNS()); assertNull(filterCondition.getAttributeValueList().get(0).getB()); assertNull(filterCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).count(classCaptor.getValue(), scanCaptor.getValue()); } @SuppressWarnings("unchecked") @Test(expected=IllegalArgumentException.class) public void testExecute_WhenFinderMethodIsCountingEntityWithCompositeIdList_WhenFindingByRangeKeyOnly_ScanCountDisabled() { setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "countByPlaylistName", 1, "userName", "playlistName"); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(false); Mockito.when(mockDynamoDBPlaylistQueryMethod.isScanCountEnabled()).thenReturn(false); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBScanExpression> scanCaptor = ArgumentCaptor.forClass(DynamoDBScanExpression.class); @SuppressWarnings("rawtypes") ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockDynamoDBOperations.count(classCaptor.capture(), scanCaptor.capture())).thenReturn( 100); // Execute the query Object[] parameters = new Object[] { "somePlaylistName" }; partTreeDynamoDBQuery.execute(parameters); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeIdList_WithSingleStringParameter_WhenFindingByHashKeyAndNotRangeKey() { setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByUserNameAndPlaylistNameNot", 2, "userName", "playlistName"); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Playlist prototypeHashKey = new Playlist(); prototypeHashKey.setUserName("someUserName"); Mockito.when(mockPlaylistEntityMetadata.getHashKeyPropotypeEntityForHashKey("someUserName")).thenReturn( prototypeHashKey); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBScanExpression> scanCaptor = ArgumentCaptor.forClass(DynamoDBScanExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockPlaylistScanResults.get(0)).thenReturn(mockPlaylist); Mockito.when(mockPlaylistScanResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.scan(classCaptor.capture(), scanCaptor.capture())).thenReturn( mockPlaylistScanResults); // Execute the query Object[] parameters = new Object[] { "someUserName", "somePlaylistName" }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(mockPlaylistScanResults, o); assertEquals(1, mockPlaylistScanResults.size()); assertEquals(mockPlaylist, mockPlaylistScanResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), Playlist.class); // Assert that we have the correct filter conditions Map<String, Condition> filterConditions = scanCaptor.getValue().getScanFilter(); assertEquals(2, filterConditions.size()); Condition filterCondition1 = filterConditions.get("userName"); Condition filterCondition2 = filterConditions.get("playlistName"); assertEquals(ComparisonOperator.EQ.name(), filterCondition1.getComparisonOperator()); assertEquals(ComparisonOperator.NE.name(), filterCondition2.getComparisonOperator()); // Assert we only have one attribute value for this filter condition assertEquals(1, filterCondition1.getAttributeValueList().size()); assertEquals(1, filterCondition2.getAttributeValueList().size()); // Assert that there the attribute value type for this attribute value // is String, // and its value is the parameter expected assertEquals("someUserName", filterCondition1.getAttributeValueList().get(0).getS()); assertEquals("somePlaylistName", filterCondition2.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(filterCondition1.getAttributeValueList().get(0).getSS()); assertNull(filterCondition1.getAttributeValueList().get(0).getN()); assertNull(filterCondition1.getAttributeValueList().get(0).getNS()); assertNull(filterCondition1.getAttributeValueList().get(0).getB()); assertNull(filterCondition1.getAttributeValueList().get(0).getBS()); assertNull(filterCondition2.getAttributeValueList().get(0).getSS()); assertNull(filterCondition2.getAttributeValueList().get(0).getN()); assertNull(filterCondition2.getAttributeValueList().get(0).getNS()); assertNull(filterCondition2.getAttributeValueList().get(0).getB()); assertNull(filterCondition2.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).scan(classCaptor.getValue(), scanCaptor.getValue()); // Assert // that // we // obtain // the // expected // results } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeIdList_WhenFindingByCompositeIdWithHashKeyOnly() { PlaylistId playlistId = new PlaylistId(); playlistId.setUserName("someUserName"); setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByPlaylistId", 1, "userName", "playlistName"); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Playlist prototypeHashKey = new Playlist(); prototypeHashKey.setUserName("someUserName"); Mockito.when(mockPlaylistEntityMetadata.getHashKeyPropotypeEntityForHashKey("someUserName")).thenReturn( prototypeHashKey); Mockito.when(mockPlaylistEntityMetadata.getHashKey(playlistId)).thenReturn("someUserName"); Mockito.when(mockPlaylistEntityMetadata.getRangeKey(playlistId)).thenReturn(null); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBQueryExpression> queryCaptor = ArgumentCaptor.forClass(DynamoDBQueryExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockPlaylistQueryResults.get(0)).thenReturn(mockPlaylist); Mockito.when(mockPlaylistQueryResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.query(classCaptor.capture(), queryCaptor.capture())).thenReturn( mockPlaylistQueryResults); // Execute the query Object[] parameters = new Object[] { playlistId }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(mockPlaylistQueryResults, o); assertEquals(1, mockPlaylistQueryResults.size()); assertEquals(mockPlaylist, mockPlaylistQueryResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), Playlist.class); // Assert that we have only one filter condition, for the name of the // property Object hashKeyPrototypeObject = queryCaptor.getValue().getHashKeyValues(); assertTrue(hashKeyPrototypeObject instanceof Playlist); Playlist hashKeyPropertyPlaylist = (Playlist) hashKeyPrototypeObject; assertEquals("someUserName", hashKeyPropertyPlaylist.getUserName()); assertEquals(0,queryCaptor.getValue().getRangeKeyConditions().size()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).query(classCaptor.getValue(), queryCaptor.getValue()); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeIdList_WhenFindingByCompositeId_HashKey() { PlaylistId playlistId = new PlaylistId(); playlistId.setUserName("someUserName"); setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByPlaylistIdUserName", 1, "userName", "playlistName"); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Playlist prototypeHashKey = new Playlist(); prototypeHashKey.setUserName("someUserName"); Mockito.when(mockPlaylistEntityMetadata.getHashKeyPropotypeEntityForHashKey("someUserName")).thenReturn( prototypeHashKey); Mockito.when(mockPlaylistEntityMetadata.getHashKey(playlistId)).thenReturn("someUserName"); Mockito.when(mockPlaylistEntityMetadata.getRangeKey(playlistId)).thenReturn(null); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBQueryExpression> queryCaptor = ArgumentCaptor.forClass(DynamoDBQueryExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockPlaylistQueryResults.get(0)).thenReturn(mockPlaylist); Mockito.when(mockPlaylistQueryResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.query(classCaptor.capture(), queryCaptor.capture())).thenReturn( mockPlaylistQueryResults); // Execute the query Object[] parameters = new Object[] { "someUserName" }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(mockPlaylistQueryResults, o); assertEquals(1, mockPlaylistQueryResults.size()); assertEquals(mockPlaylist, mockPlaylistQueryResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), Playlist.class); // Assert that we have only one filter condition, for the name of the // property Object hashKeyPrototypeObject = queryCaptor.getValue().getHashKeyValues(); assertTrue(hashKeyPrototypeObject instanceof Playlist); Playlist hashKeyPropertyPlaylist = (Playlist) hashKeyPrototypeObject; assertEquals("someUserName", hashKeyPropertyPlaylist.getUserName()); assertEquals(0,queryCaptor.getValue().getRangeKeyConditions().size()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).query(classCaptor.getValue(), queryCaptor.getValue()); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeIdList_WhenFindingByCompositeId_HashKeyAndIndexRangeKey() { PlaylistId playlistId = new PlaylistId(); playlistId.setUserName("someUserName"); setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByPlaylistIdUserNameAndDisplayName", 2, "userName", "playlistName"); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Playlist prototypeHashKey = new Playlist(); prototypeHashKey.setUserName("someUserName"); Mockito.when(mockPlaylistEntityMetadata.getHashKeyPropotypeEntityForHashKey("someUserName")).thenReturn( prototypeHashKey); Mockito.when(mockPlaylistEntityMetadata.getHashKey(playlistId)).thenReturn("someUserName"); Mockito.when(mockPlaylistEntityMetadata.getRangeKey(playlistId)).thenReturn(null); Set<String> indexRangeKeyPropertyNames = new HashSet<String>(); indexRangeKeyPropertyNames.add("displayName"); Mockito.when(mockPlaylistEntityMetadata.getIndexRangeKeyPropertyNames()).thenReturn(indexRangeKeyPropertyNames); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBQueryExpression> queryCaptor = ArgumentCaptor.forClass(DynamoDBQueryExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockPlaylistQueryResults.get(0)).thenReturn(mockPlaylist); Mockito.when(mockPlaylistQueryResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.query(classCaptor.capture(), queryCaptor.capture())).thenReturn( mockPlaylistQueryResults); // Execute the query Object[] parameters = new Object[] { "someUserName","someDisplayName" }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(mockPlaylistQueryResults, o); assertEquals(1, mockPlaylistQueryResults.size()); assertEquals(mockPlaylist, mockPlaylistQueryResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), Playlist.class); // Assert that we have two filter condition, for the name of the // property Object hashKeyPrototypeObject = queryCaptor.getValue().getHashKeyValues(); assertTrue(hashKeyPrototypeObject instanceof Playlist); Playlist hashKeyPropertyPlaylist = (Playlist) hashKeyPrototypeObject; assertEquals("someUserName", hashKeyPropertyPlaylist.getUserName()); assertEquals(1,queryCaptor.getValue().getRangeKeyConditions().size()); Condition condition = (Condition) queryCaptor.getValue().getRangeKeyConditions().get("displayName"); assertEquals(ComparisonOperator.EQ.name(),condition.getComparisonOperator()); assertEquals(1,condition.getAttributeValueList().size()); assertEquals("someDisplayName",condition.getAttributeValueList().get(0).getS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).query(classCaptor.getValue(), queryCaptor.getValue()); } @Test public void testExecute_WhenFinderMethodIsFindingSingleEntityWithCompositeId_WhenFindingByCompositeId_HashKeyAndCompositeId_RangeKey() { PlaylistId playlistId = new PlaylistId(); playlistId.setUserName("someUserName"); playlistId.setPlaylistName("somePlaylistName"); setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByPlaylistIdUserNameAndPlaylistIdPlaylistName", 2, "userName", "playlistName"); Mockito.when(mockPlaylistEntityMetadata.getHashKey(playlistId)).thenReturn("someUserName"); Mockito.when(mockPlaylistEntityMetadata.getRangeKey(playlistId)).thenReturn("somePlaylistName"); // Mock out specific DynamoDBOperations behavior expected by this method Mockito.when(mockDynamoDBOperations.load(Playlist.class, "someUserName", "somePlaylistName")).thenReturn( mockPlaylist); // Execute the query Object[] parameters = new Object[] { "someUserName","somePlaylistName" }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected single result assertEquals(o, mockPlaylist); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).load(Playlist.class, "someUserName", "somePlaylistName"); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeIdList_WhenFindingByCompositeIdWithHashKeyOnly_WhenSortingByRangeKey() { PlaylistId playlistId = new PlaylistId(); playlistId.setUserName("someUserName"); setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByPlaylistIdOrderByPlaylistNameDesc", 1, "userName", "playlistName"); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Playlist prototypeHashKey = new Playlist(); prototypeHashKey.setUserName("someUserName"); Mockito.when(mockPlaylistEntityMetadata.getHashKeyPropotypeEntityForHashKey("someUserName")).thenReturn( prototypeHashKey); Mockito.when(mockPlaylistEntityMetadata.getHashKey(playlistId)).thenReturn("someUserName"); Mockito.when(mockPlaylistEntityMetadata.getRangeKey(playlistId)).thenReturn(null); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBQueryExpression> queryCaptor = ArgumentCaptor.forClass(DynamoDBQueryExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockPlaylistQueryResults.get(0)).thenReturn(mockPlaylist); Mockito.when(mockPlaylistQueryResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.query(classCaptor.capture(), queryCaptor.capture())).thenReturn( mockPlaylistQueryResults); // Execute the query Object[] parameters = new Object[] { playlistId }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(mockPlaylistQueryResults, o); assertEquals(1, mockPlaylistQueryResults.size()); assertEquals(mockPlaylist, mockPlaylistQueryResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), Playlist.class); // Assert that we have only one filter condition, for the name of the // property Object hashKeyPrototypeObject = queryCaptor.getValue().getHashKeyValues(); assertTrue(hashKeyPrototypeObject instanceof Playlist); Playlist hashKeyPropertyPlaylist = (Playlist) hashKeyPrototypeObject; assertEquals("someUserName", hashKeyPropertyPlaylist.getUserName()); assertEquals(0,queryCaptor.getValue().getRangeKeyConditions().size()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).query(classCaptor.getValue(), queryCaptor.getValue()); } @SuppressWarnings({ "unchecked", "rawtypes" }) // Can't sort by indexrangekey when querying by hash key only @Test(expected=UnsupportedOperationException.class) public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeIdList_WhenFindingByCompositeIdWithHashKeyOnly_WhenSortingByIndexRangeKey() { PlaylistId playlistId = new PlaylistId(); playlistId.setUserName("someUserName"); setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByPlaylistIdOrderByDisplayNameDesc", 1, "userName", "playlistName"); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Playlist prototypeHashKey = new Playlist(); prototypeHashKey.setUserName("someUserName"); Mockito.when(mockPlaylistEntityMetadata.getHashKeyPropotypeEntityForHashKey("someUserName")).thenReturn( prototypeHashKey); Mockito.when(mockPlaylistEntityMetadata.getHashKey(playlistId)).thenReturn("someUserName"); Mockito.when(mockPlaylistEntityMetadata.getRangeKey(playlistId)).thenReturn(null); Set<String> indexRangeKeyPropertyNames = new HashSet<String>(); indexRangeKeyPropertyNames.add("displayName"); Mockito.when(mockPlaylistEntityMetadata.getIndexRangeKeyPropertyNames()).thenReturn(indexRangeKeyPropertyNames); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBQueryExpression> queryCaptor = ArgumentCaptor.forClass(DynamoDBQueryExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockPlaylistQueryResults.get(0)).thenReturn(mockPlaylist); Mockito.when(mockPlaylistQueryResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.query(classCaptor.capture(), queryCaptor.capture())).thenReturn( mockPlaylistQueryResults); // Execute the query Object[] parameters = new Object[] { playlistId }; partTreeDynamoDBQuery.execute(parameters); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeIdList_WhenFindingByHashKeyAndIndexRangeKey() { setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByUserNameAndDisplayName", 2, "userName", "playlistName"); Set<String> indexRangeKeyPropertyNames = new HashSet<String>(); indexRangeKeyPropertyNames.add("displayName"); Mockito.when(mockPlaylistEntityMetadata.getIndexRangeKeyPropertyNames()).thenReturn(indexRangeKeyPropertyNames); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Playlist prototypeHashKey = new Playlist(); prototypeHashKey.setUserName("someUserName"); Mockito.when(mockPlaylistEntityMetadata.getHashKeyPropotypeEntityForHashKey("someUserName")).thenReturn( prototypeHashKey); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBQueryExpression> queryCaptor = ArgumentCaptor.forClass(DynamoDBQueryExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockPlaylistQueryResults.get(0)).thenReturn(mockPlaylist); Mockito.when(mockPlaylistQueryResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.query(classCaptor.capture(), queryCaptor.capture())).thenReturn( mockPlaylistQueryResults); // Execute the query Object[] parameters = new Object[] { "someUserName","someDisplayName" }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(mockPlaylistQueryResults, o); assertEquals(1, mockPlaylistQueryResults.size()); assertEquals(mockPlaylist, mockPlaylistQueryResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), Playlist.class); // Assert that we have only one filter condition for the hash key,and for the index range key Object hashKeyPrototypeObject = queryCaptor.getValue().getHashKeyValues(); assertTrue(hashKeyPrototypeObject instanceof Playlist); Playlist hashKeyPropertyPlaylist = (Playlist) hashKeyPrototypeObject; assertEquals("someUserName", hashKeyPropertyPlaylist.getUserName()); assertEquals(1,queryCaptor.getValue().getRangeKeyConditions().size()); Condition condition = (Condition) queryCaptor.getValue().getRangeKeyConditions().get("displayName"); assertEquals(ComparisonOperator.EQ.name(),condition.getComparisonOperator()); assertEquals(1,condition.getAttributeValueList().size()); assertEquals("someDisplayName",condition.getAttributeValueList().get(0).getS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).query(classCaptor.getValue(), queryCaptor.getValue()); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeIdList_WhenFindingByHashKeyAndIndexRangeKey_WithValidOrderSpecified() { setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByUserNameAndDisplayNameOrderByDisplayNameDesc", 2, "userName", "playlistName"); Set<String> indexRangeKeyPropertyNames = new HashSet<String>(); indexRangeKeyPropertyNames.add("displayName"); Mockito.when(mockPlaylistEntityMetadata.getIndexRangeKeyPropertyNames()).thenReturn(indexRangeKeyPropertyNames); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Playlist prototypeHashKey = new Playlist(); prototypeHashKey.setUserName("someUserName"); Mockito.when(mockPlaylistEntityMetadata.getHashKeyPropotypeEntityForHashKey("someUserName")).thenReturn( prototypeHashKey); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBQueryExpression> queryCaptor = ArgumentCaptor.forClass(DynamoDBQueryExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockPlaylistQueryResults.get(0)).thenReturn(mockPlaylist); Mockito.when(mockPlaylistQueryResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.query(classCaptor.capture(), queryCaptor.capture())).thenReturn( mockPlaylistQueryResults); // Execute the query Object[] parameters = new Object[] { "someUserName","someDisplayName" }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(mockPlaylistQueryResults, o); assertEquals(1, mockPlaylistQueryResults.size()); assertEquals(mockPlaylist, mockPlaylistQueryResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), Playlist.class); // Assert that we have only one filter condition for the hash key,and for the index range key Object hashKeyPrototypeObject = queryCaptor.getValue().getHashKeyValues(); assertTrue(hashKeyPrototypeObject instanceof Playlist); Playlist hashKeyPropertyPlaylist = (Playlist) hashKeyPrototypeObject; assertEquals("someUserName", hashKeyPropertyPlaylist.getUserName()); assertEquals(1,queryCaptor.getValue().getRangeKeyConditions().size()); Condition condition = (Condition) queryCaptor.getValue().getRangeKeyConditions().get("displayName"); assertEquals(ComparisonOperator.EQ.name(),condition.getComparisonOperator()); assertEquals(1,condition.getAttributeValueList().size()); assertEquals("someDisplayName",condition.getAttributeValueList().get(0).getS()); Assert.assertFalse(queryCaptor.getValue().isScanIndexForward()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).query(classCaptor.getValue(), queryCaptor.getValue()); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test(expected=UnsupportedOperationException.class) public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeIdList_WhenFindingByHashKeyAndIndexRangeKey_WithInvalidOrderSpecified() { setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByUserNameAndDisplayNameOrderByPlaylistNameDesc", 2, "userName", "playlistName"); Set<String> indexRangeKeyPropertyNames = new HashSet<String>(); indexRangeKeyPropertyNames.add("displayName"); Mockito.when(mockPlaylistEntityMetadata.getIndexRangeKeyPropertyNames()).thenReturn(indexRangeKeyPropertyNames); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Playlist prototypeHashKey = new Playlist(); prototypeHashKey.setUserName("someUserName"); Mockito.when(mockPlaylistEntityMetadata.getHashKeyPropotypeEntityForHashKey("someUserName")).thenReturn( prototypeHashKey); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBQueryExpression> queryCaptor = ArgumentCaptor.forClass(DynamoDBQueryExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockPlaylistQueryResults.get(0)).thenReturn(mockPlaylist); Mockito.when(mockPlaylistQueryResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.query(classCaptor.capture(), queryCaptor.capture())).thenReturn( mockPlaylistQueryResults); // Execute the query Object[] parameters = new Object[] { "someUserName","someDisplayName" }; partTreeDynamoDBQuery.execute(parameters); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeIdList_WhenFindingByHashKeyAndIndexRangeKey_OrderByIndexRangeKey() { setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByUserNameAndDisplayNameOrderByDisplayNameDesc", 2, "userName", "playlistName"); Set<String> indexRangeKeyPropertyNames = new HashSet<String>(); indexRangeKeyPropertyNames.add("displayName"); Mockito.when(mockPlaylistEntityMetadata.getIndexRangeKeyPropertyNames()).thenReturn(indexRangeKeyPropertyNames); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Playlist prototypeHashKey = new Playlist(); prototypeHashKey.setUserName("someUserName"); Mockito.when(mockPlaylistEntityMetadata.getHashKeyPropotypeEntityForHashKey("someUserName")).thenReturn( prototypeHashKey); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBQueryExpression> queryCaptor = ArgumentCaptor.forClass(DynamoDBQueryExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockPlaylistQueryResults.get(0)).thenReturn(mockPlaylist); Mockito.when(mockPlaylistQueryResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.query(classCaptor.capture(), queryCaptor.capture())).thenReturn( mockPlaylistQueryResults); // Execute the query Object[] parameters = new Object[] { "someUserName","someDisplayName" }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(mockPlaylistQueryResults, o); assertEquals(1, mockPlaylistQueryResults.size()); assertEquals(mockPlaylist, mockPlaylistQueryResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), Playlist.class); // Assert that we have only one filter condition for the hash key,and for the index range key Object hashKeyPrototypeObject = queryCaptor.getValue().getHashKeyValues(); assertTrue(hashKeyPrototypeObject instanceof Playlist); Playlist hashKeyPropertyPlaylist = (Playlist) hashKeyPrototypeObject; assertEquals("someUserName", hashKeyPropertyPlaylist.getUserName()); assertEquals(1,queryCaptor.getValue().getRangeKeyConditions().size()); Condition condition = (Condition) queryCaptor.getValue().getRangeKeyConditions().get("displayName"); assertEquals(ComparisonOperator.EQ.name(),condition.getComparisonOperator()); assertEquals(1,condition.getAttributeValueList().size()); assertEquals("someDisplayName",condition.getAttributeValueList().get(0).getS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).query(classCaptor.getValue(), queryCaptor.getValue()); } @SuppressWarnings({ "unchecked", "rawtypes" }) // Sorting by range key when querying by indexrangekey not supported @Test(expected=UnsupportedOperationException.class) public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeIdList_WhenFindingByHashKeyAndIndexRangeKey_OrderByRangeKey() { setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByUserNameAndDisplayNameOrderByPlaylistNameDesc", 2, "userName", "playlistName"); Set<String> indexRangeKeyPropertyNames = new HashSet<String>(); indexRangeKeyPropertyNames.add("displayName"); Mockito.when(mockPlaylistEntityMetadata.getIndexRangeKeyPropertyNames()).thenReturn(indexRangeKeyPropertyNames); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Playlist prototypeHashKey = new Playlist(); prototypeHashKey.setUserName("someUserName"); Mockito.when(mockPlaylistEntityMetadata.getHashKeyPropotypeEntityForHashKey("someUserName")).thenReturn( prototypeHashKey); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBQueryExpression> queryCaptor = ArgumentCaptor.forClass(DynamoDBQueryExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockPlaylistQueryResults.get(0)).thenReturn(mockPlaylist); Mockito.when(mockPlaylistQueryResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.query(classCaptor.capture(), queryCaptor.capture())).thenReturn( mockPlaylistQueryResults); // Execute the query Object[] parameters = new Object[] { "someUserName","someDisplayName" }; partTreeDynamoDBQuery.execute(parameters); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeIdList_WhenFindingByHashKeyAndIndexRangeKeyWithOveriddenName() { setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByUserNameAndDisplayName", 2, "userName", "playlistName"); Set<String> indexRangeKeyPropertyNames = new HashSet<String>(); indexRangeKeyPropertyNames.add("displayName"); Mockito.when(mockPlaylistEntityMetadata.getIndexRangeKeyPropertyNames()).thenReturn(indexRangeKeyPropertyNames); Mockito.when(mockPlaylistEntityMetadata.getOverriddenAttributeName("displayName")).thenReturn("DisplayName"); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Playlist prototypeHashKey = new Playlist(); prototypeHashKey.setUserName("someUserName"); Mockito.when(mockPlaylistEntityMetadata.getHashKeyPropotypeEntityForHashKey("someUserName")).thenReturn( prototypeHashKey); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBQueryExpression> queryCaptor = ArgumentCaptor.forClass(DynamoDBQueryExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockPlaylistQueryResults.get(0)).thenReturn(mockPlaylist); Mockito.when(mockPlaylistQueryResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.query(classCaptor.capture(), queryCaptor.capture())).thenReturn( mockPlaylistQueryResults); // Execute the query Object[] parameters = new Object[] { "someUserName","someDisplayName" }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(mockPlaylistQueryResults, o); assertEquals(1, mockPlaylistQueryResults.size()); assertEquals(mockPlaylist, mockPlaylistQueryResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), Playlist.class); // Assert that we have only one filter condition for the hash key,and for the index range key Object hashKeyPrototypeObject = queryCaptor.getValue().getHashKeyValues(); assertTrue(hashKeyPrototypeObject instanceof Playlist); Playlist hashKeyPropertyPlaylist = (Playlist) hashKeyPrototypeObject; assertEquals("someUserName", hashKeyPropertyPlaylist.getUserName()); assertEquals(1,queryCaptor.getValue().getRangeKeyConditions().size()); Condition condition = (Condition) queryCaptor.getValue().getRangeKeyConditions().get("DisplayName"); assertEquals(ComparisonOperator.EQ.name(),condition.getComparisonOperator()); assertEquals(1,condition.getAttributeValueList().size()); assertEquals("someDisplayName",condition.getAttributeValueList().get(0).getS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).query(classCaptor.getValue(), queryCaptor.getValue()); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeIdList_WhenFindingByCompositeIdWithHashKeyOnlyAndByAnotherPropertyWithOverriddenAttributeName() { PlaylistId playlistId = new PlaylistId(); playlistId.setUserName("someUserName"); setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByPlaylistIdAndDisplayName", 2, "userName", "playlistName"); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Playlist prototypeHashKey = new Playlist(); prototypeHashKey.setUserName("someUserName"); Mockito.when(mockPlaylistEntityMetadata.getHashKeyPropotypeEntityForHashKey("someUserName")).thenReturn( prototypeHashKey); Mockito.when(mockPlaylistEntityMetadata.getHashKey(playlistId)).thenReturn("someUserName"); Mockito.when(mockPlaylistEntityMetadata.getRangeKey(playlistId)).thenReturn(null); Mockito.when(mockPlaylistEntityMetadata.getOverriddenAttributeName("displayName")).thenReturn("DisplayName"); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBScanExpression> scanCaptor = ArgumentCaptor.forClass(DynamoDBScanExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockUserScanResults.get(0)).thenReturn(mockUser); Mockito.when(mockUserScanResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.scan(classCaptor.capture(), scanCaptor.capture())).thenReturn( mockUserScanResults); // Execute the query Object[] parameters = new Object[] { playlistId, "someDisplayName" }; partTreeDynamoDBQuery.execute(parameters); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), Playlist.class); // Assert that we have only three filter conditions Map<String, Condition> filterConditions = scanCaptor.getValue().getScanFilter(); assertEquals(2, filterConditions.size()); Condition filterCondition1 = filterConditions.get("userName"); Condition filterCondition2 = filterConditions.get("DisplayName"); assertEquals(ComparisonOperator.EQ.name(), filterCondition1.getComparisonOperator()); assertEquals(ComparisonOperator.EQ.name(), filterCondition2.getComparisonOperator()); // Assert we only have one attribute value for this filter condition assertEquals(1, filterCondition1.getAttributeValueList().size()); assertEquals(1, filterCondition2.getAttributeValueList().size()); // Assert that there the attribute value type for this attribute value // is String, // and its value is the parameter expected assertEquals("someUserName", filterCondition1.getAttributeValueList().get(0).getS()); assertEquals("someDisplayName", filterCondition2.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(filterCondition1.getAttributeValueList().get(0).getSS()); assertNull(filterCondition1.getAttributeValueList().get(0).getN()); assertNull(filterCondition1.getAttributeValueList().get(0).getNS()); assertNull(filterCondition1.getAttributeValueList().get(0).getB()); assertNull(filterCondition1.getAttributeValueList().get(0).getBS()); assertNull(filterCondition2.getAttributeValueList().get(0).getSS()); assertNull(filterCondition2.getAttributeValueList().get(0).getN()); assertNull(filterCondition2.getAttributeValueList().get(0).getNS()); assertNull(filterCondition2.getAttributeValueList().get(0).getB()); assertNull(filterCondition2.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).scan(classCaptor.getValue(), scanCaptor.getValue()); // Assert // that // we // obtain // the // expected // results } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeIdList_WhenFindingByCompositeIdWithRangeKeyOnlyAndByAnotherPropertyWithOverriddenAttributeName() { PlaylistId playlistId = new PlaylistId(); playlistId.setPlaylistName("somePlaylistName"); setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByPlaylistIdAndDisplayName", 2, "userName", "playlistName"); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Playlist prototypeHashKey = new Playlist(); prototypeHashKey.setUserName("someUserName"); Mockito.when(mockPlaylistEntityMetadata.getHashKey(playlistId)).thenReturn(null); Mockito.when(mockPlaylistEntityMetadata.getRangeKey(playlistId)).thenReturn("somePlaylistName"); Mockito.when(mockPlaylistEntityMetadata.getOverriddenAttributeName("displayName")).thenReturn("DisplayName"); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBScanExpression> scanCaptor = ArgumentCaptor.forClass(DynamoDBScanExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockUserScanResults.get(0)).thenReturn(mockUser); Mockito.when(mockUserScanResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.scan(classCaptor.capture(), scanCaptor.capture())).thenReturn( mockUserScanResults); // Execute the query Object[] parameters = new Object[] { playlistId, "someDisplayName" }; partTreeDynamoDBQuery.execute(parameters); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), Playlist.class); // Assert that we have only three filter conditions Map<String, Condition> filterConditions = scanCaptor.getValue().getScanFilter(); assertEquals(2, filterConditions.size()); Condition filterCondition1 = filterConditions.get("playlistName"); Condition filterCondition2 = filterConditions.get("DisplayName"); assertEquals(ComparisonOperator.EQ.name(), filterCondition1.getComparisonOperator()); assertEquals(ComparisonOperator.EQ.name(), filterCondition2.getComparisonOperator()); // Assert we only have one attribute value for this filter condition assertEquals(1, filterCondition1.getAttributeValueList().size()); assertEquals(1, filterCondition2.getAttributeValueList().size()); // Assert that there the attribute value type for this attribute value // is String, // and its value is the parameter expected assertEquals("somePlaylistName", filterCondition1.getAttributeValueList().get(0).getS()); assertEquals("someDisplayName", filterCondition2.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(filterCondition1.getAttributeValueList().get(0).getSS()); assertNull(filterCondition1.getAttributeValueList().get(0).getN()); assertNull(filterCondition1.getAttributeValueList().get(0).getNS()); assertNull(filterCondition1.getAttributeValueList().get(0).getB()); assertNull(filterCondition1.getAttributeValueList().get(0).getBS()); assertNull(filterCondition2.getAttributeValueList().get(0).getSS()); assertNull(filterCondition2.getAttributeValueList().get(0).getN()); assertNull(filterCondition2.getAttributeValueList().get(0).getNS()); assertNull(filterCondition2.getAttributeValueList().get(0).getB()); assertNull(filterCondition2.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).scan(classCaptor.getValue(), scanCaptor.getValue()); // Assert // that // we // obtain // the // expected // results } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeIdList_WhenFindingByNotHashKeyAndNotRangeKey() { setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByUserNameNotAndPlaylistNameNot", 2, "userName", "playlistName"); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBScanExpression> scanCaptor = ArgumentCaptor.forClass(DynamoDBScanExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockUserScanResults.get(0)).thenReturn(mockUser); Mockito.when(mockUserScanResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.scan(classCaptor.capture(), scanCaptor.capture())).thenReturn( mockUserScanResults); // Execute the query Object[] parameters = new Object[] { "someUserName", "somePlaylistName" }; partTreeDynamoDBQuery.execute(parameters); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), Playlist.class); // Assert that we have only three filter conditions Map<String, Condition> filterConditions = scanCaptor.getValue().getScanFilter(); assertEquals(2, filterConditions.size()); Condition filterCondition1 = filterConditions.get("userName"); Condition filterCondition2 = filterConditions.get("playlistName"); assertEquals(ComparisonOperator.NE.name(), filterCondition1.getComparisonOperator()); assertEquals(ComparisonOperator.NE.name(), filterCondition2.getComparisonOperator()); // Assert we only have one attribute value for this filter condition assertEquals(1, filterCondition1.getAttributeValueList().size()); assertEquals(1, filterCondition2.getAttributeValueList().size()); // Assert that there the attribute value type for this attribute value // is String, // and its value is the parameter expected assertEquals("someUserName", filterCondition1.getAttributeValueList().get(0).getS()); assertEquals("somePlaylistName", filterCondition2.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(filterCondition1.getAttributeValueList().get(0).getSS()); assertNull(filterCondition1.getAttributeValueList().get(0).getN()); assertNull(filterCondition1.getAttributeValueList().get(0).getNS()); assertNull(filterCondition1.getAttributeValueList().get(0).getB()); assertNull(filterCondition1.getAttributeValueList().get(0).getBS()); assertNull(filterCondition2.getAttributeValueList().get(0).getSS()); assertNull(filterCondition2.getAttributeValueList().get(0).getN()); assertNull(filterCondition2.getAttributeValueList().get(0).getNS()); assertNull(filterCondition2.getAttributeValueList().get(0).getB()); assertNull(filterCondition2.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).scan(classCaptor.getValue(), scanCaptor.getValue()); // Assert // that // we // obtain // the // expected // results } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeIdList_WhenFindingByCompositeIdAndByAnotherPropertyWithOverriddenAttributeName() { PlaylistId playlistId = new PlaylistId(); playlistId.setUserName("someUserName"); playlistId.setPlaylistName("somePlaylistName"); setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByPlaylistIdAndDisplayName", 2, "userName", "playlistName"); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Playlist prototypeHashKey = new Playlist(); prototypeHashKey.setUserName("someUserName"); Mockito.when(mockPlaylistEntityMetadata.getHashKeyPropotypeEntityForHashKey("someUserName")).thenReturn( prototypeHashKey); Mockito.when(mockPlaylistEntityMetadata.getHashKey(playlistId)).thenReturn("someUserName"); Mockito.when(mockPlaylistEntityMetadata.getRangeKey(playlistId)).thenReturn("somePlaylistName"); Mockito.when(mockPlaylistEntityMetadata.getOverriddenAttributeName("displayName")).thenReturn("DisplayName"); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBScanExpression> scanCaptor = ArgumentCaptor.forClass(DynamoDBScanExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockUserScanResults.get(0)).thenReturn(mockUser); Mockito.when(mockUserScanResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.scan(classCaptor.capture(), scanCaptor.capture())).thenReturn( mockUserScanResults); // Execute the query Object[] parameters = new Object[] { playlistId, "someDisplayName" }; partTreeDynamoDBQuery.execute(parameters); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), Playlist.class); // Assert that we have only three filter conditions Map<String, Condition> filterConditions = scanCaptor.getValue().getScanFilter(); assertEquals(3, filterConditions.size()); Condition filterCondition1 = filterConditions.get("userName"); Condition filterCondition2 = filterConditions.get("playlistName"); Condition filterCondition3 = filterConditions.get("DisplayName"); assertEquals(ComparisonOperator.EQ.name(), filterCondition1.getComparisonOperator()); assertEquals(ComparisonOperator.EQ.name(), filterCondition2.getComparisonOperator()); assertEquals(ComparisonOperator.EQ.name(), filterCondition3.getComparisonOperator()); // Assert we only have one attribute value for this filter condition assertEquals(1, filterCondition1.getAttributeValueList().size()); assertEquals(1, filterCondition2.getAttributeValueList().size()); assertEquals(1, filterCondition3.getAttributeValueList().size()); // Assert that there the attribute value type for this attribute value // is String, // and its value is the parameter expected assertEquals("someUserName", filterCondition1.getAttributeValueList().get(0).getS()); assertEquals("somePlaylistName", filterCondition2.getAttributeValueList().get(0).getS()); assertEquals("someDisplayName", filterCondition3.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(filterCondition1.getAttributeValueList().get(0).getSS()); assertNull(filterCondition1.getAttributeValueList().get(0).getN()); assertNull(filterCondition1.getAttributeValueList().get(0).getNS()); assertNull(filterCondition1.getAttributeValueList().get(0).getB()); assertNull(filterCondition1.getAttributeValueList().get(0).getBS()); assertNull(filterCondition2.getAttributeValueList().get(0).getSS()); assertNull(filterCondition2.getAttributeValueList().get(0).getN()); assertNull(filterCondition2.getAttributeValueList().get(0).getNS()); assertNull(filterCondition2.getAttributeValueList().get(0).getB()); assertNull(filterCondition2.getAttributeValueList().get(0).getBS()); assertNull(filterCondition3.getAttributeValueList().get(0).getSS()); assertNull(filterCondition3.getAttributeValueList().get(0).getN()); assertNull(filterCondition3.getAttributeValueList().get(0).getNS()); assertNull(filterCondition3.getAttributeValueList().get(0).getB()); assertNull(filterCondition3.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).scan(classCaptor.getValue(), scanCaptor.getValue()); // Assert // that // we // obtain // the // expected // results } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingSingleEntity_WithSingleStringParameter_WhenNotFindingByHashKey() { setupCommonMocksForThisRepositoryMethod(mockUserEntityMetadata, mockDynamoDBUserQueryMethod, User.class, "findByName", 1, "id", null); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBScanExpression> scanCaptor = ArgumentCaptor.forClass(DynamoDBScanExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockUserScanResults.get(0)).thenReturn(mockUser); Mockito.when(mockUserScanResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.scan(classCaptor.capture(), scanCaptor.capture())).thenReturn( mockUserScanResults); // Execute the query Object[] parameters = new Object[] { "someName" }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected single result assertEquals(o, mockUser); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), User.class); // Assert that we have only one filter condition, for the name of the // property Map<String, Condition> filterConditions = scanCaptor.getValue().getScanFilter(); assertEquals(1, filterConditions.size()); Condition filterCondition = filterConditions.get("name"); assertNotNull(filterCondition); assertEquals(ComparisonOperator.EQ.name(), filterCondition.getComparisonOperator()); // Assert we only have one attribute value for this filter condition assertEquals(1, filterCondition.getAttributeValueList().size()); // Assert that there the attribute value type for this attribute value // is String, // and its value is the parameter expected assertEquals("someName", filterCondition.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(filterCondition.getAttributeValueList().get(0).getSS()); assertNull(filterCondition.getAttributeValueList().get(0).getN()); assertNull(filterCondition.getAttributeValueList().get(0).getNS()); assertNull(filterCondition.getAttributeValueList().get(0).getB()); assertNull(filterCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).scan(classCaptor.getValue(), scanCaptor.getValue()); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingSingleEntity_WithSingleStringParameter_WhenNotFindingByHashKey_WhenDynamoAttributeNameOverridden() { setupCommonMocksForThisRepositoryMethod(mockUserEntityMetadata, mockDynamoDBUserQueryMethod, User.class, "findByName", 1, "id", null); Mockito.when(mockUserEntityMetadata.getOverriddenAttributeName("name")).thenReturn("Name"); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBScanExpression> scanCaptor = ArgumentCaptor.forClass(DynamoDBScanExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockUserScanResults.get(0)).thenReturn(mockUser); Mockito.when(mockUserScanResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.scan(classCaptor.capture(), scanCaptor.capture())).thenReturn( mockUserScanResults); // Execute the query Object[] parameters = new Object[] { "someName" }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected single result assertEquals(o, mockUser); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), User.class); // Assert that we have only one filter condition, for the name of the // property Map<String, Condition> filterConditions = scanCaptor.getValue().getScanFilter(); assertEquals(1, filterConditions.size()); Condition filterCondition = filterConditions.get("Name"); assertNotNull(filterCondition); assertEquals(ComparisonOperator.EQ.name(), filterCondition.getComparisonOperator()); // Assert we only have one attribute value for this filter condition assertEquals(1, filterCondition.getAttributeValueList().size()); // Assert that there the attribute value type for this attribute value // is String, // and its value is the parameter expected assertEquals("someName", filterCondition.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(filterCondition.getAttributeValueList().get(0).getSS()); assertNull(filterCondition.getAttributeValueList().get(0).getN()); assertNull(filterCondition.getAttributeValueList().get(0).getNS()); assertNull(filterCondition.getAttributeValueList().get(0).getB()); assertNull(filterCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).scan(classCaptor.getValue(), scanCaptor.getValue()); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingSingleEntity_WithMultipleStringParameters_WhenFindingByHashKeyAndANonHashOrRangeProperty() { setupCommonMocksForThisRepositoryMethod(mockUserEntityMetadata, mockDynamoDBUserQueryMethod, User.class, "findByIdAndName", 2, "id", null); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBScanExpression> scanCaptor = ArgumentCaptor.forClass(DynamoDBScanExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockUserScanResults.get(0)).thenReturn(mockUser); Mockito.when(mockUserScanResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.scan(classCaptor.capture(), scanCaptor.capture())).thenReturn( mockUserScanResults); // Execute the query Object[] parameters = new Object[] { "someId", "someName" }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected single result assertEquals(o, mockUser); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), User.class); // Assert that we have two filter conditions, for the id and name Map<String, Condition> filterConditions = scanCaptor.getValue().getScanFilter(); assertEquals(2, filterConditions.size()); Condition nameFilterCondition = filterConditions.get("name"); assertNotNull(nameFilterCondition); Condition idFilterCondition = filterConditions.get("id"); assertNotNull(idFilterCondition); assertEquals(ComparisonOperator.EQ.name(), nameFilterCondition.getComparisonOperator()); assertEquals(ComparisonOperator.EQ.name(), idFilterCondition.getComparisonOperator()); // Assert we only have one attribute value for each filter condition assertEquals(1, nameFilterCondition.getAttributeValueList().size()); assertEquals(1, idFilterCondition.getAttributeValueList().size()); // Assert that there the attribute value type for this attribute value // is String, // and its value is the parameter expected assertEquals("someName", nameFilterCondition.getAttributeValueList().get(0).getS()); assertEquals("someId", idFilterCondition.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(nameFilterCondition.getAttributeValueList().get(0).getSS()); assertNull(nameFilterCondition.getAttributeValueList().get(0).getN()); assertNull(nameFilterCondition.getAttributeValueList().get(0).getNS()); assertNull(nameFilterCondition.getAttributeValueList().get(0).getB()); assertNull(nameFilterCondition.getAttributeValueList().get(0).getBS()); assertNull(idFilterCondition.getAttributeValueList().get(0).getSS()); assertNull(idFilterCondition.getAttributeValueList().get(0).getN()); assertNull(idFilterCondition.getAttributeValueList().get(0).getNS()); assertNull(idFilterCondition.getAttributeValueList().get(0).getB()); assertNull(idFilterCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).scan(classCaptor.getValue(), scanCaptor.getValue()); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingSingleEntity_WithMultipleStringParameters_WhenFindingByHashKeyAndACollectionProperty() { setupCommonMocksForThisRepositoryMethod(mockUserEntityMetadata, mockDynamoDBUserQueryMethod, User.class, "findByTestSet", 1, "id", null); Set<String> testSet = new HashSet<String>(); testSet.add("testData"); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBScanExpression> scanCaptor = ArgumentCaptor.forClass(DynamoDBScanExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockUserScanResults.get(0)).thenReturn(mockUser); Mockito.when(mockUserScanResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.scan(classCaptor.capture(), scanCaptor.capture())).thenReturn( mockUserScanResults); // Execute the query Object[] parameters = new Object[] { testSet }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected single result assertEquals(o, mockUser); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), User.class); // Assert that we have one filter condition Map<String, Condition> filterConditions = scanCaptor.getValue().getScanFilter(); assertEquals(1, filterConditions.size()); Condition testSetFilterCondition = filterConditions.get("testSet"); assertNotNull(testSetFilterCondition); assertEquals(ComparisonOperator.EQ.name(), testSetFilterCondition.getComparisonOperator()); // Assert we only have one attribute value for each filter condition assertEquals(1, testSetFilterCondition.getAttributeValueList().size()); // Assert that there the attribute value type for this attribute value // is String, // and its value is the parameter expected assertNotNull(testSetFilterCondition.getAttributeValueList().get(0).getSS()); assertTrue(ClassUtils.isAssignable(Iterable.class, testSetFilterCondition.getAttributeValueList().get(0).getSS().getClass())); Iterable iterable = testSetFilterCondition.getAttributeValueList().get(0).getSS(); List<Object> returnObjects = new ArrayList<Object>(); for (Object object : iterable) { returnObjects.add(object); } assertEquals(1,returnObjects.size()); assertEquals("testData",returnObjects.get(0)); // Assert that all other attribute value types other than String type // are null assertNull(testSetFilterCondition.getAttributeValueList().get(0).getS()); assertNull(testSetFilterCondition.getAttributeValueList().get(0).getN()); assertNull(testSetFilterCondition.getAttributeValueList().get(0).getNS()); assertNull(testSetFilterCondition.getAttributeValueList().get(0).getB()); assertNull(testSetFilterCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).scan(classCaptor.getValue(), scanCaptor.getValue()); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingSingleEntity_WithMultipleStringParameters_WhenFindingByHashKeyAndANonHashOrRangeProperty_WhenDynamoDBAttributeNamesOveridden() { setupCommonMocksForThisRepositoryMethod(mockUserEntityMetadata, mockDynamoDBUserQueryMethod, User.class, "findByIdAndName", 2, "id", null); Mockito.when(mockUserEntityMetadata.getOverriddenAttributeName("name")).thenReturn("Name"); Mockito.when(mockUserEntityMetadata.getOverriddenAttributeName("id")).thenReturn("Id"); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBScanExpression> scanCaptor = ArgumentCaptor.forClass(DynamoDBScanExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockUserScanResults.get(0)).thenReturn(mockUser); Mockito.when(mockUserScanResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.scan(classCaptor.capture(), scanCaptor.capture())).thenReturn( mockUserScanResults); // Execute the query Object[] parameters = new Object[] { "someId", "someName" }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected single result assertEquals(o, mockUser); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), User.class); // Assert that we have two filter conditions, for the id and name Map<String, Condition> filterConditions = scanCaptor.getValue().getScanFilter(); assertEquals(2, filterConditions.size()); Condition nameFilterCondition = filterConditions.get("Name"); assertNotNull(nameFilterCondition); Condition idFilterCondition = filterConditions.get("Id"); assertNotNull(idFilterCondition); assertEquals(ComparisonOperator.EQ.name(), nameFilterCondition.getComparisonOperator()); assertEquals(ComparisonOperator.EQ.name(), idFilterCondition.getComparisonOperator()); // Assert we only have one attribute value for each filter condition assertEquals(1, nameFilterCondition.getAttributeValueList().size()); assertEquals(1, idFilterCondition.getAttributeValueList().size()); // Assert that there the attribute value type for this attribute value // is String, // and its value is the parameter expected assertEquals("someName", nameFilterCondition.getAttributeValueList().get(0).getS()); assertEquals("someId", idFilterCondition.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(nameFilterCondition.getAttributeValueList().get(0).getSS()); assertNull(nameFilterCondition.getAttributeValueList().get(0).getN()); assertNull(nameFilterCondition.getAttributeValueList().get(0).getNS()); assertNull(nameFilterCondition.getAttributeValueList().get(0).getB()); assertNull(nameFilterCondition.getAttributeValueList().get(0).getBS()); assertNull(idFilterCondition.getAttributeValueList().get(0).getSS()); assertNull(idFilterCondition.getAttributeValueList().get(0).getN()); assertNull(idFilterCondition.getAttributeValueList().get(0).getNS()); assertNull(idFilterCondition.getAttributeValueList().get(0).getB()); assertNull(idFilterCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).scan(classCaptor.getValue(), scanCaptor.getValue()); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityList_WithSingleStringParameter_WhenNotFindingByHashKey() { setupCommonMocksForThisRepositoryMethod(mockUserEntityMetadata, mockDynamoDBUserQueryMethod, User.class, "findByName", 1, "id", null); Mockito.when(mockDynamoDBUserQueryMethod.isCollectionQuery()).thenReturn(true); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBScanExpression> scanCaptor = ArgumentCaptor.forClass(DynamoDBScanExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockUserScanResults.get(0)).thenReturn(mockUser); Mockito.when(mockUserScanResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.scan(classCaptor.capture(), scanCaptor.capture())).thenReturn( mockUserScanResults); // Execute the query Object[] parameters = new Object[] { "someName" }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected list of results assertEquals(o, mockUserScanResults); // Assert that the list of results contains the correct elements assertEquals(1, mockUserScanResults.size()); assertEquals(mockUser, mockUserScanResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), User.class); // Assert that we have only one filter condition, for the name of the // property Map<String, Condition> filterConditions = scanCaptor.getValue().getScanFilter(); assertEquals(1, filterConditions.size()); Condition filterCondition = filterConditions.get("name"); assertNotNull(filterCondition); assertEquals(ComparisonOperator.EQ.name(), filterCondition.getComparisonOperator()); // Assert we only have one attribute value for this filter condition assertEquals(1, filterCondition.getAttributeValueList().size()); // Assert that there the attribute value type for this attribute value // is String, // and its value is the parameter expected assertEquals("someName", filterCondition.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(filterCondition.getAttributeValueList().get(0).getSS()); assertNull(filterCondition.getAttributeValueList().get(0).getN()); assertNull(filterCondition.getAttributeValueList().get(0).getNS()); assertNull(filterCondition.getAttributeValueList().get(0).getB()); assertNull(filterCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).scan(classCaptor.getValue(), scanCaptor.getValue()); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test(expected = UnsupportedOperationException.class) // Not yet supported public void testExecute_WhenFinderMethodIsFindingEntityList_WithSingleStringParameterIgnoringCase_WhenNotFindingByHashKey() { setupCommonMocksForThisRepositoryMethod(mockUserEntityMetadata, mockDynamoDBUserQueryMethod, User.class, "findByNameIgnoringCase", 1, "id", null); Mockito.when(mockDynamoDBUserQueryMethod.isCollectionQuery()).thenReturn(true); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBScanExpression> scanCaptor = ArgumentCaptor.forClass(DynamoDBScanExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockUserScanResults.get(0)).thenReturn(mockUser); Mockito.when(mockUserScanResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.scan(classCaptor.capture(), scanCaptor.capture())).thenReturn( mockUserScanResults); // Execute the query Object[] parameters = new Object[] { "someName" }; partTreeDynamoDBQuery.execute(parameters); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test(expected = UnsupportedOperationException.class) // Not yet supported public void testExecute_WhenFinderMethodIsFindingEntityList_WithSingleStringParameter_WithSort_WhenNotFindingByHashKey() { setupCommonMocksForThisRepositoryMethod(mockUserEntityMetadata, mockDynamoDBUserQueryMethod, User.class, "findByNameOrderByNameAsc", 1, "id", null); Mockito.when(mockDynamoDBUserQueryMethod.isCollectionQuery()).thenReturn(true); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBScanExpression> scanCaptor = ArgumentCaptor.forClass(DynamoDBScanExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockUserScanResults.get(0)).thenReturn(mockUser); Mockito.when(mockUserScanResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.scan(classCaptor.capture(), scanCaptor.capture())).thenReturn( mockUserScanResults); // Execute the query Object[] parameters = new Object[] { "someName" }; partTreeDynamoDBQuery.execute(parameters); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityList_WithSingleStringArrayParameter_WithIn_WhenNotFindingByHashKey() { setupCommonMocksForThisRepositoryMethod(mockUserEntityMetadata, mockDynamoDBUserQueryMethod, User.class, "findByNameIn", 1, "id", null); Mockito.when(mockDynamoDBUserQueryMethod.isCollectionQuery()).thenReturn(true); String[] names = new String[] { "someName", "someOtherName" }; // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBScanExpression> scanCaptor = ArgumentCaptor.forClass(DynamoDBScanExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockUserScanResults.get(0)).thenReturn(mockUser); Mockito.when(mockUserScanResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.scan(classCaptor.capture(), scanCaptor.capture())).thenReturn(mockUserScanResults); // Execute the query Object[] parameters = new Object[] { names }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected list of results assertEquals(o, mockUserScanResults); // Assert that the list of results contains the correct elements assertEquals(1, mockUserScanResults.size()); assertEquals(mockUser, mockUserScanResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), User.class); // Assert that we have only one filter condition, for the name of the // property Map<String, Condition> filterConditions = scanCaptor.getValue().getScanFilter(); assertEquals(1, filterConditions.size()); Condition filterCondition = filterConditions.get("name"); assertNotNull(filterCondition); assertEquals(ComparisonOperator.IN.name(), filterCondition.getComparisonOperator()); // Assert we only have an attribute value for each element of the IN array assertEquals(2, filterCondition.getAttributeValueList().size()); // Assert that there the attribute value type for this attribute value // is String, // and its value is the parameter expected assertEquals(names[0], filterCondition.getAttributeValueList().get(0).getS()); assertEquals(names[1], filterCondition.getAttributeValueList().get(1).getS()); // Assert that all other attribute value types other than String type // are null assertNull(filterCondition.getAttributeValueList().get(0).getSS()); assertNull(filterCondition.getAttributeValueList().get(0).getN()); assertNull(filterCondition.getAttributeValueList().get(0).getNS()); assertNull(filterCondition.getAttributeValueList().get(0).getB()); assertNull(filterCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).scan(classCaptor.getValue(), scanCaptor.getValue()); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityList_WithSingleListParameter_WithIn_WhenNotFindingByHashKey() { setupCommonMocksForThisRepositoryMethod(mockUserEntityMetadata, mockDynamoDBUserQueryMethod, User.class, "findByNameIn", 1, "id", null); Mockito.when(mockDynamoDBUserQueryMethod.isCollectionQuery()).thenReturn(true); List<String> names = Arrays.asList(new String[] { "someName", "someOtherName" }); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBScanExpression> scanCaptor = ArgumentCaptor.forClass(DynamoDBScanExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockUserScanResults.get(0)).thenReturn(mockUser); Mockito.when(mockUserScanResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.scan(classCaptor.capture(), scanCaptor.capture())).thenReturn(mockUserScanResults); // Execute the query Object[] parameters = new Object[] { names }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected list of results assertEquals(o, mockUserScanResults); // Assert that the list of results contains the correct elements assertEquals(1, mockUserScanResults.size()); assertEquals(mockUser, mockUserScanResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), User.class); // Assert that we have only one filter condition, for the name of the // property Map<String, Condition> filterConditions = scanCaptor.getValue().getScanFilter(); assertEquals(1, filterConditions.size()); Condition filterCondition = filterConditions.get("name"); assertNotNull(filterCondition); assertEquals(ComparisonOperator.IN.name(), filterCondition.getComparisonOperator()); // Assert we only have an attribute value for each element of the IN array assertEquals(2, filterCondition.getAttributeValueList().size()); // Assert that there the attribute value type for this attribute value // is String, // and its value is the parameter expected assertEquals(names.get(0), filterCondition.getAttributeValueList().get(0).getS()); assertEquals(names.get(1), filterCondition.getAttributeValueList().get(1).getS()); // Assert that all other attribute value types other than String type // are null assertNull(filterCondition.getAttributeValueList().get(0).getSS()); assertNull(filterCondition.getAttributeValueList().get(0).getN()); assertNull(filterCondition.getAttributeValueList().get(0).getNS()); assertNull(filterCondition.getAttributeValueList().get(0).getB()); assertNull(filterCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).scan(classCaptor.getValue(), scanCaptor.getValue()); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityList_WithSingleDateParameter_WhenNotFindingByHashKey() throws ParseException { String joinDateString = "2013-09-12T14:04:03.123Z"; DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); Date joinDate = dateFormat.parse(joinDateString); setupCommonMocksForThisRepositoryMethod(mockUserEntityMetadata, mockDynamoDBUserQueryMethod, User.class, "findByJoinDate", 1, "id", null); Mockito.when(mockDynamoDBUserQueryMethod.isCollectionQuery()).thenReturn(true); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBScanExpression> scanCaptor = ArgumentCaptor.forClass(DynamoDBScanExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockUserScanResults.get(0)).thenReturn(mockUser); Mockito.when(mockUserScanResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.scan(classCaptor.capture(), scanCaptor.capture())).thenReturn( mockUserScanResults); // Execute the query Object[] parameters = new Object[] { joinDate }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected list of results assertEquals(o, mockUserScanResults); // Assert that the list of results contains the correct elements assertEquals(1, mockUserScanResults.size()); assertEquals(mockUser, mockUserScanResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), User.class); // Assert that we have only one filter condition, for the name of the // property Map<String, Condition> filterConditions = scanCaptor.getValue().getScanFilter(); assertEquals(1, filterConditions.size()); Condition filterCondition = filterConditions.get("joinDate"); assertNotNull(filterCondition); assertEquals(ComparisonOperator.EQ.name(), filterCondition.getComparisonOperator()); // Assert we only have one attribute value for this filter condition assertEquals(1, filterCondition.getAttributeValueList().size()); // Assert that there the attribute value type for this attribute value // is String, // and its value is the parameter expected assertEquals(joinDateString, filterCondition.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(filterCondition.getAttributeValueList().get(0).getSS()); assertNull(filterCondition.getAttributeValueList().get(0).getN()); assertNull(filterCondition.getAttributeValueList().get(0).getNS()); assertNull(filterCondition.getAttributeValueList().get(0).getB()); assertNull(filterCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).scan(classCaptor.getValue(), scanCaptor.getValue()); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityList_WithSingleDateParameter_WithCustomMarshaller_WhenNotFindingByHashKey() throws ParseException { String joinYearString = "2013"; DateFormat dateFormat = new SimpleDateFormat("yyyy"); Date joinYear = dateFormat.parse(joinYearString); setupCommonMocksForThisRepositoryMethod(mockUserEntityMetadata, mockDynamoDBUserQueryMethod, User.class, "findByJoinYear", 1, "id", null); Mockito.when(mockDynamoDBUserQueryMethod.isCollectionQuery()).thenReturn(true); DynamoDBMarshaller marshaller = new DynamoDBYearMarshaller(); Mockito.when(mockUserEntityMetadata.getMarshallerForProperty("joinYear")).thenReturn(marshaller); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBScanExpression> scanCaptor = ArgumentCaptor.forClass(DynamoDBScanExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockUserScanResults.get(0)).thenReturn(mockUser); Mockito.when(mockUserScanResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.scan(classCaptor.capture(), scanCaptor.capture())).thenReturn( mockUserScanResults); // Execute the query Object[] parameters = new Object[] { joinYear }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected list of results assertEquals(o, mockUserScanResults); // Assert that the list of results contains the correct elements assertEquals(1, mockUserScanResults.size()); assertEquals(mockUser, mockUserScanResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), User.class); // Assert that we have only one filter condition, for the name of the // property Map<String, Condition> filterConditions = scanCaptor.getValue().getScanFilter(); assertEquals(1, filterConditions.size()); Condition filterCondition = filterConditions.get("joinYear"); assertNotNull(filterCondition); assertEquals(ComparisonOperator.EQ.name(), filterCondition.getComparisonOperator()); // Assert we only have one attribute value for this filter condition assertEquals(1, filterCondition.getAttributeValueList().size()); // Assert that there the attribute value type for this attribute value // is String, // and its value is the parameter expected assertEquals(joinYearString, filterCondition.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(filterCondition.getAttributeValueList().get(0).getSS()); assertNull(filterCondition.getAttributeValueList().get(0).getN()); assertNull(filterCondition.getAttributeValueList().get(0).getNS()); assertNull(filterCondition.getAttributeValueList().get(0).getB()); assertNull(filterCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).scan(classCaptor.getValue(), scanCaptor.getValue()); } // Global Secondary Index Test 1 @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityList_WithSingleDateParameter_WithCustomMarshaller_WhenFindingByGlobalSecondaryHashIndexHashKey() throws ParseException { String joinYearString = "2013"; DateFormat dateFormat = new SimpleDateFormat("yyyy"); Date joinYear = dateFormat.parse(joinYearString); setupCommonMocksForThisRepositoryMethod(mockUserEntityMetadata, mockDynamoDBUserQueryMethod, User.class, "findByJoinYear", 1, "id", null); Mockito.when(mockDynamoDBUserQueryMethod.isCollectionQuery()).thenReturn(true); DynamoDBMarshaller marshaller = new DynamoDBYearMarshaller(); Mockito.when(mockUserEntityMetadata.isGlobalIndexHashKeyProperty("joinYear")).thenReturn(true); Mockito.when(mockUserEntityMetadata.getMarshallerForProperty("joinYear")).thenReturn(marshaller); Map<String, String[]> indexRangeKeySecondaryIndexNames = new HashMap<String,String[]>(); indexRangeKeySecondaryIndexNames.put("joinYear", new String[] {"JoinYear-index"}); Mockito.when(mockUserEntityMetadata.getGlobalSecondaryIndexNamesByPropertyName()).thenReturn(indexRangeKeySecondaryIndexNames); Mockito.when(mockUserEntityMetadata.getDynamoDBTableName()).thenReturn("user"); // Mock out specific QueryRequestMapper behavior expected by this method ArgumentCaptor<QueryRequest> queryCaptor = ArgumentCaptor.forClass(QueryRequest.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockUserQueryResults.get(0)).thenReturn(mockUser); Mockito.when(mockUserQueryResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.query(classCaptor.capture(), queryCaptor.capture())) .thenReturn(mockUserQueryResults); Mockito.when(mockDynamoDBOperations.getOverriddenTableName("user")).thenReturn("user"); // Execute the query Object[] parameters = new Object[] { joinYear}; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(mockUserQueryResults, o); assertEquals(1, mockUserQueryResults.size()); assertEquals(mockUser, mockUserQueryResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), User.class); String indexName = queryCaptor.getValue().getIndexName(); assertNotNull(indexName); assertEquals("JoinYear-index",indexName); assertEquals("user",queryCaptor.getValue().getTableName()); // Assert that we have only one range condition for the global secondary index hash key assertEquals(1,queryCaptor.getValue().getKeyConditions().size()); Condition condition = queryCaptor.getValue().getKeyConditions().get("joinYear"); assertEquals(ComparisonOperator.EQ.name(),condition.getComparisonOperator()); assertEquals(1,condition.getAttributeValueList().size()); assertEquals(joinYearString,condition.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(condition.getAttributeValueList().get(0).getSS()); assertNull(condition.getAttributeValueList().get(0).getN()); assertNull(condition.getAttributeValueList().get(0).getNS()); assertNull(condition.getAttributeValueList().get(0).getB()); assertNull(condition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).query(classCaptor.getValue(), queryCaptor.getValue()); } // Global Secondary Index Test 2 @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityList_WithDateParameterAndStringParameter_WithCustomMarshaller_WhenFindingByGlobalSecondaryHashAndRangeIndexHashAndRangeKey() throws ParseException { String joinYearString = "2013"; DateFormat dateFormat = new SimpleDateFormat("yyyy"); Date joinYear = dateFormat.parse(joinYearString); setupCommonMocksForThisRepositoryMethod(mockUserEntityMetadata, mockDynamoDBUserQueryMethod, User.class, "findByJoinYearAndPostCode", 2, "id", null); Mockito.when(mockDynamoDBUserQueryMethod.isCollectionQuery()).thenReturn(true); DynamoDBMarshaller marshaller = new DynamoDBYearMarshaller(); Mockito.when(mockUserEntityMetadata.isGlobalIndexHashKeyProperty("joinYear")).thenReturn(true); Mockito.when(mockUserEntityMetadata.isGlobalIndexRangeKeyProperty("postCode")).thenReturn(true); Mockito.when(mockUserEntityMetadata.getMarshallerForProperty("joinYear")).thenReturn(marshaller); Map<String, String[]> indexRangeKeySecondaryIndexNames = new HashMap<String,String[]>(); indexRangeKeySecondaryIndexNames.put("joinYear", new String[] {"JoinYear-index"}); indexRangeKeySecondaryIndexNames.put("postCode", new String[] {"JoinYear-index"}); Mockito.when(mockUserEntityMetadata.getGlobalSecondaryIndexNamesByPropertyName()).thenReturn(indexRangeKeySecondaryIndexNames); // Mock out specific QueryRequestMapper behavior expected by this method ArgumentCaptor<QueryRequest> queryCaptor = ArgumentCaptor.forClass(QueryRequest.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockUserQueryResults.get(0)).thenReturn(mockUser); Mockito.when(mockUserQueryResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.query(classCaptor.capture(), queryCaptor.capture())) .thenReturn(mockUserQueryResults); Mockito.when(mockUserEntityMetadata.getDynamoDBTableName()).thenReturn("user"); Mockito.when(mockDynamoDBOperations.getOverriddenTableName("user")).thenReturn("user"); // Execute the query Object[] parameters = new Object[] { joinYear,"nw1"}; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(mockUserQueryResults, o); assertEquals(1, mockUserQueryResults.size()); assertEquals(mockUser, mockUserQueryResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), User.class); String indexName = queryCaptor.getValue().getIndexName(); assertNotNull(indexName); assertEquals("JoinYear-index",indexName); // Assert that we have only two range conditions for the global secondary index hash key and range key assertEquals(2,queryCaptor.getValue().getKeyConditions().size()); Condition yearCondition = queryCaptor.getValue().getKeyConditions().get("joinYear"); assertEquals(ComparisonOperator.EQ.name(),yearCondition.getComparisonOperator()); assertEquals(1,yearCondition.getAttributeValueList().size()); assertEquals(joinYearString,yearCondition.getAttributeValueList().get(0).getS()); Condition postCodeCondition = queryCaptor.getValue().getKeyConditions().get("postCode"); assertEquals(ComparisonOperator.EQ.name(),postCodeCondition.getComparisonOperator()); assertEquals(1,postCodeCondition.getAttributeValueList().size()); assertEquals("nw1",postCodeCondition.getAttributeValueList().get(0).getS()); assertEquals("user",queryCaptor.getValue().getTableName()); // Assert that all other attribute value types other than String type // are null assertNull(yearCondition.getAttributeValueList().get(0).getSS()); assertNull(yearCondition.getAttributeValueList().get(0).getN()); assertNull(yearCondition.getAttributeValueList().get(0).getNS()); assertNull(yearCondition.getAttributeValueList().get(0).getB()); assertNull(yearCondition.getAttributeValueList().get(0).getBS()); assertNull(postCodeCondition.getAttributeValueList().get(0).getSS()); assertNull(postCodeCondition.getAttributeValueList().get(0).getN()); assertNull(postCodeCondition.getAttributeValueList().get(0).getNS()); assertNull(postCodeCondition.getAttributeValueList().get(0).getB()); assertNull(postCodeCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).query(classCaptor.getValue(),queryCaptor.getValue()); } // Global Secondary Index Test 3 @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeKeyList_WhenFindingByGlobalSecondaryHashIndexHashKey() throws ParseException { setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByDisplayNameOrderByDisplayNameDesc", 1, "userName", "playlistName"); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Mockito.when(mockPlaylistEntityMetadata.isGlobalIndexHashKeyProperty("displayName")).thenReturn(true); Map<String, String[]> indexRangeKeySecondaryIndexNames = new HashMap<String,String[]>(); indexRangeKeySecondaryIndexNames.put("displayName", new String[] {"DisplayName-index"}); Mockito.when(mockPlaylistEntityMetadata.getGlobalSecondaryIndexNamesByPropertyName()).thenReturn(indexRangeKeySecondaryIndexNames); Mockito.when(mockPlaylistEntityMetadata.getDynamoDBTableName()).thenReturn("playlist"); // Mock out specific QueryRequestMapper behavior expected by this method ArgumentCaptor<QueryRequest> queryCaptor = ArgumentCaptor.forClass(QueryRequest.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockPlaylistQueryResults.get(0)).thenReturn(mockPlaylist); Mockito.when(mockPlaylistQueryResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.query(classCaptor.capture(), queryCaptor.capture())) .thenReturn(mockPlaylistQueryResults); Mockito.when(mockDynamoDBOperations.getOverriddenTableName("playlist")).thenReturn("playlist"); // Execute the query Object[] parameters = new Object[] { "Michael"}; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(mockPlaylistQueryResults, o); assertEquals(1, mockPlaylistQueryResults.size()); assertEquals(mockPlaylist, mockPlaylistQueryResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), Playlist.class); String indexName = queryCaptor.getValue().getIndexName(); assertNotNull(indexName); assertEquals("DisplayName-index",indexName); assertEquals("playlist",queryCaptor.getValue().getTableName()); // Assert that we have only one range condition for the global secondary index hash key assertEquals(1,queryCaptor.getValue().getKeyConditions().size()); Condition condition = queryCaptor.getValue().getKeyConditions().get("displayName"); assertEquals(ComparisonOperator.EQ.name(),condition.getComparisonOperator()); assertEquals(1,condition.getAttributeValueList().size()); assertEquals("Michael",condition.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(condition.getAttributeValueList().get(0).getSS()); assertNull(condition.getAttributeValueList().get(0).getN()); assertNull(condition.getAttributeValueList().get(0).getNS()); assertNull(condition.getAttributeValueList().get(0).getB()); assertNull(condition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).query(classCaptor.getValue(), queryCaptor.getValue()); } // Global Secondary Index Test 3a @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeKeyList_WhenFindingByGlobalSecondaryHashIndexHashKey_WhereSecondaryHashKeyIsPrimaryRangeKey() throws ParseException { setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByPlaylistName", 1, "userName", "playlistName"); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Map<String, String[]> indexRangeKeySecondaryIndexNames = new HashMap<String,String[]>(); indexRangeKeySecondaryIndexNames.put("playlistName", new String[] {"PlaylistName-index"}); Mockito.when(mockPlaylistEntityMetadata.getGlobalSecondaryIndexNamesByPropertyName()).thenReturn(indexRangeKeySecondaryIndexNames); Mockito.when(mockPlaylistEntityMetadata.getDynamoDBTableName()).thenReturn("playlist"); // Mock out specific QueryRequestMapper behavior expected by this method ArgumentCaptor<QueryRequest> queryCaptor = ArgumentCaptor.forClass(QueryRequest.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockPlaylistQueryResults.get(0)).thenReturn(mockPlaylist); Mockito.when(mockPlaylistQueryResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.query(classCaptor.capture(), queryCaptor.capture())) .thenReturn(mockPlaylistQueryResults); Mockito.when(mockDynamoDBOperations.getOverriddenTableName("playlist")).thenReturn("playlist"); // Execute the query Object[] parameters = new Object[] { "Some Playlist"}; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(mockPlaylistQueryResults, o); assertEquals(1, mockPlaylistQueryResults.size()); assertEquals(mockPlaylist, mockPlaylistQueryResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), Playlist.class); String indexName = queryCaptor.getValue().getIndexName(); assertNotNull(indexName); assertEquals("PlaylistName-index",indexName); assertEquals("playlist",queryCaptor.getValue().getTableName()); // Assert that we have the correct conditions assertEquals(1,queryCaptor.getValue().getKeyConditions().size()); Condition condition = queryCaptor.getValue().getKeyConditions().get("playlistName"); assertEquals(ComparisonOperator.EQ.name(),condition.getComparisonOperator()); assertEquals(1,condition.getAttributeValueList().size()); assertEquals("Some Playlist",condition.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(condition.getAttributeValueList().get(0).getSS()); assertNull(condition.getAttributeValueList().get(0).getN()); assertNull(condition.getAttributeValueList().get(0).getNS()); assertNull(condition.getAttributeValueList().get(0).getB()); assertNull(condition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).query(classCaptor.getValue(), queryCaptor.getValue()); } // Global Secondary Index Test 4 @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeKeyList_WhenFindingByGlobalSecondaryHashAndRangeIndexHashAndRangeKey_WhereSecondaryHashKeyIsPrimaryHashKey() throws ParseException { setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByUserNameAndDisplayName", 2, "userName", "playlistName"); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Mockito.when(mockPlaylistEntityMetadata.isGlobalIndexHashKeyProperty("userName")).thenReturn(true); Mockito.when(mockPlaylistEntityMetadata.isGlobalIndexRangeKeyProperty("displayName")).thenReturn(true); Map<String, String[]> indexRangeKeySecondaryIndexNames = new HashMap<String,String[]>(); indexRangeKeySecondaryIndexNames.put("displayName", new String[] {"UserName-DisplayName-index"}); indexRangeKeySecondaryIndexNames.put("userName", new String[] {"UserName-DisplayName-index"}); Mockito.when(mockPlaylistEntityMetadata.getGlobalSecondaryIndexNamesByPropertyName()).thenReturn(indexRangeKeySecondaryIndexNames); Mockito.when(mockPlaylistEntityMetadata.getDynamoDBTableName()).thenReturn("playlist"); // Mock out specific QueryRequestMapper behavior expected by this method ArgumentCaptor<QueryRequest> queryCaptor = ArgumentCaptor.forClass(QueryRequest.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockPlaylistQueryResults.get(0)).thenReturn(mockPlaylist); Mockito.when(mockPlaylistQueryResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.query(classCaptor.capture(), queryCaptor.capture())) .thenReturn(mockPlaylistQueryResults); Mockito.when(mockDynamoDBOperations.getOverriddenTableName("playlist")).thenReturn("playlist"); // Execute the query Object[] parameters = new Object[] { "1","Michael"}; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(mockPlaylistQueryResults, o); assertEquals(1, mockPlaylistQueryResults.size()); assertEquals(mockPlaylist, mockPlaylistQueryResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), Playlist.class); String indexName = queryCaptor.getValue().getIndexName(); assertNotNull(indexName); assertEquals("UserName-DisplayName-index",indexName); assertEquals("playlist",queryCaptor.getValue().getTableName()); // Assert that we the correct conditions assertEquals(2,queryCaptor.getValue().getKeyConditions().size()); Condition globalRangeKeyCondition = queryCaptor.getValue().getKeyConditions().get("displayName"); assertEquals(ComparisonOperator.EQ.name(),globalRangeKeyCondition.getComparisonOperator()); assertEquals(1,globalRangeKeyCondition.getAttributeValueList().size()); assertEquals("Michael",globalRangeKeyCondition.getAttributeValueList().get(0).getS()); Condition globalHashKeyCondition = queryCaptor.getValue().getKeyConditions().get("userName"); assertEquals(ComparisonOperator.EQ.name(),globalHashKeyCondition.getComparisonOperator()); assertEquals(1,globalHashKeyCondition.getAttributeValueList().size()); assertEquals("1",globalHashKeyCondition.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getSS()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getN()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getNS()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getB()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getBS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getSS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getN()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getNS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getB()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).query(classCaptor.getValue(), queryCaptor.getValue()); } // Global Secondary Index Test 4b @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeKeyList_WhenFindingByGlobalSecondaryHashAndRangeIndexHashAndRangeKey_WhereSecondaryHashKeyIsPrimaryRangeKey() throws ParseException { setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByPlaylistNameAndDisplayName", 2, "userName", "playlistName"); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Mockito.when(mockPlaylistEntityMetadata.isGlobalIndexHashKeyProperty("playlistName")).thenReturn(true); Mockito.when(mockPlaylistEntityMetadata.isGlobalIndexRangeKeyProperty("displayName")).thenReturn(true); Map<String, String[]> indexRangeKeySecondaryIndexNames = new HashMap<String,String[]>(); indexRangeKeySecondaryIndexNames.put("playlistName", new String[] {"PlaylistName-DisplayName-index"}); indexRangeKeySecondaryIndexNames.put("displayName", new String[] {"PlaylistName-DisplayName-index"}); Mockito.when(mockPlaylistEntityMetadata.getGlobalSecondaryIndexNamesByPropertyName()).thenReturn(indexRangeKeySecondaryIndexNames); Mockito.when(mockPlaylistEntityMetadata.getDynamoDBTableName()).thenReturn("playlist"); // Mock out specific QueryRequestMapper behavior expected by this method ArgumentCaptor<QueryRequest> queryCaptor = ArgumentCaptor.forClass(QueryRequest.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockPlaylistQueryResults.get(0)).thenReturn(mockPlaylist); Mockito.when(mockPlaylistQueryResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.query(classCaptor.capture(), queryCaptor.capture())) .thenReturn(mockPlaylistQueryResults); Mockito.when(mockDynamoDBOperations.getOverriddenTableName("playlist")).thenReturn("playlist"); // Execute the query Object[] parameters = new Object[] { "SomePlaylistName","Michael"}; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(mockPlaylistQueryResults, o); assertEquals(1, mockPlaylistQueryResults.size()); assertEquals(mockPlaylist, mockPlaylistQueryResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), Playlist.class); String indexName = queryCaptor.getValue().getIndexName(); assertNotNull(indexName); assertEquals("PlaylistName-DisplayName-index",indexName); assertEquals("playlist",queryCaptor.getValue().getTableName()); // Assert that we have the correct conditions assertEquals(2,queryCaptor.getValue().getKeyConditions().size()); Condition globalRangeKeyCondition = queryCaptor.getValue().getKeyConditions().get("displayName"); assertEquals(ComparisonOperator.EQ.name(),globalRangeKeyCondition.getComparisonOperator()); assertEquals(1,globalRangeKeyCondition.getAttributeValueList().size()); assertEquals("Michael",globalRangeKeyCondition.getAttributeValueList().get(0).getS()); Condition globalHashKeyCondition = queryCaptor.getValue().getKeyConditions().get("playlistName"); assertEquals(ComparisonOperator.EQ.name(),globalHashKeyCondition.getComparisonOperator()); assertEquals(1,globalHashKeyCondition.getAttributeValueList().size()); assertEquals("SomePlaylistName",globalHashKeyCondition.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getSS()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getN()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getNS()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getB()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getBS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getSS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getN()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getNS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getB()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).query(classCaptor.getValue(), queryCaptor.getValue()); } // Global Secondary Index Test 4c @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeKeyList_WhenFindingByGlobalSecondaryHashAndRangeIndexHashAndRangeKey_WhereSecondaryRangeKeyIsPrimaryRangeKey() throws ParseException { setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByDisplayNameAndPlaylistName", 2, "userName", "playlistName"); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Mockito.when(mockPlaylistEntityMetadata.isGlobalIndexHashKeyProperty("displayName")).thenReturn(true); Mockito.when(mockPlaylistEntityMetadata.isGlobalIndexRangeKeyProperty("playlistName")).thenReturn(true); Map<String, String[]> indexRangeKeySecondaryIndexNames = new HashMap<String,String[]>(); indexRangeKeySecondaryIndexNames.put("displayName", new String[] {"DisplayName-PlaylistName-index"}); indexRangeKeySecondaryIndexNames.put("playlistName", new String[] {"DisplayName-PlaylistName-index"}); Mockito.when(mockPlaylistEntityMetadata.getGlobalSecondaryIndexNamesByPropertyName()).thenReturn(indexRangeKeySecondaryIndexNames); Mockito.when(mockPlaylistEntityMetadata.getDynamoDBTableName()).thenReturn("playlist"); // Mock out specific QueryRequestMapper behavior expected by this method ArgumentCaptor<QueryRequest> queryCaptor = ArgumentCaptor.forClass(QueryRequest.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockPlaylistQueryResults.get(0)).thenReturn(mockPlaylist); Mockito.when(mockPlaylistQueryResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.query(classCaptor.capture(), queryCaptor.capture())) .thenReturn(mockPlaylistQueryResults); Mockito.when(mockDynamoDBOperations.getOverriddenTableName("playlist")).thenReturn("playlist"); // Execute the query Object[] parameters = new Object[] { "SomeDisplayName","SomePlaylistName"}; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(mockPlaylistQueryResults, o); assertEquals(1, mockPlaylistQueryResults.size()); assertEquals(mockPlaylist, mockPlaylistQueryResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), Playlist.class); String indexName = queryCaptor.getValue().getIndexName(); assertNotNull(indexName); assertEquals("DisplayName-PlaylistName-index",indexName); assertEquals("playlist",queryCaptor.getValue().getTableName()); // Assert that we have the correct conditions assertEquals(2,queryCaptor.getValue().getKeyConditions().size()); Condition globalRangeKeyCondition = queryCaptor.getValue().getKeyConditions().get("displayName"); assertEquals(ComparisonOperator.EQ.name(),globalRangeKeyCondition.getComparisonOperator()); assertEquals(1,globalRangeKeyCondition.getAttributeValueList().size()); assertEquals("SomeDisplayName",globalRangeKeyCondition.getAttributeValueList().get(0).getS()); Condition globalHashKeyCondition = queryCaptor.getValue().getKeyConditions().get("playlistName"); assertEquals(ComparisonOperator.EQ.name(),globalHashKeyCondition.getComparisonOperator()); assertEquals(1,globalHashKeyCondition.getAttributeValueList().size()); assertEquals("SomePlaylistName",globalHashKeyCondition.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getSS()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getN()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getNS()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getB()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getBS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getSS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getN()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getNS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getB()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).query(classCaptor.getValue(), queryCaptor.getValue()); } // Global Secondary Index Test 4d @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeKeyList_WhenFindingByGlobalSecondaryHashAndRangeIndexHashAndRangeKey_WhereSecondaryRangeKeyIsPrimaryHashKey() throws ParseException { setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByDisplayNameAndUserName", 2, "userName", "playlistName"); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Mockito.when(mockPlaylistEntityMetadata.isGlobalIndexHashKeyProperty("displayName")).thenReturn(true); Mockito.when(mockPlaylistEntityMetadata.isGlobalIndexRangeKeyProperty("userName")).thenReturn(true); Map<String, String[]> indexRangeKeySecondaryIndexNames = new HashMap<String,String[]>(); indexRangeKeySecondaryIndexNames.put("displayName", new String[] {"DisplayName-UserName-index"}); indexRangeKeySecondaryIndexNames.put("userName", new String[] {"DisplayName-UserName-index"}); Mockito.when(mockPlaylistEntityMetadata.getGlobalSecondaryIndexNamesByPropertyName()).thenReturn(indexRangeKeySecondaryIndexNames); Mockito.when(mockPlaylistEntityMetadata.getDynamoDBTableName()).thenReturn("playlist"); // Mock out specific QueryRequestMapper behavior expected by this method ArgumentCaptor<QueryRequest> queryCaptor = ArgumentCaptor.forClass(QueryRequest.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockPlaylistQueryResults.get(0)).thenReturn(mockPlaylist); Mockito.when(mockPlaylistQueryResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.query(classCaptor.capture(), queryCaptor.capture())) .thenReturn(mockPlaylistQueryResults); Mockito.when(mockDynamoDBOperations.getOverriddenTableName("playlist")).thenReturn("playlist"); // Execute the query Object[] parameters = new Object[] { "SomeDisplayName","SomeUserName"}; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(mockPlaylistQueryResults, o); assertEquals(1, mockPlaylistQueryResults.size()); assertEquals(mockPlaylist, mockPlaylistQueryResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), Playlist.class); String indexName = queryCaptor.getValue().getIndexName(); assertNotNull(indexName); assertEquals("DisplayName-UserName-index",indexName); assertEquals("playlist",queryCaptor.getValue().getTableName()); // Assert that we have the correct conditions assertEquals(2,queryCaptor.getValue().getKeyConditions().size()); Condition globalRangeKeyCondition = queryCaptor.getValue().getKeyConditions().get("displayName"); assertEquals(ComparisonOperator.EQ.name(),globalRangeKeyCondition.getComparisonOperator()); assertEquals(1,globalRangeKeyCondition.getAttributeValueList().size()); assertEquals("SomeDisplayName",globalRangeKeyCondition.getAttributeValueList().get(0).getS()); Condition globalHashKeyCondition = queryCaptor.getValue().getKeyConditions().get("userName"); assertEquals(ComparisonOperator.EQ.name(),globalHashKeyCondition.getComparisonOperator()); assertEquals(1,globalHashKeyCondition.getAttributeValueList().size()); assertEquals("SomeUserName",globalHashKeyCondition.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getSS()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getN()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getNS()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getB()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getBS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getSS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getN()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getNS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getB()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).query(classCaptor.getValue(), queryCaptor.getValue()); } // Global Secondary Index Test 4e @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeKeyList_WhenFindingByGlobalSecondaryHashAndRangeIndexHashAndRangeKeyNonEqualityCondition_WhereSecondaryHashKeyIsPrimaryHashKey() throws ParseException { setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByUserNameAndDisplayNameAfter", 2, "userName", "playlistName"); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Mockito.when(mockPlaylistEntityMetadata.isGlobalIndexHashKeyProperty("userName")).thenReturn(true); Mockito.when(mockPlaylistEntityMetadata.isGlobalIndexRangeKeyProperty("displayName")).thenReturn(true); Map<String, String[]> indexRangeKeySecondaryIndexNames = new HashMap<String,String[]>(); indexRangeKeySecondaryIndexNames.put("displayName", new String[] {"UserName-DisplayName-index"}); indexRangeKeySecondaryIndexNames.put("userName", new String[] {"UserName-DisplayName-index"}); Mockito.when(mockPlaylistEntityMetadata.getGlobalSecondaryIndexNamesByPropertyName()).thenReturn(indexRangeKeySecondaryIndexNames); Mockito.when(mockPlaylistEntityMetadata.getDynamoDBTableName()).thenReturn("playlist"); // Mock out specific QueryRequestMapper behavior expected by this method ArgumentCaptor<QueryRequest> queryCaptor = ArgumentCaptor.forClass(QueryRequest.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockPlaylistQueryResults.get(0)).thenReturn(mockPlaylist); Mockito.when(mockPlaylistQueryResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.query(classCaptor.capture(), queryCaptor.capture())) .thenReturn(mockPlaylistQueryResults); Mockito.when(mockDynamoDBOperations.getOverriddenTableName("playlist")).thenReturn("playlist"); // Execute the query Object[] parameters = new Object[] { "1","Michael"}; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(mockPlaylistQueryResults, o); assertEquals(1, mockPlaylistQueryResults.size()); assertEquals(mockPlaylist, mockPlaylistQueryResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), Playlist.class); String indexName = queryCaptor.getValue().getIndexName(); assertNotNull(indexName); assertEquals("UserName-DisplayName-index",indexName); assertEquals("playlist",queryCaptor.getValue().getTableName()); // Assert that we the correct conditions assertEquals(2,queryCaptor.getValue().getKeyConditions().size()); Condition globalRangeKeyCondition = queryCaptor.getValue().getKeyConditions().get("displayName"); assertEquals(ComparisonOperator.GT.name(),globalRangeKeyCondition.getComparisonOperator()); assertEquals(1,globalRangeKeyCondition.getAttributeValueList().size()); assertEquals("Michael",globalRangeKeyCondition.getAttributeValueList().get(0).getS()); Condition globalHashKeyCondition = queryCaptor.getValue().getKeyConditions().get("userName"); assertEquals(ComparisonOperator.EQ.name(),globalHashKeyCondition.getComparisonOperator()); assertEquals(1,globalHashKeyCondition.getAttributeValueList().size()); assertEquals("1",globalHashKeyCondition.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getSS()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getN()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getNS()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getB()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getBS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getSS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getN()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getNS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getB()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).query(classCaptor.getValue(), queryCaptor.getValue()); } // Global Secondary Index Test 4e2 @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeKeyList_WhenFindingByGlobalSecondaryHashAndRangeIndexHashAndRangeKeyNonEqualityCondition_WhereSecondaryHashKeyIsPrimaryHashKey_WhenAccessingPropertyViaCompositeIdPath() throws ParseException { setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByPlaylistIdUserNameAndDisplayNameAfter", 2, "userName", "playlistName"); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Mockito.when(mockPlaylistEntityMetadata.isGlobalIndexHashKeyProperty("userName")).thenReturn(true); Mockito.when(mockPlaylistEntityMetadata.isGlobalIndexRangeKeyProperty("displayName")).thenReturn(true); Map<String, String[]> indexRangeKeySecondaryIndexNames = new HashMap<String,String[]>(); indexRangeKeySecondaryIndexNames.put("displayName", new String[] {"UserName-DisplayName-index"}); indexRangeKeySecondaryIndexNames.put("userName", new String[] {"UserName-DisplayName-index"}); Mockito.when(mockPlaylistEntityMetadata.getGlobalSecondaryIndexNamesByPropertyName()).thenReturn(indexRangeKeySecondaryIndexNames); Mockito.when(mockPlaylistEntityMetadata.getDynamoDBTableName()).thenReturn("playlist"); // Mock out specific QueryRequestMapper behavior expected by this method ArgumentCaptor<QueryRequest> queryCaptor = ArgumentCaptor.forClass(QueryRequest.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockPlaylistQueryResults.get(0)).thenReturn(mockPlaylist); Mockito.when(mockPlaylistQueryResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.query(classCaptor.capture(), queryCaptor.capture())) .thenReturn(mockPlaylistQueryResults); Mockito.when(mockDynamoDBOperations.getOverriddenTableName("playlist")).thenReturn("playlist"); // Execute the query Object[] parameters = new Object[] { "1","Michael"}; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(mockPlaylistQueryResults, o); assertEquals(1, mockPlaylistQueryResults.size()); assertEquals(mockPlaylist, mockPlaylistQueryResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), Playlist.class); String indexName = queryCaptor.getValue().getIndexName(); assertNotNull(indexName); assertEquals("UserName-DisplayName-index",indexName); assertEquals("playlist",queryCaptor.getValue().getTableName()); // Assert that we the correct conditions assertEquals(2,queryCaptor.getValue().getKeyConditions().size()); Condition globalRangeKeyCondition = queryCaptor.getValue().getKeyConditions().get("displayName"); assertEquals(ComparisonOperator.GT.name(),globalRangeKeyCondition.getComparisonOperator()); assertEquals(1,globalRangeKeyCondition.getAttributeValueList().size()); assertEquals("Michael",globalRangeKeyCondition.getAttributeValueList().get(0).getS()); Condition globalHashKeyCondition = queryCaptor.getValue().getKeyConditions().get("userName"); assertEquals(ComparisonOperator.EQ.name(),globalHashKeyCondition.getComparisonOperator()); assertEquals(1,globalHashKeyCondition.getAttributeValueList().size()); assertEquals("1",globalHashKeyCondition.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getSS()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getN()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getNS()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getB()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getBS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getSS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getN()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getNS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getB()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).query(classCaptor.getValue(), queryCaptor.getValue()); } // Global Secondary Index Test 4f @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeKeyList_WhenFindingByGlobalSecondaryHashAndRangeIndexHashAndRangeKeyNonEqualityCondition_WhereSecondaryHashKeyIsPrimaryRangeKey() throws ParseException { setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByPlaylistNameAndDisplayNameAfter", 2, "userName", "playlistName"); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Mockito.when(mockPlaylistEntityMetadata.isGlobalIndexHashKeyProperty("playlistName")).thenReturn(true); Mockito.when(mockPlaylistEntityMetadata.isGlobalIndexRangeKeyProperty("displayName")).thenReturn(true); Map<String, String[]> indexRangeKeySecondaryIndexNames = new HashMap<String,String[]>(); indexRangeKeySecondaryIndexNames.put("playlistName", new String[] {"PlaylistName-DisplayName-index"}); indexRangeKeySecondaryIndexNames.put("displayName", new String[] {"PlaylistName-DisplayName-index"}); Mockito.when(mockPlaylistEntityMetadata.getGlobalSecondaryIndexNamesByPropertyName()).thenReturn(indexRangeKeySecondaryIndexNames); Mockito.when(mockPlaylistEntityMetadata.getDynamoDBTableName()).thenReturn("playlist"); // Mock out specific QueryRequestMapper behavior expected by this method ArgumentCaptor<QueryRequest> queryCaptor = ArgumentCaptor.forClass(QueryRequest.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockPlaylistQueryResults.get(0)).thenReturn(mockPlaylist); Mockito.when(mockPlaylistQueryResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.query(classCaptor.capture(), queryCaptor.capture())) .thenReturn(mockPlaylistQueryResults); Mockito.when(mockDynamoDBOperations.getOverriddenTableName("playlist")).thenReturn("playlist"); // Execute the query Object[] parameters = new Object[] { "SomePlaylistName","Michael"}; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(mockPlaylistQueryResults, o); assertEquals(1, mockPlaylistQueryResults.size()); assertEquals(mockPlaylist, mockPlaylistQueryResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), Playlist.class); String indexName = queryCaptor.getValue().getIndexName(); assertNotNull(indexName); assertEquals("PlaylistName-DisplayName-index",indexName); assertEquals("playlist",queryCaptor.getValue().getTableName()); // Assert that we have the correct conditions assertEquals(2,queryCaptor.getValue().getKeyConditions().size()); Condition globalRangeKeyCondition = queryCaptor.getValue().getKeyConditions().get("displayName"); assertEquals(ComparisonOperator.GT.name(),globalRangeKeyCondition.getComparisonOperator()); assertEquals(1,globalRangeKeyCondition.getAttributeValueList().size()); assertEquals("Michael",globalRangeKeyCondition.getAttributeValueList().get(0).getS()); Condition globalHashKeyCondition = queryCaptor.getValue().getKeyConditions().get("playlistName"); assertEquals(ComparisonOperator.EQ.name(),globalHashKeyCondition.getComparisonOperator()); assertEquals(1,globalHashKeyCondition.getAttributeValueList().size()); assertEquals("SomePlaylistName",globalHashKeyCondition.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getSS()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getN()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getNS()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getB()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getBS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getSS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getN()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getNS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getB()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).query(classCaptor.getValue(), queryCaptor.getValue()); } // Global Secondary Index Test 4g @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeKeyList_WhenFindingByGlobalSecondaryHashAndRangeIndexHashAndRangeKeyNonEqualityCondition_WhereSecondaryRangeKeyIsPrimaryRangeKey() throws ParseException { setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByDisplayNameAndPlaylistNameAfter", 2, "userName", "playlistName"); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Mockito.when(mockPlaylistEntityMetadata.isGlobalIndexHashKeyProperty("displayName")).thenReturn(true); Mockito.when(mockPlaylistEntityMetadata.isGlobalIndexRangeKeyProperty("playlistName")).thenReturn(true); Map<String, String[]> indexRangeKeySecondaryIndexNames = new HashMap<String,String[]>(); indexRangeKeySecondaryIndexNames.put("displayName", new String[] {"DisplayName-PlaylistName-index"}); indexRangeKeySecondaryIndexNames.put("playlistName", new String[] {"DisplayName-PlaylistName-index"}); Mockito.when(mockPlaylistEntityMetadata.getGlobalSecondaryIndexNamesByPropertyName()).thenReturn(indexRangeKeySecondaryIndexNames); Mockito.when(mockPlaylistEntityMetadata.getDynamoDBTableName()).thenReturn("playlist"); // Mock out specific QueryRequestMapper behavior expected by this method ArgumentCaptor<QueryRequest> queryCaptor = ArgumentCaptor.forClass(QueryRequest.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockPlaylistQueryResults.get(0)).thenReturn(mockPlaylist); Mockito.when(mockPlaylistQueryResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.query(classCaptor.capture(), queryCaptor.capture())) .thenReturn(mockPlaylistQueryResults); Mockito.when(mockDynamoDBOperations.getOverriddenTableName("playlist")).thenReturn("playlist"); // Execute the query Object[] parameters = new Object[] { "SomeDisplayName","SomePlaylistName"}; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(mockPlaylistQueryResults, o); assertEquals(1, mockPlaylistQueryResults.size()); assertEquals(mockPlaylist, mockPlaylistQueryResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), Playlist.class); String indexName = queryCaptor.getValue().getIndexName(); assertNotNull(indexName); assertEquals("DisplayName-PlaylistName-index",indexName); assertEquals("playlist",queryCaptor.getValue().getTableName()); // Assert that we have the correct conditions assertEquals(2,queryCaptor.getValue().getKeyConditions().size()); Condition globalRangeKeyCondition = queryCaptor.getValue().getKeyConditions().get("displayName"); assertEquals(ComparisonOperator.EQ.name(),globalRangeKeyCondition.getComparisonOperator()); assertEquals(1,globalRangeKeyCondition.getAttributeValueList().size()); assertEquals("SomeDisplayName",globalRangeKeyCondition.getAttributeValueList().get(0).getS()); Condition globalHashKeyCondition = queryCaptor.getValue().getKeyConditions().get("playlistName"); assertEquals(ComparisonOperator.GT.name(),globalHashKeyCondition.getComparisonOperator()); assertEquals(1,globalHashKeyCondition.getAttributeValueList().size()); assertEquals("SomePlaylistName",globalHashKeyCondition.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getSS()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getN()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getNS()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getB()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getBS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getSS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getN()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getNS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getB()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).query(classCaptor.getValue(), queryCaptor.getValue()); } // Global Secondary Index Test 4h @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityWithCompositeKeyList_WhenFindingByGlobalSecondaryHashAndRangeIndexHashAndRangeKeyNonEqualityCondition_WhereSecondaryRangeKeyIsPrimaryHashKey() throws ParseException { setupCommonMocksForThisRepositoryMethod(mockPlaylistEntityMetadata, mockDynamoDBPlaylistQueryMethod, Playlist.class, "findByDisplayNameAndUserNameAfter", 2, "userName", "playlistName"); Mockito.when(mockDynamoDBPlaylistQueryMethod.isCollectionQuery()).thenReturn(true); Mockito.when(mockPlaylistEntityMetadata.isGlobalIndexHashKeyProperty("displayName")).thenReturn(true); Mockito.when(mockPlaylistEntityMetadata.isGlobalIndexRangeKeyProperty("userName")).thenReturn(true); Map<String, String[]> indexRangeKeySecondaryIndexNames = new HashMap<String,String[]>(); indexRangeKeySecondaryIndexNames.put("displayName", new String[] {"DisplayName-UserName-index"}); indexRangeKeySecondaryIndexNames.put("userName", new String[] {"DisplayName-UserName-index"}); Mockito.when(mockPlaylistEntityMetadata.getGlobalSecondaryIndexNamesByPropertyName()).thenReturn(indexRangeKeySecondaryIndexNames); Mockito.when(mockPlaylistEntityMetadata.getDynamoDBTableName()).thenReturn("playlist"); // Mock out specific QueryRequestMapper behavior expected by this method ArgumentCaptor<QueryRequest> queryCaptor = ArgumentCaptor.forClass(QueryRequest.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockPlaylistQueryResults.get(0)).thenReturn(mockPlaylist); Mockito.when(mockPlaylistQueryResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.query(classCaptor.capture(), queryCaptor.capture())) .thenReturn(mockPlaylistQueryResults); Mockito.when(mockDynamoDBOperations.getOverriddenTableName("playlist")).thenReturn("playlist"); // Execute the query Object[] parameters = new Object[] { "SomeDisplayName","SomeUserName"}; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(mockPlaylistQueryResults, o); assertEquals(1, mockPlaylistQueryResults.size()); assertEquals(mockPlaylist, mockPlaylistQueryResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), Playlist.class); String indexName = queryCaptor.getValue().getIndexName(); assertNotNull(indexName); assertEquals("DisplayName-UserName-index",indexName); assertEquals("playlist",queryCaptor.getValue().getTableName()); // Assert that we have the correct conditions assertEquals(2,queryCaptor.getValue().getKeyConditions().size()); Condition globalRangeKeyCondition = queryCaptor.getValue().getKeyConditions().get("displayName"); assertEquals(ComparisonOperator.EQ.name(),globalRangeKeyCondition.getComparisonOperator()); assertEquals(1,globalRangeKeyCondition.getAttributeValueList().size()); assertEquals("SomeDisplayName",globalRangeKeyCondition.getAttributeValueList().get(0).getS()); Condition globalHashKeyCondition = queryCaptor.getValue().getKeyConditions().get("userName"); assertEquals(ComparisonOperator.GT.name(),globalHashKeyCondition.getComparisonOperator()); assertEquals(1,globalHashKeyCondition.getAttributeValueList().size()); assertEquals("SomeUserName",globalHashKeyCondition.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getSS()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getN()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getNS()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getB()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getBS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getSS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getN()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getNS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getB()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).query(classCaptor.getValue(), queryCaptor.getValue()); } // Global Secondary Index Test 4i @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityByGlobalSecondaryHashAndRangeIndexHashAndRangeKeyNonEqualityCondition_WhereBothSecondaryHashKeyAndSecondaryIndexRangeKeyMembersOfMultipleIndexes() throws ParseException { setupCommonMocksForThisRepositoryMethod(mockUserEntityMetadata, mockDynamoDBUserQueryMethod, User.class, "findByNameAndPostCodeAfter", 2, "id", null); Mockito.when(mockDynamoDBUserQueryMethod.isCollectionQuery()).thenReturn(true); Mockito.when(mockUserEntityMetadata.isGlobalIndexHashKeyProperty("name")).thenReturn(true); Mockito.when(mockUserEntityMetadata.isGlobalIndexRangeKeyProperty("postCode")).thenReturn(true); Map<String, String[]> indexRangeKeySecondaryIndexNames = new HashMap<String,String[]>(); indexRangeKeySecondaryIndexNames.put("name", new String[] {"Name-PostCode-index","Name-JoinYear-index"}); indexRangeKeySecondaryIndexNames.put("postCode", new String[] {"Name-PostCode-index","Id-PostCode-index"}); Mockito.when(mockUserEntityMetadata.getGlobalSecondaryIndexNamesByPropertyName()).thenReturn(indexRangeKeySecondaryIndexNames); Mockito.when(mockUserEntityMetadata.getDynamoDBTableName()).thenReturn("user"); // Mock out specific QueryRequestMapper behavior expected by this method ArgumentCaptor<QueryRequest> queryCaptor = ArgumentCaptor.forClass(QueryRequest.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockUserQueryResults.get(0)).thenReturn(mockUser); Mockito.when(mockUserQueryResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.query(classCaptor.capture(), queryCaptor.capture())) .thenReturn(mockUserQueryResults); Mockito.when(mockDynamoDBOperations.getOverriddenTableName("user")).thenReturn("user"); // Execute the query Object[] parameters = new Object[] { "SomeName","SomePostCode"}; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(mockUserQueryResults, o); assertEquals(1, mockUserQueryResults.size()); assertEquals(mockUser, mockUserQueryResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), User.class); String indexName = queryCaptor.getValue().getIndexName(); assertNotNull(indexName); assertEquals("Name-PostCode-index",indexName); assertEquals("user",queryCaptor.getValue().getTableName()); // Assert that we have the correct conditions assertEquals(2,queryCaptor.getValue().getKeyConditions().size()); Condition globalRangeKeyCondition = queryCaptor.getValue().getKeyConditions().get("name"); assertEquals(ComparisonOperator.EQ.name(),globalRangeKeyCondition.getComparisonOperator()); assertEquals(1,globalRangeKeyCondition.getAttributeValueList().size()); assertEquals("SomeName",globalRangeKeyCondition.getAttributeValueList().get(0).getS()); Condition globalHashKeyCondition = queryCaptor.getValue().getKeyConditions().get("postCode"); assertEquals(ComparisonOperator.GT.name(),globalHashKeyCondition.getComparisonOperator()); assertEquals(1,globalHashKeyCondition.getAttributeValueList().size()); assertEquals("SomePostCode",globalHashKeyCondition.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getSS()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getN()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getNS()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getB()); assertNull(globalRangeKeyCondition.getAttributeValueList().get(0).getBS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getSS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getN()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getNS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getB()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).query(classCaptor.getValue(), queryCaptor.getValue()); } // Global Secondary Index Test 4j @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityByGlobalSecondaryHashAndRangeIndexHashCondition_WhereSecondaryHashKeyMemberOfMultipleIndexes() throws ParseException { setupCommonMocksForThisRepositoryMethod(mockUserEntityMetadata, mockDynamoDBUserQueryMethod, User.class, "findByName", 1, "id", null); Mockito.when(mockDynamoDBUserQueryMethod.isCollectionQuery()).thenReturn(true); Mockito.when(mockUserEntityMetadata.isGlobalIndexHashKeyProperty("name")).thenReturn(true); Mockito.when(mockUserEntityMetadata.isGlobalIndexRangeKeyProperty("postCode")).thenReturn(true); Mockito.when(mockUserEntityMetadata.isGlobalIndexRangeKeyProperty("joinYear")).thenReturn(true); Mockito.when(mockUserEntityMetadata.isGlobalIndexHashKeyProperty("id")).thenReturn(true); Map<String, String[]> indexRangeKeySecondaryIndexNames = new HashMap<String,String[]>(); indexRangeKeySecondaryIndexNames.put("name", new String[] {"Name-PostCode-index","Name-JoinYear-index"}); indexRangeKeySecondaryIndexNames.put("postCode", new String[] {"Name-PostCode-index","Id-PostCode-index"}); indexRangeKeySecondaryIndexNames.put("joinYear", new String[] {"Name-JoinYear-index"}); indexRangeKeySecondaryIndexNames.put("id", new String[] {"Id-PostCode-index"}); Mockito.when(mockUserEntityMetadata.getGlobalSecondaryIndexNamesByPropertyName()).thenReturn(indexRangeKeySecondaryIndexNames); Mockito.when(mockUserEntityMetadata.getDynamoDBTableName()).thenReturn("user"); // Mock out specific QueryRequestMapper behavior expected by this method ArgumentCaptor<QueryRequest> queryCaptor = ArgumentCaptor.forClass(QueryRequest.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockUserQueryResults.get(0)).thenReturn(mockUser); Mockito.when(mockUserQueryResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.query(classCaptor.capture(), queryCaptor.capture())) .thenReturn(mockUserQueryResults); Mockito.when(mockDynamoDBOperations.getOverriddenTableName("user")).thenReturn("user"); // Execute the query Object[] parameters = new Object[] { "SomeName"}; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(mockUserQueryResults, o); assertEquals(1, mockUserQueryResults.size()); assertEquals(mockUser, mockUserQueryResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), User.class); String indexName = queryCaptor.getValue().getIndexName(); assertNotNull(indexName); assertEquals("Name-PostCode-index",indexName); assertEquals("user",queryCaptor.getValue().getTableName()); // Assert that we have the correct conditions Condition globalHashKeyCondition = queryCaptor.getValue().getKeyConditions().get("name"); assertEquals(ComparisonOperator.EQ.name(),globalHashKeyCondition.getComparisonOperator()); assertEquals(1,globalHashKeyCondition.getAttributeValueList().size()); assertEquals("SomeName",globalHashKeyCondition.getAttributeValueList().get(0).getS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getSS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getN()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getNS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getB()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).query(classCaptor.getValue(), queryCaptor.getValue()); } // Global Secondary Index Test 4k @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityByGlobalSecondaryHashAndRangeIndexHashCondition_WhereSecondaryHashKeyMemberOfMultipleIndexes_WhereOneIndexIsExactMatch() throws ParseException { setupCommonMocksForThisRepositoryMethod(mockUserEntityMetadata, mockDynamoDBUserQueryMethod, User.class, "findByName", 1, "id", null); Mockito.when(mockDynamoDBUserQueryMethod.isCollectionQuery()).thenReturn(true); Mockito.when(mockUserEntityMetadata.isGlobalIndexHashKeyProperty("name")).thenReturn(true); Mockito.when(mockUserEntityMetadata.isGlobalIndexRangeKeyProperty("postCode")).thenReturn(true); Mockito.when(mockUserEntityMetadata.isGlobalIndexRangeKeyProperty("joinYear")).thenReturn(true); Mockito.when(mockUserEntityMetadata.isGlobalIndexHashKeyProperty("id")).thenReturn(true); Map<String, String[]> indexRangeKeySecondaryIndexNames = new HashMap<String,String[]>(); indexRangeKeySecondaryIndexNames.put("name", new String[] {"Name-PostCode-index","Name-index","Name-JoinYear-index"}); indexRangeKeySecondaryIndexNames.put("postCode", new String[] {"Name-PostCode-index","Id-PostCode-index"}); indexRangeKeySecondaryIndexNames.put("joinYear", new String[] {"Name-JoinYear-index"}); indexRangeKeySecondaryIndexNames.put("id", new String[] {"Id-PostCode-index"}); Mockito.when(mockUserEntityMetadata.getGlobalSecondaryIndexNamesByPropertyName()).thenReturn(indexRangeKeySecondaryIndexNames); Mockito.when(mockUserEntityMetadata.getDynamoDBTableName()).thenReturn("user"); // Mock out specific QueryRequestMapper behavior expected by this method ArgumentCaptor<QueryRequest> queryCaptor = ArgumentCaptor.forClass(QueryRequest.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockUserQueryResults.get(0)).thenReturn(mockUser); Mockito.when(mockUserQueryResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.query(classCaptor.capture(), queryCaptor.capture())) .thenReturn(mockUserQueryResults); Mockito.when(mockDynamoDBOperations.getOverriddenTableName("user")).thenReturn("user"); // Execute the query Object[] parameters = new Object[] { "SomeName"}; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected results assertEquals(mockUserQueryResults, o); assertEquals(1, mockUserQueryResults.size()); assertEquals(mockUser, mockUserQueryResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), User.class); String indexName = queryCaptor.getValue().getIndexName(); assertNotNull(indexName); assertEquals("Name-index",indexName); assertEquals("user",queryCaptor.getValue().getTableName()); // Assert that we have the correct conditions Condition globalHashKeyCondition = queryCaptor.getValue().getKeyConditions().get("name"); assertEquals(ComparisonOperator.EQ.name(),globalHashKeyCondition.getComparisonOperator()); assertEquals(1,globalHashKeyCondition.getAttributeValueList().size()); assertEquals("SomeName",globalHashKeyCondition.getAttributeValueList().get(0).getS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getSS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getN()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getNS()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getB()); assertNull(globalHashKeyCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).query(classCaptor.getValue(), queryCaptor.getValue()); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityList_WithSingleStringParameter_WithCustomMarshaller_WhenNotFindingByHashKey() throws ParseException { String postcode = "N1"; setupCommonMocksForThisRepositoryMethod(mockUserEntityMetadata, mockDynamoDBUserQueryMethod, User.class, "findByPostCode", 1, "id", null); Mockito.when(mockDynamoDBUserQueryMethod.isCollectionQuery()).thenReturn(true); DynamoDBMarshaller marshaller = new CaseChangingMarshaller(); Mockito.when(mockUserEntityMetadata.getMarshallerForProperty("postCode")).thenReturn(marshaller); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBScanExpression> scanCaptor = ArgumentCaptor.forClass(DynamoDBScanExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockUserScanResults.get(0)).thenReturn(mockUser); Mockito.when(mockUserScanResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.scan(classCaptor.capture(), scanCaptor.capture())).thenReturn( mockUserScanResults); // Execute the query Object[] parameters = new Object[] { postcode }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected list of results assertEquals(o, mockUserScanResults); // Assert that the list of results contains the correct elements assertEquals(1, mockUserScanResults.size()); assertEquals(mockUser, mockUserScanResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), User.class); // Assert that we have only one filter condition, for the name of the // property Map<String, Condition> filterConditions = scanCaptor.getValue().getScanFilter(); assertEquals(1, filterConditions.size()); Condition filterCondition = filterConditions.get("postCode"); assertNotNull(filterCondition); assertEquals(ComparisonOperator.EQ.name(), filterCondition.getComparisonOperator()); // Assert we only have one attribute value for this filter condition assertEquals(1, filterCondition.getAttributeValueList().size()); // Assert that there the attribute value type for this attribute value // is String, // and its value is the parameter expected assertEquals("n1", filterCondition.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(filterCondition.getAttributeValueList().get(0).getSS()); assertNull(filterCondition.getAttributeValueList().get(0).getN()); assertNull(filterCondition.getAttributeValueList().get(0).getNS()); assertNull(filterCondition.getAttributeValueList().get(0).getB()); assertNull(filterCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).scan(classCaptor.getValue(), scanCaptor.getValue()); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityList_WithSingleIntegerParameter_WhenNotFindingByHashKey() { int numberOfPlaylists = 5; setupCommonMocksForThisRepositoryMethod(mockUserEntityMetadata, mockDynamoDBUserQueryMethod, User.class, "findByNumberOfPlaylists", 1, "id", null); Mockito.when(mockDynamoDBUserQueryMethod.isCollectionQuery()).thenReturn(true); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBScanExpression> scanCaptor = ArgumentCaptor.forClass(DynamoDBScanExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockUserScanResults.get(0)).thenReturn(mockUser); Mockito.when(mockUserScanResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.scan(classCaptor.capture(), scanCaptor.capture())).thenReturn( mockUserScanResults); // Execute the query Object[] parameters = new Object[] { numberOfPlaylists }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected list of results assertEquals(o, mockUserScanResults); // Assert that the list of results contains the correct elements assertEquals(1, mockUserScanResults.size()); assertEquals(mockUser, mockUserScanResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), User.class); // Assert that we have only one filter condition, for the name of the // property Map<String, Condition> filterConditions = scanCaptor.getValue().getScanFilter(); assertEquals(1, filterConditions.size()); Condition filterCondition = filterConditions.get("numberOfPlaylists"); assertNotNull(filterCondition); assertEquals(ComparisonOperator.EQ.name(), filterCondition.getComparisonOperator()); // Assert we only have one attribute value for this filter condition assertEquals(1, filterCondition.getAttributeValueList().size()); // Assert that there the attribute value type for this attribute value // is Number, // and its Dynamo value is the number as a string assertEquals("5", filterCondition.getAttributeValueList().get(0).getN()); // Assert that all other attribute value types other than String type // are null assertNull(filterCondition.getAttributeValueList().get(0).getNS()); assertNull(filterCondition.getAttributeValueList().get(0).getS()); assertNull(filterCondition.getAttributeValueList().get(0).getSS()); assertNull(filterCondition.getAttributeValueList().get(0).getB()); assertNull(filterCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).scan(classCaptor.getValue(), scanCaptor.getValue()); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityList_WithSingleStringParameter_WhenNotFindingByNotHashKey() { setupCommonMocksForThisRepositoryMethod(mockUserEntityMetadata, mockDynamoDBUserQueryMethod, User.class, "findByIdNot", 1, "id", null); Mockito.when(mockDynamoDBUserQueryMethod.isCollectionQuery()).thenReturn(true); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBScanExpression> scanCaptor = ArgumentCaptor.forClass(DynamoDBScanExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockUserScanResults.get(0)).thenReturn(mockUser); Mockito.when(mockUserScanResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.scan(classCaptor.capture(), scanCaptor.capture())).thenReturn( mockUserScanResults); // Execute the query Object[] parameters = new Object[] { "someId" }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected list of results assertEquals(o, mockUserScanResults); // Assert that the list of results contains the correct elements assertEquals(1, mockUserScanResults.size()); assertEquals(mockUser, mockUserScanResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), User.class); // Assert that we have only one filter condition, for the name of the // property Map<String, Condition> filterConditions = scanCaptor.getValue().getScanFilter(); assertEquals(1, filterConditions.size()); Condition filterCondition = filterConditions.get("id"); assertNotNull(filterCondition); assertEquals(ComparisonOperator.NE.name(), filterCondition.getComparisonOperator()); // Assert we only have one attribute value for this filter condition assertEquals(1, filterCondition.getAttributeValueList().size()); // Assert that there the attribute value type for this attribute value // is String, // and its value is the parameter expected assertEquals("someId", filterCondition.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(filterCondition.getAttributeValueList().get(0).getSS()); assertNull(filterCondition.getAttributeValueList().get(0).getN()); assertNull(filterCondition.getAttributeValueList().get(0).getNS()); assertNull(filterCondition.getAttributeValueList().get(0).getB()); assertNull(filterCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).scan(classCaptor.getValue(), scanCaptor.getValue()); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Test public void testExecute_WhenFinderMethodIsFindingEntityList_WithSingleStringParameter_WhenNotFindingByNotAProperty() { setupCommonMocksForThisRepositoryMethod(mockUserEntityMetadata, mockDynamoDBUserQueryMethod, User.class, "findByNameNot", 1, "id", null); Mockito.when(mockDynamoDBUserQueryMethod.isCollectionQuery()).thenReturn(true); // Mock out specific DynamoDBOperations behavior expected by this method ArgumentCaptor<DynamoDBScanExpression> scanCaptor = ArgumentCaptor.forClass(DynamoDBScanExpression.class); ArgumentCaptor<Class> classCaptor = ArgumentCaptor.forClass(Class.class); Mockito.when(mockUserScanResults.get(0)).thenReturn(mockUser); Mockito.when(mockUserScanResults.size()).thenReturn(1); Mockito.when(mockDynamoDBOperations.scan(classCaptor.capture(), scanCaptor.capture())).thenReturn( mockUserScanResults); // Execute the query Object[] parameters = new Object[] { "someName" }; Object o = partTreeDynamoDBQuery.execute(parameters); // Assert that we obtain the expected list of results assertEquals(o, mockUserScanResults); // Assert that the list of results contains the correct elements assertEquals(1, mockUserScanResults.size()); assertEquals(mockUser, mockUserScanResults.get(0)); // Assert that we scanned DynamoDB for the correct class assertEquals(classCaptor.getValue(), User.class); // Assert that we have only one filter condition, for the name of the // property Map<String, Condition> filterConditions = scanCaptor.getValue().getScanFilter(); assertEquals(1, filterConditions.size()); Condition filterCondition = filterConditions.get("name"); assertNotNull(filterCondition); assertEquals(ComparisonOperator.NE.name(), filterCondition.getComparisonOperator()); // Assert we only have one attribute value for this filter condition assertEquals(1, filterCondition.getAttributeValueList().size()); // Assert that there the attribute value type for this attribute value // is String, // and its value is the parameter expected assertEquals("someName", filterCondition.getAttributeValueList().get(0).getS()); // Assert that all other attribute value types other than String type // are null assertNull(filterCondition.getAttributeValueList().get(0).getSS()); assertNull(filterCondition.getAttributeValueList().get(0).getN()); assertNull(filterCondition.getAttributeValueList().get(0).getNS()); assertNull(filterCondition.getAttributeValueList().get(0).getB()); assertNull(filterCondition.getAttributeValueList().get(0).getBS()); // Verify that the expected DynamoDBOperations method was called Mockito.verify(mockDynamoDBOperations).scan(classCaptor.getValue(), scanCaptor.getValue()); } }