diff --git a/api-template.yaml b/api-template.yaml index 48490daf..e74df376 100644 --- a/api-template.yaml +++ b/api-template.yaml @@ -214,6 +214,17 @@ Resources: type: string created_at: type: integer + MeArticlesFraudCreate: + type: object + properties: + reason: + type: string + plagiarism_url: + type: string + plagiarism_description: + type: string + illegal_content: + type: string paths: /articles/recent: get: @@ -813,6 +824,11 @@ Resources: description: '対象記事の指定するために使用' required: true type: 'string' + - name: 'FraudContents' + in: 'body' + description: '違反報告の内容' + schema: + $ref: '#/definitions/MeArticlesFraudCreate' responses: '200': description: '不正報告の実施成功' diff --git a/src/common/settings.py b/src/common/settings.py index 8061204d..ccce2741 100644 --- a/src/common/settings.py +++ b/src/common/settings.py @@ -85,6 +85,25 @@ 'minLength': 12, 'maxLength': 12 } + }, + 'fraud_user': { + 'reason': { + 'type': 'string', + }, + 'plagiarism_url': { + 'type': 'string', + 'format': 'uri', + 'maxLength': 2048 + }, + 'plagiarism_description': { + 'type': 'string', + 'maxLength': 65535 + }, + 'illegal_content': { + 'type': 'string', + 'maxLength': 65535 + }, + } } @@ -136,7 +155,6 @@ 'xml', 'year' ] - LIKED_RETRY_COUNT = 3 ARTICLE_IMAGE_MAX_WIDTH = 3840 @@ -150,3 +168,16 @@ LIKE_NOTIFICATION_TYPE = 'like' COMMENT_NOTIFICATION_TYPE = 'comment' + +FRAUD_REASONS = [ + 'violence', + 'spam', + 'plagiarism', + 'slander', + 'illegal', + 'other' +] + +FRAUD_NEED_ORIGINAL_REASONS = ['plagiarism'] + +FRAUD_NEED_DETAIL_REASONS = ['illegal', 'other'] diff --git a/src/handlers/me/articles/fraud/create/me_articles_fraud_create.py b/src/handlers/me/articles/fraud/create/me_articles_fraud_create.py index 33e1472c..eb618a75 100644 --- a/src/handlers/me/articles/fraud/create/me_articles_fraud_create.py +++ b/src/handlers/me/articles/fraud/create/me_articles_fraud_create.py @@ -14,8 +14,19 @@ def get_schema(self): return { 'type': 'object', 'properties': { - 'article_id': settings.parameters['article_id'] + 'article_id': settings.parameters['article_id'], + 'reason': settings.parameters['fraud_user']['reason'], + 'plagiarism_url': settings.parameters['fraud_user']['plagiarism_url'], + 'plagiarism_description': settings.parameters['fraud_user']['plagiarism_description'], + 'illegal_content': settings.parameters['fraud_user']['illegal_content'] }, + 'anyOf': [ + { + 'properties': { + 'reason': {'enum': settings.FRAUD_REASONS} + } + } + ], 'required': ['article_id'] } @@ -23,11 +34,12 @@ def validate_params(self): # single if self.event.get('pathParameters') is None: raise ValidationError('pathParameters is required') - validate(self.event.get('pathParameters'), self.get_schema()) + validate(self.params, self.get_schema()) + self.__validate_reason_dependencies(self.params) # relation DBUtil.validate_article_existence( self.dynamodb, - self.event['pathParameters']['article_id'], + self.params['article_id'], status='public' ) @@ -52,9 +64,26 @@ def __create_article_fraud_user(self, article_fraud_user_table): article_fraud_user = { 'article_id': self.event['pathParameters']['article_id'], 'user_id': self.event['requestContext']['authorizer']['claims']['cognito:username'], + 'reason': self.params.get('reason'), + 'plagiarism_url': self.params.get('plagiarism_url'), + 'plagiarism_description': self.params.get('plagiarism_description'), + 'illegal_content': self.params.get('illegal_content'), 'created_at': int(time.time()) } article_fraud_user_table.put_item( Item=article_fraud_user, ConditionExpression='attribute_not_exists(article_id)' ) + + def __validate_reason_dependencies(self, params): + reason = params.get('reason', '') + if reason in settings.FRAUD_NEED_ORIGINAL_REASONS: + self.__validate_dependencies(params, ['plagiarism_url', 'plagiarism_description']) + + if reason in settings.FRAUD_NEED_DETAIL_REASONS: + self.__validate_dependencies(params, ['illegal_content']) + + def __validate_dependencies(self, params, required_items): + for item in required_items: + if not params[item]: + raise ValidationError("%s is required" % item) diff --git a/tests/handlers/me/articles/fraud/create/test_me_articles_fraud_create.py b/tests/handlers/me/articles/fraud/create/test_me_articles_fraud_create.py index 75c8e00d..45cbddec 100644 --- a/tests/handlers/me/articles/fraud/create/test_me_articles_fraud_create.py +++ b/tests/handlers/me/articles/fraud/create/test_me_articles_fraud_create.py @@ -1,4 +1,5 @@ import os +import json from tests_util import TestsUtil from unittest import TestCase from me_articles_fraud_create import MeArticlesFraudCreate @@ -78,6 +79,12 @@ def test_main_ok_exist_article_id(self): 'pathParameters': { 'article_id': self.article_fraud_user_table_items[0]['article_id'] }, + 'body': json.dumps({ + 'reason': 'plagiarism', + 'plagiarism_url': 'http://test.com', + 'plagiarism_description': 'plagiarism description', + 'illegal_content': 'illegal content' + }), 'requestContext': { 'authorizer': { 'claims': { @@ -97,18 +104,35 @@ def test_main_ok_exist_article_id(self): target_article_id = params['pathParameters']['article_id'] target_user_id = params['requestContext']['authorizer']['claims']['cognito:username'] + body = json.loads(params['body']) + target_reason = body['reason'] + target_plagiarism_url = body['plagiarism_url'] + target_plagiarism_description = body['plagiarism_description'] + target_illegal_content = body['illegal_content'] article_fraud_user = self.get_article_fraud_user(target_article_id, target_user_id) expected_items = { 'article_id': target_article_id, 'user_id': target_user_id, + 'reason': target_reason, + 'plagiarism_url': target_plagiarism_url, + 'plagiarism_description': target_plagiarism_description, + 'illegal_content': target_illegal_content, 'created_at': 1520150272000003 } self.assertEqual(response['statusCode'], 200) self.assertEqual(len(article_fraud_user_after), len(article_fraud_user_before) + 1) - article_fraud_user_param_names = ['article_id', 'user_id', 'created_at'] + article_fraud_user_param_names = [ + 'article_id', + 'user_id', + 'reason', + 'plagiarism_url', + 'plagiarism_description', + 'illegal_content', + 'created_at' + ] for key in article_fraud_user_param_names: self.assertEqual(expected_items[key], article_fraud_user[key]) @@ -177,6 +201,68 @@ def test_validation_article_id_min(self): self.assert_bad_request(params) + def test_validation_invalid_reason(self): + params = { + 'body': json.dumps({'reason': 'abcde'}) + } + self.assert_bad_request(params) + + def test_validation_required_plagiarism_url_when_reason_is_plagiarism(self): + params = { + 'body': json.dumps( + { + 'reason': 'plagiarism', + 'plagiarism_url': '', + } + ) + } + self.assert_bad_request(params) + + def test_validation_required_plagiarism_description_when_reason_is_plagiarism(self): + params = { + 'body': json.dumps( + { + 'reason': 'plagiarism', + 'plagiarism_url': 'http://test.com', + 'plagiarism_description': '', + } + ) + } + self.assert_bad_request(params) + + def test_validation_invalid_plagiarism_url_when_reason_is_plagiarism(self): + params = { + 'body': json.dumps( + { + 'reason': 'plagiarism', + 'plagiarism_url': 'aaa' + } + ) + } + self.assert_bad_request(params) + + def test_validation_required_illegal_content_when_reason_is_illegal(self): + params = { + 'body': json.dumps( + { + 'reason': 'illegal', + 'illegal_content': '', + } + ) + } + self.assert_bad_request(params) + + def test_validation_required_illegal_content_when_reason_is_other(self): + params = { + 'body': json.dumps( + { + 'reason': 'other', + 'illegal_content': '', + } + ) + } + self.assert_bad_request(params) + def get_article_fraud_user(self, article_id, user_id): query_params = { 'KeyConditionExpression': Key('article_id').eq(article_id) & Key('user_id').eq(user_id)