package software.amazon.awssdk.enhanced.dynamodb; import static org.assertj.core.api.Assertions.assertThat; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; import org.junit.jupiter.api.Test; import software.amazon.awssdk.enhanced.dynamodb.internal.ProjectionExpression; public class ProjectionExpressionTest { private static final String NESTING_SEPARATOR = "."; private static final String PROJ_EXP_SEPARATOR = ","; private static final Map EXPECTED_ATTRIBUTE_NAMES = new HashMap<>(); static { EXPECTED_ATTRIBUTE_NAMES.put("#AMZN_MAPPED_attribute", "attribute"); EXPECTED_ATTRIBUTE_NAMES.put("#AMZN_MAPPED_Attribute", "Attribute"); EXPECTED_ATTRIBUTE_NAMES.put("#AMZN_MAPPED_firstiteminlist[0]", "firstiteminlist[0]"); EXPECTED_ATTRIBUTE_NAMES.put("#AMZN_MAPPED_March_2021", "March-2021"); EXPECTED_ATTRIBUTE_NAMES.put("#AMZN_MAPPED_Why_Make_This_An_Attribute_Name", "Why.Make-This*An:Attribute:Name"); } @Test public void nullInputSetsStateCorrectly() { ProjectionExpression projectionExpression = ProjectionExpression.create(null); assertThat(projectionExpression.expressionAttributeNames()).isEmpty(); assertThat(projectionExpression.projectionExpressionAsString()).isEmpty(); } @Test public void emptyInputSetsStateCorrectly() { ProjectionExpression projectionExpression = ProjectionExpression.create(new ArrayList<>()); assertThat(projectionExpression.expressionAttributeNames()).isEmpty(); assertThat(projectionExpression.projectionExpressionAsString()).isEmpty(); } @Test public void severalTopLevelAttributes_handledCorrectly() { List attributeNames = EXPECTED_ATTRIBUTE_NAMES.values() .stream() .map(NestedAttributeName::create) .collect(Collectors.toList()); String expectedProjectionExpression = EXPECTED_ATTRIBUTE_NAMES.keySet() .stream() .collect(Collectors.joining(PROJ_EXP_SEPARATOR)); assertProjectionExpression(attributeNames, EXPECTED_ATTRIBUTE_NAMES, expectedProjectionExpression); } @Test public void severalNestedAttributes_handledCorrectly() { List attributeNames = Arrays.asList(NestedAttributeName.create( EXPECTED_ATTRIBUTE_NAMES.values() .stream() .collect(Collectors.toList()))); String expectedProjectionExpression = EXPECTED_ATTRIBUTE_NAMES.keySet() .stream() .collect(Collectors.joining(NESTING_SEPARATOR)); assertProjectionExpression(attributeNames, EXPECTED_ATTRIBUTE_NAMES, expectedProjectionExpression); } @Test public void nonUniqueAttributeNames_AreCollapsed() { Map expectedAttributeNames = new HashMap<>(); expectedAttributeNames.put("#AMZN_MAPPED_attribute", "attribute"); List attributeNames = Arrays.asList( NestedAttributeName.create("attribute", "attribute"), NestedAttributeName.create("attribute") ); String expectedProjectionExpression = "#AMZN_MAPPED_attribute.#AMZN_MAPPED_attribute,#AMZN_MAPPED_attribute"; assertProjectionExpression(attributeNames, expectedAttributeNames, expectedProjectionExpression); } @Test public void nonUniquePlaceholders_AreDisambiguated() { Map expectedAttributeNames = new HashMap<>(); expectedAttributeNames.put("#AMZN_MAPPED_0_attribute_03", "attribute-03"); expectedAttributeNames.put("#AMZN_MAPPED_1_attribute_03", "attribute.03"); expectedAttributeNames.put("#AMZN_MAPPED_2_attribute_03", "attribute:03"); List attributeNames = Arrays.asList( NestedAttributeName.create("attribute-03", "attribute.03"), NestedAttributeName.create("attribute:03") ); String expectedProjectionExpression = "#AMZN_MAPPED_0_attribute_03.#AMZN_MAPPED_1_attribute_03," + "#AMZN_MAPPED_2_attribute_03"; assertProjectionExpression(attributeNames, expectedAttributeNames, expectedProjectionExpression); } private void assertProjectionExpression(List attributeNames, Map expectedAttributeNames, String expectedProjectionExpression) { ProjectionExpression projectionExpression = ProjectionExpression.create(attributeNames); Map expressionAttributeNames = projectionExpression.expressionAttributeNames(); Optional projectionExpressionString = projectionExpression.projectionExpressionAsString(); assertThat(projectionExpressionString.get()).isEqualTo(expectedProjectionExpression); assertThat(expressionAttributeNames).isEqualTo(expectedAttributeNames); } }