Skip to content

Commit 3afc024

Browse files
committed
Added Mockito framework to tests.
Added ShoppingCartRepository.
1 parent 2552998 commit 3afc024

24 files changed

+1085
-564
lines changed

source/.idea/libraries/com_google_dexmaker_dexmaker_mockito_1_2.xml

+18
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

source/.idea/workspace.xml

+514-462
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

source/shoppingbot-lambda.iml

+1
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,6 @@
3232
</orderEntry>
3333
<orderEntry type="library" name="com.amazonaws:aws-java-sdk-dynamodb:1.11.113" level="project" />
3434
<orderEntry type="library" scope="TEST" name="DynamoDBLocal" level="project" />
35+
<orderEntry type="library" scope="TEST" name="com.google.dexmaker:dexmaker-mockito:1.2" level="project" />
3536
</component>
3637
</module>
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package io.github.satr.aws.lambda.shoppingbot.data;
22

33
public interface RepositoryFactory{
4+
UserRepository getUserRepository();
5+
ShoppingCartRepository getShoppingCartRepository();
46
void shutdown();
57
}

source/src/io/github/satr/aws/lambda/shoppingbot/data/RepositoryFactoryImpl.java

+7
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,24 @@ public class RepositoryFactoryImpl implements RepositoryFactory {
99
private final AmazonDynamoDB dynamoDbClient;
1010
private final DynamoDBMapper dbMapper;
1111
private UserRepository userRepository;
12+
private ShoppingCartRepository shoppingCartRepository;
1213

1314
public RepositoryFactoryImpl() {
1415
dynamoDbClient = AmazonDynamoDBClientBuilder.standard()
1516
.withRegion(Regions.US_EAST_1).build();
1617
dbMapper = new DynamoDBMapper(dynamoDbClient);
1718
}
1819

20+
@Override
1921
public UserRepository getUserRepository() {
2022
return userRepository != null ? userRepository : (userRepository = new UserRepositoryImpl(dynamoDbClient, dbMapper));
2123
}
2224

25+
@Override
26+
public ShoppingCartRepository getShoppingCartRepository() {
27+
return shoppingCartRepository != null ? shoppingCartRepository : (shoppingCartRepository = new ShoppingCartRepositoryImpl(dynamoDbClient, dbMapper));
28+
}
29+
2330
@Override
2431
public void shutdown() {
2532
userRepository = null;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package io.github.satr.aws.lambda.shoppingbot.data;
2+
3+
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
4+
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
5+
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBScanExpression;
6+
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
7+
import io.github.satr.aws.lambda.shoppingbot.entity.ShoppingCart;
8+
9+
import java.util.HashMap;
10+
import java.util.List;
11+
import java.util.Map;
12+
13+
public class RepositoryImpl {
14+
protected final DynamoDBMapper dbMapper;
15+
protected AmazonDynamoDB dynamodb;
16+
17+
public RepositoryImpl(AmazonDynamoDB dynamodb, DynamoDBMapper dbMapper) {
18+
this.dynamodb = dynamodb;
19+
this.dbMapper = dbMapper;
20+
}
21+
22+
protected <T> List<T> scan(Class<T> type, String filterExpression, Map<String, AttributeValue> expressionValueMap) {
23+
DynamoDBScanExpression scanExpression = new DynamoDBScanExpression()
24+
.withFilterExpression(filterExpression)
25+
.withExpressionAttributeValues(expressionValueMap);
26+
return dbMapper.scan(type, scanExpression);
27+
}
28+
29+
protected <T> List<T> scan(Class<T> type, String name, String value) {
30+
String attrValue = ":v_attr";
31+
String filterExpression = String.format("%s=%s", name, attrValue);
32+
Map<String, AttributeValue> expressionValueMap = new HashMap<>();
33+
expressionValueMap.put(attrValue, new AttributeValue().withS(value));
34+
return scan(type, filterExpression, expressionValueMap);
35+
}
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package io.github.satr.aws.lambda.shoppingbot.data;
2+
3+
import com.sun.media.sound.InvalidDataException;
4+
import io.github.satr.aws.lambda.shoppingbot.entity.ShoppingCart;
5+
6+
import java.util.List;
7+
8+
public interface ShoppingCartRepository extends Repository {
9+
List<ShoppingCart> getList();
10+
11+
ShoppingCart getById(String cartId) throws InvalidDataException;
12+
13+
List<ShoppingCart> getByUserId(String userId);
14+
List<ShoppingCart> getBySessionId(String sessionId);
15+
void save(ShoppingCart cart);
16+
void delete(ShoppingCart cart);
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package io.github.satr.aws.lambda.shoppingbot.data;
2+
3+
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
4+
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
5+
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBScanExpression;
6+
import com.sun.media.sound.InvalidDataException;
7+
import io.github.satr.aws.lambda.shoppingbot.entity.ShoppingCart;
8+
9+
import java.time.ZoneId;
10+
import java.time.ZonedDateTime;
11+
import java.util.List;
12+
13+
public class ShoppingCartRepositoryImpl extends RepositoryImpl implements ShoppingCartRepository {
14+
public final class Attr {
15+
public final static String CartId = "cart_id";
16+
public final static String SessionId = "session_id";
17+
public final static String UpdatedOn = "updated_on";
18+
public final static String UserId = "user_id";
19+
public final static String FirstName = "first_name";
20+
public final static String LastName = "last_name";
21+
public final static String Address = "address";
22+
}
23+
24+
public final static String TableName = "ShoppingCart";
25+
26+
public ShoppingCartRepositoryImpl(AmazonDynamoDB dynamodb, DynamoDBMapper dbMapper) {
27+
super(dynamodb, dbMapper);
28+
}
29+
30+
@Override
31+
public void save(ShoppingCart cart) {
32+
cart.setUpdatedOn(ZonedDateTime.now(ZoneId.of("UTC")).toString());
33+
dbMapper.save(cart);
34+
}
35+
36+
@Override
37+
public List<ShoppingCart> getList() {
38+
return dbMapper.scan(ShoppingCart.class, new DynamoDBScanExpression());
39+
}
40+
41+
@Override
42+
public ShoppingCart getById(String cartId) throws InvalidDataException {
43+
return dbMapper.load(ShoppingCart.class, cartId);
44+
}
45+
46+
@Override
47+
public List<ShoppingCart> getByUserId(String userId) {
48+
return scan(ShoppingCart.class, Attr.UserId, userId);
49+
}
50+
51+
@Override
52+
public List<ShoppingCart> getBySessionId(String sessionId) {
53+
return scan(ShoppingCart.class, Attr.SessionId, sessionId);
54+
}
55+
56+
@Override
57+
public void delete(ShoppingCart cart) {
58+
dbMapper.delete(cart);
59+
}
60+
}

source/src/io/github/satr/aws/lambda/shoppingbot/data/UserRepositoryImpl.java

+2-6
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@
1111
import java.util.List;
1212
import java.util.Map;
1313

14-
public class UserRepositoryImpl implements UserRepository {
14+
public class UserRepositoryImpl extends RepositoryImpl implements UserRepository {
1515
public final static String TableName = "User";
16-
private final DynamoDBMapper dbMapper;
1716

1817
public final class Attr {
1918
public final static String UserId = "user_id";
@@ -22,11 +21,8 @@ public final class Attr {
2221
public final static String Address = "address";
2322
}
2423

25-
private AmazonDynamoDB dynamodb;
26-
2724
public UserRepositoryImpl(AmazonDynamoDB dynamodb, DynamoDBMapper dbMapper) {
28-
this.dynamodb = dynamodb;
29-
this.dbMapper = dbMapper;
25+
super(dynamodb, dbMapper);
3026
}
3127

3228
@Override
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package io.github.satr.aws.lambda.shoppingbot.entity;
2+
3+
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute;
4+
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
5+
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBIgnore;
6+
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;
7+
8+
import java.time.ZoneId;
9+
import java.time.ZonedDateTime;
10+
import java.util.UUID;
11+
12+
@DynamoDBTable(tableName = "ShoppingCart")
13+
public class ShoppingCart {
14+
private String cartId;
15+
private String userId;
16+
private User user;
17+
private String sessionId;
18+
private String updatedOn;
19+
private ZonedDateTime updatedOnAsDate;
20+
21+
public ShoppingCart() {
22+
setCartId(UUID.randomUUID().toString());
23+
}
24+
25+
@DynamoDBHashKey(attributeName="cart_id")
26+
public String getCartId() {
27+
return cartId;
28+
}
29+
30+
public void setCartId(String cartId) {
31+
this.cartId = cartId;
32+
}
33+
34+
@DynamoDBAttribute(attributeName = "user_id")
35+
public String getUserId() {
36+
return userId;
37+
}
38+
39+
public void setUserId(String userId) {
40+
this.userId = userId;
41+
}
42+
43+
@DynamoDBAttribute(attributeName = "session_id")
44+
public String getSessionId() {
45+
return sessionId;
46+
}
47+
48+
public void setSessionId(String sessionId) {
49+
this.sessionId = sessionId;
50+
}
51+
52+
@DynamoDBAttribute(attributeName = "updated_on")
53+
public String getUpdatedOn() {
54+
return updatedOn;
55+
}
56+
57+
public void setUpdatedOn(String updatedOn) {
58+
this.updatedOn = updatedOn;
59+
updatedOnAsDate = null;
60+
}
61+
62+
private ZonedDateTime getUtc() {
63+
return ZonedDateTime.now(ZoneId.of("UTC"));
64+
}
65+
66+
@DynamoDBIgnore
67+
public User getUser() {
68+
return user;
69+
}
70+
71+
@DynamoDBIgnore
72+
public void setUser(User user) {
73+
this.user = user;
74+
if(user != null)
75+
setUserId(user.getUserId());
76+
}
77+
78+
@Override
79+
public String toString() {
80+
return "ShoppingCart{" +
81+
"cartId='" + cartId + '\'' +
82+
", userId='" + userId + '\'' +
83+
", sessionId='" + sessionId + '\'' +
84+
'}';
85+
}
86+
87+
@DynamoDBIgnore
88+
public ZonedDateTime getUpdatedOnAsDate() {
89+
if(updatedOnAsDate != null)
90+
return updatedOnAsDate;
91+
try {
92+
updatedOnAsDate = updatedOn != null && updatedOn.length() > 0 ? ZonedDateTime.parse(updatedOn) : getUtc();
93+
} catch (Exception e) {
94+
e.printStackTrace();
95+
updatedOnAsDate = getUtc();
96+
}
97+
return updatedOnAsDate;
98+
}
99+
}

source/src/io/github/satr/aws/lambda/shoppingbot/processing/ShoppingBotProcessor.java

+4
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
import io.github.satr.aws.lambda.shoppingbot.processing.strategies.IntentProcessingStrategy;
99
import io.github.satr.aws.lambda.shoppingbot.processing.strategies.UnsupportedIntentProcessingStrategy;
1010
import io.github.satr.aws.lambda.shoppingbot.request.LexRequest;
11+
import io.github.satr.aws.lambda.shoppingbot.request.LexRequestAttribute;
1112
import io.github.satr.aws.lambda.shoppingbot.response.LexResponse;
1213

1314
import java.util.LinkedHashMap;
1415
import java.util.Map;
16+
import java.util.UUID;
1517

1618
public class ShoppingBotProcessor {
1719
private RepositoryFactory repositoryFactory;
@@ -28,6 +30,8 @@ public ShoppingBotProcessor(RepositoryFactory repositoryFactory) {
2830
}
2931

3032
public LexResponse Process(LexRequest lexRequest) {
33+
if(lexRequest.getSessionAttribute(LexRequestAttribute.SessionAttribute.SessionId) == null)
34+
lexRequest.setSessionAttribute(LexRequestAttribute.SessionAttribute.SessionId, UUID.randomUUID().toString());
3135
return getProcessingStrategy(lexRequest.getIntentName()).Process(lexRequest);
3236
}
3337

source/src/io/github/satr/aws/lambda/shoppingbot/processing/strategies/RequestDepartmentProductProcessingStrategy.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@ public LexResponse Process(LexRequest lexRequest) {
1111
if(!lexRequest.requestedAmountIsSet() || !lexRequest.requestedProductIsSet())
1212
return LexResponseHelper.createFailedLexResponse("Product or amount are not specified.", lexRequest);
1313

14-
return LexResponseHelper.createLexResponse(lexRequest, buildContent(lexRequest),
15-
DialogAction.Type.Close,
16-
DialogAction.FulfillmentState.Fulfilled);
14+
15+
16+
LexResponse lexResponse = LexResponseHelper.createLexResponse(lexRequest, buildContent(lexRequest),
17+
DialogAction.Type.Close,
18+
DialogAction.FulfillmentState.Fulfilled);
19+
return lexResponse;
1720
}
1821

1922
private String buildContent(LexRequest lexRequest) {

source/src/io/github/satr/aws/lambda/shoppingbot/request/LexRequest.java

+8
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,12 @@ public String getAddress() {
123123
public void setAddress(String address) {
124124
this.address = address;
125125
}
126+
127+
public Object getSessionAttribute(String attributeName) {
128+
return sessionAttributes.containsKey(attributeName) ? sessionAttributes.get(attributeName) : null;
129+
}
130+
131+
public void setSessionAttribute(String attributeName, Object value) {
132+
sessionAttributes.put(attributeName, value);
133+
}
126134
}

source/src/io/github/satr/aws/lambda/shoppingbot/request/LexRequestAttribute.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,16 @@
33
public final class LexRequestAttribute {
44
public static final String Bot = "bot";
55
public static final String BotName = "name";
6-
public static final String SessionAttributes = "sessionAttributes";
76
public static final String CurrentIntent = "currentIntent";
87
public static final String CurrentIntentName = "name";
98
public static final String ConfirmationStatus = "confirmationStatus";
109
public static final String Slots = "slots";
1110
public static final String InvocationSource = "invocationSource";
1211
public static final String OutputDialogMode = "outputDialogMode";
12+
public static final String SessionAttributes = "sessionAttributes";
13+
public final class SessionAttribute{
14+
public static final String SessionId = "SessionId";
15+
public static final String FirstName = "FirstName";
16+
public static final String LastName = "LastName";
17+
}
1318
}

0 commit comments

Comments
 (0)