def test_store_itemtag(self, monkeypatch): monkeypatch.setenv("DBNAME", "Test") os.environ["STAGE"] = "dev" session = get_db_session(True, None) # creating items item = Item() item.content = "RKI bestätigt Covid-19 Sterblichkeitsrate von 0,01 Prozent in (...) - Corona Transition " item.language = "de" item = item_handler.create_item(item, True, session) list_tags = ['RKI', 'Covid', 'Corona Transition'] # store tags event = {"item": item.to_dict(), "Tags": list_tags} context = "" EnrichItem.store_itemtags(event, context, True, session) tag = tag_handler.get_tag_by_content(list_tags[0], True, session) assert tag.tag == list_tags[0] itemtag = tag_handler.get_itemtag_by_tag_and_item_id( tag.id, item.id, True, session) assert itemtag.id is not None event = {"pathParameters": {"item_id": item.id}} ret = GetTags.get_tags_for_item(event, context, True, session) body = ret['body'] # Deserialize if body is string if isinstance(body, str): tags = json.loads(body)['Tags'] else: tags = body['Tags'] assert tags == list_tags
def update_item(event, context, is_test=False, session=None): """stores data related to item Parameters ---------- event: dict, required item Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format context: object, required Lambda Context runtime methods and attributes Context doc: https://docs.aws.amazon.com/lambda/latest/dg/python-context-object.html Returns ------ API Gateway Lambda Proxy Output Format: application/json Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html """ if session is None: session = get_db_session(is_test, session) # Parse event dict to Item object item = Item() json_event = event['item'] for key in json_event: setattr(item, key, json_event[key]) update_object(item, is_test, session)
def get_top_users(n, attr, descending, is_test, session) -> [User]: """ Returns the top "n" users as sorted by "attr" in descending or ascending order as set by "descending". Parameters ---------- n: int, required the number of users to return attr: str, required the column on the users table to sort by descending: bool, required which order to sort the rows by column 'attr' in False = ASC or True =DESC is_test: bool, required is this code being run as part of the tests or in production session: Session??, required a database session Returns ------ users: [User] A list including the top n user objects as ordered by attr, desc """ if session == None: session = get_db_session(is_test, session) sort_column = getattr(User, attr).desc() if descending else getattr( User, attr) users = session.query(User).order_by(sort_column).limit(n).all() return users
def session(fixtures): session = connection_handler.get_db_session(True, None) session.add_all(fixtures) session.commit() return session
def get_review_pairs_by_item(item_id, is_test, session): session = get_db_session(is_test, session) pairs = session.query(ReviewPair).filter( ReviewPair.item_id == item_id).all() return pairs
def test_store_itemurl(self, monkeypatch): monkeypatch.setenv("DBNAME", "Test") from urllib.parse import urlparse session = get_db_session(True, None) str_url = "https://smopo.ch/zehntausende-als-falsche-coronatote-deklariert/" # creating items item = Item() item.content = str_url item = item_handler.create_item(item, True, session) # store a url event = {"item": item.to_dict(), "Claim": {"urls": [str_url]}} context = "" EnrichItem.store_itemurl(event, context, True, session) url = url_handler.get_url_by_content(str_url, True, session) itemurl = url_handler.get_itemurl_by_url_and_item_id( url.id, item.id, True, session) domain = urlparse(str_url).hostname claimant = claimant_handler.get_claimant_by_name(domain, True, session) assert url.url == str_url assert itemurl.id is not None assert claimant.claimant == domain assert url.claimant_id is not None
def delete_user(event, is_test, session): """Deletes a user from the database. Parameters ---------- user_id: str, required The id of the user Returns ------ nothing """ if session is None: session = get_db_session(is_test, session) user_id = helper.cognito_id_from_event(event) user = session.query(User).get(user_id) if (user == None): raise Exception( f"User with id {user_id} could not be found in database.") client = boto3.client('cognito-idp') client.admin_delete_user(UserPoolId=event['requestContext']['identity'] ['cognitoAuthenticationProvider'].split( ',')[0].split('amazonaws.com/')[1], Username=user.name) session.delete(user) session.commit()
def test_get_user(monkeypatch): monkeypatch.setenv("DBNAME", "Test") session = get_db_session(True, None) session = setup_scenarios.create_levels_junior_and_senior_detectives( session) junior_detective1 = user_handler.get_user_by_id("1", True, session) event = event_creator.get_create_review_event(junior_detective1.id, "abc") resp = get_user(event, None, True, session) body = json.loads(resp["body"]) assert body["id"] == junior_detective1.id assert body["level"] == 1 assert body["level_description"] == "Junior" assert body["progress"] == 0 assert body["total_rank"] == session.query(User).count() assert body["level_rank"] == session.query(User).filter( User.level_id == junior_detective1.level_id).count() assert body["solved_cases_total"] == 0 assert body["solved_cases_today"] == 0 assert body["exp_needed"] == 5 sign_up_date = datetime.strptime(body["sign_up_timestamp"], '%Y-%m-%d %H:%M:%S').date() assert sign_up_date != datetime.today()
def store_itemtags(event, context, is_test=False, session=None): """stores tags of an item Parameters ---------- event: dict, required item Tags Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format context: object, required Lambda Context runtime methods and attributes Context doc: https://docs.aws.amazon.com/lambda/latest/dg/python-context-object.html Returns ------ API Gateway Lambda Proxy Output Format: application/json Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html """ if session is None: session = get_db_session(is_test, session) # extract item id item_id = event['item']['id'] # Store all tags of the item for str_tag in event['Tags']: tag_handler.store_tag_for_item(item_id, str_tag, is_test, session)
def reset_locked_items(event, context, is_test=False, session=None): logger = logging.getLogger() logger.setLevel(logging.INFO) helper.log_method_initiated("Reset locked items", event, logger) if session == None: session = get_db_session(False, None) try: reviews_in_progress = review_handler.get_old_reviews_in_progress( is_test, session) review_handler.delete_old_reviews_in_progress(reviews_in_progress, is_test, session) return { "statusCode": 200, 'headers': { "content-type": "application/json; charset=utf-8" }, "body": "{} Review(s) deleted".format(len(reviews_in_progress)) } except Exception: return { "statusCode": 400, "body": "Something went wrong. Check HTTP POST payload. Stacktrace: {}". format(traceback.format_exc()) }
def test_questions_and_answers(monkeypatch): monkeypatch.setenv("DBNAME", "Test") session = get_db_session(True, None) q1 = ReviewQuestion() q1.id = "1" q1.content = "Es ist eine Quelle angegeben." q2 = ReviewQuestion() q2.id = "2" q2.content = "Die Rechtschreibung ist korrekt." o1 = AnswerOption() o1.id = "1" o1.text = "Stimme zu" o1.value = 4 q1.options = [o1] assert len(q1.options) == 1 assert len(o1.questions) == 1 q2.options = [o1] assert len(q1.options) == 1 assert len(o1.questions) == 2 session.add(q1) session.add(q2) session.add(o1) options = session.query(AnswerOption).all() assert len(options) == 1
def test_level_system(monkeypatch): monkeypatch.setenv("DBNAME", "Test") session = get_db_session(True, None) session = setup_scenarios.create_levels_junior_and_senior_detectives( session) junior_detective1 = user_handler.get_user_by_id("1", True, session) assert junior_detective1.level_id == 1 assert junior_detective1.experience_points == 0 user_handler.give_experience_point(junior_detective1.id, True, session) junior_detective1 = user_handler.get_user_by_id(junior_detective1.id, True, session) assert junior_detective1.level_id == 1 assert junior_detective1.experience_points == 1 for _ in range(5): user_handler.give_experience_point(junior_detective1.id, True, session) junior_detective1 = user_handler.get_user_by_id(junior_detective1.id, True, session) assert junior_detective1.level_id == 2 assert junior_detective1.experience_points == 6
def notify_users(is_test, session, item): """Notify user(s) about a closed item. Parameters ---------- is_test: boolean If this method is called from a test session: session The session item: Item The closed item """ if session == None: session = get_db_session(False, None) # TODO: This implementation is not ideal: 1.55 is rounded to 1.5. However, 1.56 is correctly rounded to 1.6. rating = round(item.result_score, 1) rating_text = "nicht vertrauenswürdig" if 2 <= rating < 3: rating_text = "eher nicht vertrauenswürdig" if 3 <= rating < 3.5: rating_text = "eher vertrauenswürdig" if rating >= 3.5: rating_text = "vertrauenswürdig" # get all submissions for the item submissions = submission_handler.get_submissions_by_item_id( item.id, is_test, session) notifications_successful = True for submission in submissions: if submission.telegram_id: try: notify_telegram_user(is_test, submission.telegram_id, item, rating, rating_text) submission.telegram_id = None except Exception: notifications_successful = False if submission.mail: if submission.status == 'confirmed': try: notify_mail_user(submission.mail, item, rating, rating_text) submission.mail = None except Exception: notifications_successful = False if notifications_successful: logger.info( "User(s) notified. Check logs to see if mail and/or telegram notifications were successful." ) update_object(submission, is_test, session) else: logger.exception( "An error occurred during closed item user notification. Please check logs." )
def get_open_items(event, context, is_test=False, session=None): logger = logging.getLogger() logger.setLevel(logging.INFO) helper.log_method_initiated("Get open items for user", event, logger) if session == None: session = connection_handler.get_db_session(False, None) try: # get cognito user id id = helper.cognito_id_from_event(event) # get number of items from url path if ('queryStringParameters' in event and 'num_items' in event['queryStringParameters']): num_items = int(event['queryStringParameters']['num_items']) else: num_items = 5 user = user_handler.get_user_by_id(id, is_test, session) response = item_handler.get_open_items_for_user( user, num_items, is_test, session) items = response['items'] if len(items) < 1: response = { "statusCode": 404, "body": "There are currently no open items for this user." } else: # Transform each item into dict items_dict = [] for item in items: items_dict.append(item.to_dict()) body = { "items": items_dict, "is_open_review": response['is_open_review'] } response = { "statusCode": 200, 'headers': { "content-type": "application/json; charset=utf-8" }, "body": json.dumps(body) } except Exception: response = { "statusCode": 400, "body": "Could not get user and/or num_items. Check URL path parameters. Stacktrace: {}" .format(traceback.format_exc()) } response_cors = helper.set_cors(response, event, is_test) return response_cors
def session2(fixtures, child_question1): session = connection_handler.get_db_session(True, None) session.add_all(fixtures) session.add(child_question1) session.commit() return session
def get_review_pair_from_review(review, is_test, session) -> ReviewPair: session = get_db_session(is_test, session) pair = session.query(ReviewPair).filter( or_(ReviewPair.junior_review_id == review.id, ReviewPair.senior_review_id == review.id)).first() return pair
def set_answer_value(answer_id: str, answer_value: int, is_test, session) -> ReviewAnswer: session = get_db_session(is_test, session) answer = ReviewAnswer() answer = session.get(ReviewAnswer, answer_id) answer.answer = answer_value session.merge(answer) session.commit() return answer
def get_partner_answer(partner_review: Review, question_id, is_test, session) -> ReviewAnswer: session = get_db_session(is_test, session) review_answer = session.query(ReviewAnswer).filter( ReviewAnswer.review_id == partner_review.id, ReviewAnswer.review_question_id == question_id).first() return review_answer
def confirm_submission(submission_id, is_test, session): session = get_db_session(is_test, session) submission = session.query(Submission).filter( Submission.id == submission_id).one() submission.status = 'confirmed' session.merge(submission) session.commit() return submission
def delete_itemtag_by_tag_and_item_id(tag_id, item_id, is_test, session): """Deletes the itemtag for an item and tag """ session = get_db_session(is_test, session) itemtag = session.query(ItemTag).filter( ItemTag.tag_id == tag_id, ItemTag.item_id == item_id).first() if itemtag != None: session.delete(itemtag) session.commit()
def session(item, pair, old_junior_review, new_senior_review): session = get_db_session(True, None) session.add(item) session.add(old_junior_review) session.add(new_senior_review) session.add(pair) session.commit() return session
def get_items(event, context, is_test=False, session=None): """Returns the requested items. Parameters ---------- event: dict, required API Gateway Lambda Proxy Input Format #api-gateway-simple-proxy-for-lambda-input-format Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html context: object, required Lambda Context runtime methods and attributes Context doc: https://docs.aws.amazon.com/lambda/latest/dg/python-context-object.html Returns ------ API Gateway Lambda Proxy Output Format: application/json Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html """ helper.log_method_initiated("Get items", event, logger) if session is None: session = get_db_session(is_test, session) if 'queryStringParameters' in event and event['queryStringParameters'] is not None: params = event['queryStringParameters'] for param in params: if hasattr(Item, param) is False: response = { "statusCode": 400, "body": "Could not get items. Query params do not match item model." } response_cors = helper.set_cors(response, event, is_test) return response_cors else: params = None items = item_handler.get_all_items(is_test, session, params=params) items_list = [] for item in items: items_list.append(item.to_dict()) response = { "statusCode": 200, 'headers': {"content-type": "application/json; charset=utf-8"}, "body": json.dumps(items_list) } response_cors = helper.set_cors(response, event, is_test) return response_cors
def session(item_id): session = get_db_session(True, None) session = setup_scenarios.create_questions(session) session = setup_scenarios.create_levels_junior_and_senior_detectives( session) item = Item(id=item_id, item_type_id="Type1") session.add(item) session.commit() return session
def get_itemtag_by_tag_and_item_id(tag_id, item_id, is_test, session): """Returns the itemtag for an item and tag Returns ------ itemtag: ItemTag Null, if no itemtag was found """ session = get_db_session(is_test, session) itemtag = session.query(ItemTag).filter( ItemTag.tag_id == tag_id, ItemTag.item_id == item_id).first() return itemtag
def get_tag_by_content(content, is_test, session): """Returns an tag with the specified content from the database Returns ------ tag: Tag A tag of an item Null, if no tag was found """ session = get_db_session(is_test, session) tag = session.query(Tag).filter(Tag.tag == content).first() return tag
def get_all_review_questions_db(is_test, session): """Returns all review questions from the database Returns ------ review_questions: ReviewQuestion[] The review questions """ session = get_db_session(is_test, session) review_questions = session.query(ReviewQuestion).all() return review_questions
def test_create_item(): session = get_db_session(True, None) item = Item() item.content = "Testitem" item = item_handler.create_item(item, True, session) assert item.id is not None assert item.open_reviews == 4 assert item.open_reviews_level_1 == 4 assert item.open_reviews_level_2 == 4 assert item.in_progress_reviews_level_1 == 0 assert item.in_progress_reviews_level_2 == 0 assert item.open_timestamp is not None
def session(item_id, review_id, review_question_id, user_id): session = get_db_session(True, None) item = Item() item.id = item_id user = User() user.id = user_id level = Level(id=1) review = Review() review.id = review_id review.item_id = item.id review.user_id = user.id review_question = ReviewQuestion() review_question.id = review_question_id review_question.content = "Question content" review_question.info = "Question info" review_question.hint = "Question hint" o1 = AnswerOption(id="1", text="Option 1", value=0) o2 = AnswerOption(id="2", text="Option 2", value=1, tooltip="Tooltip 2") o3 = AnswerOption(id="3", text="Option 3", value=2) o4 = AnswerOption(id="4", text="Option 4", value=3) o1.questions = [review_question] o2.questions = [review_question] o4.questions = [review_question] o3.questions = [review_question] # all answers use the same review questions in order to keep the test data small reviewanswer1 = generate_review_answer(1, review_id, review_question_id) reviewanswer2 = generate_review_answer(0, review_id, review_question_id) reviewanswer3 = generate_review_answer(1, review_id, review_question_id) reviewanswer4 = generate_review_answer(3, review_id, review_question_id) reviewanswer5 = generate_review_answer(2, review_id, review_question_id) reviewanswer6 = generate_review_answer(1, review_id, review_question_id) reviewanswer7 = generate_review_answer(2, review_id, review_question_id) review.review_answers = [reviewanswer1, reviewanswer2, reviewanswer3, reviewanswer4, reviewanswer5, reviewanswer6, reviewanswer7] session.add(item) session.add(user) session.add(level) session.add(review_question) # refernenced ReviewAnswers are stored as well session.add(review) session.commit() return session
def test_post_tags_for_item_2(self, monkeypatch): monkeypatch.setenv("DBNAME", "Test") os.environ["STAGE"] = "dev" session = get_db_session(True, None) # creating items item = Item() item.content = "https://corona-transition.org/rki-bestatigt-covid-19-sterblichkeitsrate-von-0-01-prozent-in" \ "-deutschland?fbclid=IwAR2vLIkW_3EejFaeC5_wC_410uKhN_WMpWDMAcI-dF9TTsZ43MwaHeSl4n8%22 " item.language = "de" item = item_handler.create_item(item, True, session) event = {"pathParameters": {"item_id": item.id}} context = "" response = GetTags.get_tags_for_item(event, context, True, session) body = response['body'] # Deserialize if body is string if isinstance(body, str): tags = json.loads(body)['Tags'] else: tags = body['Tags'] assert tags == [] json.dumps({"tags": ["RKI", "Covid-19"]}) event = { "pathParameters": { "item_id": item.id }, "body": json.dumps({"tags": ["RKI", "Covid-19"]}) } response = GetTags.post_tags_for_item(event, context, True, session) body = response['body'] # Deserialize if body is string if isinstance(body, str): tags_added = json.loads(body)['added tags'] tags_removed = json.loads(body)['removed tags'] else: tags_added = body['added tags'] tags_removed = body['removed tags'] assert 'RKI' in tags_added assert 'Covid-19' in tags_added assert len(tags_removed) == 0 assert tags_removed == [] response = GetTags.get_tags_for_item(event, context, True, session) body = response['body'] # Deserialize if body is string if isinstance(body, str): tags = json.loads(body)['Tags'] else: tags = body['Tags'] assert tags == ['RKI', 'Covid-19']
def test_get_online_factcheck_by_itemid_2(self, monkeypatch): monkeypatch.setenv("DBNAME", "Test") os.environ["STAGE"] = "dev" session = get_db_session(True, None) # creating items item = Item() item.content = "https://corona-transition.org/rki-bestatigt-covid-19-sterblichkeitsrate-von-0-01-prozent-in" \ "-deutschland?fbclid=IwAR2vLIkW_3EejFaeC5_wC_410uKhN_WMpWDMAcI-dF9TTsZ43MwaHeSl4n8%22 " item.language = "de" item = item_handler.create_item(item, True, session) # store a fact check event = { "item": { "id": item.id, "content": item.content, "language": item.language, }, "KeyPhrases": [ "das Zahlenmaterial", "es", "den letzten 7 Tagen", "das RKI", "sich" ], "Entities": [ "RKI", "0,01 Prozent", "19 Sterblichkeitsrate", "Corona Transition", "Covid" ], "Sentiment": "NEUTRAL" } context = "" EnrichItem.store_itementities(event, context, True, session) EnrichItem.store_itemphrases(event, context, True, session) event = {"pathParameters": {"item_id": item.id}} context = {} s = time.perf_counter() response = get_online_factcheck.get_online_factcheck( event, context, True, session) elapsed = time.perf_counter() - s body = response['body'] # Deserialize if body is string if isinstance(body, str): factcheck = json.loads(body) else: factcheck = body assert factcheck[ 'url'] == 'https://correctiv.org/faktencheck/2020/07/09/nein-rki-bestaetigt-nicht-eine-covid-19-sterblichkeitsrate-von-001-prozent-in-deutschland/' assert factcheck[ 'title'] == 'Falsch. Das Robert-Koch-Institut bestätigte nicht eine Covid-19- Sterblichkeitsrate von 0,01 Prozent in Deutschland.' assert elapsed < 3