Skip to content

Commit 0b7ddc2

Browse files
authored
Merge pull request #115 from matsumatsu20/modify-feature-notification
Modify feature notification
2 parents b43cdc8 + 8c6b142 commit 0b7ddc2

File tree

7 files changed

+213
-54
lines changed

7 files changed

+213
-54
lines changed

database-template.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,18 @@ Resources:
363363
KeyType: HASH
364364
- AttributeName: sort_key
365365
KeyType: RANGE
366+
GlobalSecondaryIndexes:
367+
- IndexName: user_id-sort_key-index
368+
KeySchema:
369+
- AttributeName: user_id
370+
KeyType: HASH
371+
- AttributeName: sort_key
372+
KeyType: RANGE
373+
Projection:
374+
ProjectionType: ALL
375+
ProvisionedThroughput:
376+
ReadCapacityUnits: !Ref MinDynamoReadCapacitty
377+
WriteCapacityUnits: !Ref MinDynamoWriteCapacitty
366378
ProvisionedThroughput:
367379
ReadCapacityUnits: !Ref MinDynamoReadCapacitty
368380
WriteCapacityUnits: !Ref MinDynamoWriteCapacitty

database.yaml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -327,15 +327,27 @@ Resources:
327327
Type: AWS::DynamoDB::Table
328328
Properties:
329329
AttributeDefinitions:
330+
- AttributeName: notification_id
331+
AttributeType: S
330332
- AttributeName: user_id
331333
AttributeType: S
332334
- AttributeName: sort_key
333335
AttributeType: N
334336
KeySchema:
335-
- AttributeName: user_id
337+
- AttributeName: notification_id
336338
KeyType: HASH
337-
- AttributeName: sort_key
338-
KeyType: RANGE
339+
GlobalSecondaryIndexes:
340+
- IndexName: user_id-sort_key-index
341+
KeySchema:
342+
- AttributeName: user_id
343+
KeyType: HASH
344+
- AttributeName: sort_key
345+
KeyType: RANGE
346+
Projection:
347+
ProjectionType: ALL
348+
ProvisionedThroughput:
349+
ReadCapacityUnits: 1
350+
WriteCapacityUnits: 1
339351
ProvisionedThroughput:
340352
ReadCapacityUnits: 1
341353
WriteCapacityUnits: 1

src/common/settings.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@
7070
'type': 'string',
7171
'maxLength': 100
7272
},
73+
'notification_id': {
74+
'type': 'string',
75+
'maxLength': 80
76+
}
7377
}
7478

7579
article_recent_default_limit = 20

src/handlers/me/articles/like/create/me_articles_like_create.py

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import json
66
import logging
77
import traceback
8+
from boto3.dynamodb.conditions import Key
89
from db_util import DBUtil
910
from botocore.exceptions import ClientError
1011
from lambda_base import LambdaBase
@@ -62,17 +63,35 @@ def exec_main_proc(self):
6263

6364
def __create_like_notification(self, article_info):
6465
notification_table = self.dynamodb.Table(os.environ['NOTIFICATION_TABLE_NAME'])
66+
notification_id = '-'.join([settings.LIKE_NOTIFICATION_TYPE, article_info['user_id'], article_info['article_id']])
67+
notification = notification_table.get_item(Key={'notification_id': notification_id}).get('Item')
6568

66-
notification_table.put_item(Item={
67-
'user_id': article_info['user_id'],
68-
'article_id': article_info['article_id'],
69-
'article_title': article_info['title'],
70-
'sort_key': TimeUtil.generate_sort_key(),
71-
'type': settings.LIKE_NOTIFICATION_TYPE,
72-
'acted_user_id': self.event['requestContext']['authorizer']['claims']['cognito:username'],
73-
'created_at': int(time.time())
74-
}
75-
)
69+
liked_count = self.__get_article_likes_count()
70+
71+
if notification:
72+
notification_table.update_item(
73+
Key={
74+
'notification_id': notification_id
75+
},
76+
UpdateExpression="set sort_key = :sort_key, article_title = :article_title, liked_count = :liked_count",
77+
ExpressionAttributeValues={
78+
':sort_key': TimeUtil.generate_sort_key(),
79+
':article_title': article_info['title'],
80+
':liked_count': liked_count
81+
}
82+
)
83+
else:
84+
notification_table.put_item(Item={
85+
'notification_id': notification_id,
86+
'user_id': article_info['user_id'],
87+
'article_id': article_info['article_id'],
88+
'article_title': article_info['title'],
89+
'sort_key': TimeUtil.generate_sort_key(),
90+
'type': settings.LIKE_NOTIFICATION_TYPE,
91+
'liked_count': liked_count,
92+
'created_at': int(time.time())
93+
}
94+
)
7695

7796
def __update_unread_notification_manager(self, article_info):
7897
unread_notification_manager_table = self.dynamodb.Table(os.environ['UNREAD_NOTIFICATION_MANAGER_TABLE_NAME'])
@@ -101,3 +120,13 @@ def __create_article_liked_user(self, article_liked_user_table):
101120
def __get_article_user_id(self, article_id):
102121
article_info_table = self.dynamodb.Table(os.environ['ARTICLE_INFO_TABLE_NAME'])
103122
return article_info_table.get_item(Key={'article_id': article_id}).get('Item').get('user_id')
123+
124+
def __get_article_likes_count(self):
125+
query_params = {
126+
'KeyConditionExpression': Key('article_id').eq(self.event['pathParameters']['article_id']),
127+
'Select': 'COUNT'
128+
}
129+
article_liked_user_table = self.dynamodb.Table(os.environ['ARTICLE_LIKED_USER_TABLE_NAME'])
130+
response = article_liked_user_table.query(**query_params)
131+
132+
return response['Count']

src/handlers/me/notifications/index/me_notifications_index.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ def get_schema(self):
1515
'type': 'object',
1616
'properties': {
1717
'limit': settings.parameters['limit'],
18+
'notification_id': settings.parameters['notification_id'],
1819
'sort_key': settings.parameters['sort_key']
1920
}
2021
}
@@ -33,12 +34,14 @@ def exec_main_proc(self):
3334

3435
query_params = {
3536
'Limit': limit,
37+
'IndexName': 'user_id-sort_key-index',
3638
'KeyConditionExpression': Key('user_id').eq(user_id),
3739
'ScanIndexForward': False
3840
}
3941

40-
if self.params.get('sort_key') is not None:
42+
if self.params.get('notification_id') is not None and self.params.get('sort_key') is not None:
4143
LastEvaluatedKey = {
44+
'notification_id': self.params.get('notification_id'),
4245
'user_id': user_id,
4346
'sort_key': int(self.params['sort_key'])
4447
}

tests/handlers/me/articles/like/create/test_me_articles_like_create.py

Lines changed: 92 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,23 @@ def setUp(self):
2121
'sort_key': 1520150272000000
2222
},
2323
{
24-
'article_id': 'testid000001',
25-
'user_id': 'test02',
26-
'sort_key': 1520150272000001
24+
'article_id': 'testid000002',
25+
'user_id': 'test03_01',
26+
'sort_key': 1520150272000002
27+
},
28+
{
29+
'article_id': 'testid000002',
30+
'user_id': 'test03_02',
31+
'sort_key': 1520150272000002
2732
},
2833
{
2934
'article_id': 'testid000002',
30-
'user_id': 'test03',
35+
'user_id': 'test03_03',
36+
'sort_key': 1520150272000002
37+
},
38+
{
39+
'article_id': 'testid000002',
40+
'user_id': 'test03_04',
3141
'sort_key': 1520150272000002
3242
}
3343
]
@@ -38,7 +48,7 @@ def setUp(self):
3848
)
3949

4050
# create article_info_table
41-
article_info_table_items = [
51+
self.article_info_table_items = [
4252
{
4353
'article_id': 'testid000000',
4454
'title': 'title1',
@@ -55,19 +65,36 @@ def setUp(self):
5565
},
5666
{
5767
'article_id': 'testid000002',
58-
'title': 'title3',
59-
'status': 'draft',
60-
'user_id': 'article_user_id_01',
68+
'title': 'title3_updated',
69+
'status': 'public',
70+
'user_id': 'article_user_id_02',
6171
'sort_key': 1520150272000002
6272
}
6373
]
6474
TestsUtil.create_table(
6575
self.dynamodb,
6676
os.environ['ARTICLE_INFO_TABLE_NAME'],
67-
article_info_table_items
77+
self.article_info_table_items
6878
)
6979

70-
TestsUtil.create_table(self.dynamodb, os.environ['NOTIFICATION_TABLE_NAME'], [])
80+
self.notification_items = [
81+
{
82+
'notification_id': 'like-article_user_id_02-testid000002',
83+
'user_id': 'article_user_id_02',
84+
'sort_key': 1520150272000010,
85+
'article_id': 'testid000002',
86+
'article_title': 'title3',
87+
'type': 'like',
88+
'liked_count': 4,
89+
'created_at': 1520150272
90+
}
91+
]
92+
93+
TestsUtil.create_table(
94+
self.dynamodb,
95+
os.environ['NOTIFICATION_TABLE_NAME'],
96+
self.notification_items
97+
)
7198

7299
self.unread_notification_manager_items = [
73100
{
@@ -93,7 +120,7 @@ def assert_bad_request(self, params):
93120
def test_main_ok_exist_article_id(self):
94121
params = {
95122
'pathParameters': {
96-
'article_id': self.article_liked_user_table_items[0]['article_id']
123+
'article_id': self.article_info_table_items[0]['article_id']
97124
},
98125
'requestContext': {
99126
'authorizer': {
@@ -141,11 +168,11 @@ def test_main_ok_exist_article_id(self):
141168
).get('Item')
142169
self.assertEqual(unread_notification_manager['unread'], True)
143170

144-
@patch('time.time', MagicMock(return_value=1520150272.000003))
171+
@patch('time.time', MagicMock(return_value=1520150272.000015))
145172
def test_create_notification_and_unread_notification_manager(self):
146173
params = {
147174
'pathParameters': {
148-
'article_id': self.article_liked_user_table_items[1]['article_id']
175+
'article_id': self.article_info_table_items[1]['article_id']
149176
},
150177
'requestContext': {
151178
'authorizer': {
@@ -168,34 +195,73 @@ def test_create_notification_and_unread_notification_manager(self):
168195
notification_after = notification_table.scan()['Items']
169196
unread_notification_manager_after = unread_notification_manager_table.scan()['Items']
170197

171-
expected_notifications = [
172-
{
173-
'user_id': 'article_user_id_01',
174-
'sort_key': 1520150272000003,
175-
'article_id': 'testid000001',
176-
'article_title': 'title2',
177-
'type': 'like',
178-
'acted_user_id': 'test06',
179-
'created_at': 1520150272
180-
}
181-
]
198+
expected_notification = {
199+
'notification_id': 'like-article_user_id_01-testid000001',
200+
'user_id': 'article_user_id_01',
201+
'sort_key': 1520150272000015,
202+
'article_id': 'testid000001',
203+
'article_title': 'title2',
204+
'type': 'like',
205+
'liked_count': 1,
206+
'created_at': 1520150272
207+
}
182208

209+
notification = notification_table.get_item(Key={'notification_id': 'like-article_user_id_01-testid000001'}).get('Item')
183210
unread_notification_manager = unread_notification_manager_table.get_item(
184211
Key={'user_id': 'article_user_id_01'}
185212
).get('Item')
186213

187214
self.assertEqual(response['statusCode'], 200)
188-
self.assertEqual(notification_after, expected_notifications)
215+
self.assertEqual(notification, expected_notification)
189216
self.assertEqual(len(notification_after), len(notification_before) + 1)
190217
self.assertEqual(unread_notification_manager['unread'], True)
191218
self.assertEqual(len(unread_notification_manager_after), len(unread_notification_manager_before) + 1)
192219

220+
@patch('time.time', MagicMock(return_value=1520150272.000015))
221+
def test_main_with_updating_notification(self):
222+
params = {
223+
'pathParameters': {
224+
'article_id': self.article_info_table_items[2]['article_id']
225+
},
226+
'requestContext': {
227+
'authorizer': {
228+
'claims': {
229+
'cognito:username': 'test06'
230+
}
231+
}
232+
}
233+
}
234+
235+
notification_table = self.dynamodb.Table(os.environ['NOTIFICATION_TABLE_NAME'])
236+
notification_before = notification_table.scan()['Items']
237+
238+
response = MeArticlesLikeCreate(event=params, context={}, dynamodb=self.dynamodb).main()
239+
240+
notification_after = notification_table.scan()['Items']
241+
242+
expected_notification = {
243+
'notification_id': 'like-article_user_id_02-testid000002',
244+
'user_id': 'article_user_id_02',
245+
'sort_key': 1520150272000015,
246+
'article_id': 'testid000002',
247+
'article_title': 'title3_updated',
248+
'type': 'like',
249+
'liked_count': 5,
250+
'created_at': 1520150272
251+
}
252+
253+
notification = notification_table.get_item(Key={'notification_id': 'like-article_user_id_02-testid000002'}).get('Item')
254+
255+
self.assertEqual(response['statusCode'], 200)
256+
self.assertEqual(notification, expected_notification)
257+
self.assertEqual(len(notification_after), len(notification_before))
258+
193259
@patch('me_articles_like_create.MeArticlesLikeCreate._MeArticlesLikeCreate__create_like_notification',
194260
MagicMock(side_effect=Exception()))
195261
def test_raise_exception_in_creating_notification(self):
196262
params = {
197263
'pathParameters': {
198-
'article_id': self.article_liked_user_table_items[0]['article_id']
264+
'article_id': self.article_info_table_items[0]['article_id']
199265
},
200266
'requestContext': {
201267
'authorizer': {

0 commit comments

Comments
 (0)