def create_task(task_info: dict, do_commit: bool = True): """Create a new task record.""" current_app.logger.debug('<create_task ') task_model = TaskModel(**camelback2snake(task_info)) task_model.flush() if do_commit: # Task mostly comes as a part of parent transaction.So do not commit unless asked. db.session.commit() current_app.logger.debug('>create_task ') return Task(task_model)
def _modify_task(user): """Clone on-hold task to a new active task; handle user-based and org-based tasks.""" # find users org. ideally only one org org_list = MembershipModel.find_orgs_for_user(user.identifier) org: OrgModel = next(iter(org_list or []), None) if org: # check if there is any holding tasks # Find if the corresponding task is NEW_ACCOUNT_STAFF_REVIEW / GOVN type, clone and close it task_model: TaskModel = TaskModel.find_by_task_for_account( org.id, TaskStatus.HOLD.value) if task_model is None: # Else, find if there are any associated task of BCEID_ADMIN type, clone and close it task_model: TaskModel = TaskModel.find_by_user_and_status( org.id, TaskStatus.HOLD.value) if task_model: task_info = { 'name': org.name, 'relationshipId': task_model.relationship_id, 'relatedTo': user.identifier, 'dateSubmitted': task_model.date_submitted, 'relationshipType': task_model.relationship_type, 'type': task_model.type, 'action': task_model.action, 'status': TaskStatus.OPEN.value, 'relationship_status': TaskRelationshipStatus.PENDING_STAFF_REVIEW.value, 'account_id': task_model.account_id } new_task = TaskService.create_task(task_info=task_info, do_commit=False) # Send notification mail to staff review task from auth_api.services import Org as OrgService # pylint:disable=cyclic-import, import-outside-toplevel if task_model.relationship_type == TaskRelationshipType.USER.value: OrgService.send_staff_review_account_reminder( relationship_id=user.identifier, task_relationship_type=TaskRelationshipType.USER.value) else: OrgService.send_staff_review_account_reminder( relationship_id=org.id) remarks = [ f'User Uploaded New affidavit .Created New task id: {new_task.identifier}' ] TaskService.close_task(task_model.id, remarks)
def factory_task_models(count: int, user_id: int): """Produce a collection of Task models.""" task_type = TaskTypePrefix.NEW_ACCOUNT_STAFF_REVIEW.value for i in range(0, count): task = TaskModel(name='TEST {}'.format(i), date_submitted=datetime.datetime.now(), relationship_type=TaskRelationshipType.ORG.value, relationship_id=10, type=task_type, status=TaskStatus.OPEN.value, related_to=user_id, relationship_status=TaskRelationshipStatus. PENDING_STAFF_REVIEW.value) task.save()
def factory_task_model(user_id: int = 1, org_id: int = 1): """Produce a Task model.""" task_type = TaskTypePrefix.NEW_ACCOUNT_STAFF_REVIEW.value task = TaskModel( id=1, name='foo', date_submitted=datetime.datetime.now(), relationship_type=TaskRelationshipType.ORG.value, relationship_id=org_id, type=task_type, status=TaskStatus.OPEN.value, related_to=user_id, relationship_status=TaskRelationshipStatus.PENDING_STAFF_REVIEW.value) task.save() return task
def test_update_task(session, keycloak_mock, monkeypatch): # pylint:disable=unused-argument """Assert that a task can be updated.""" user_with_token = TestUserInfo.user_bceid_tester user_with_token['keycloak_guid'] = TestJwtClaims.public_bceid_user['sub'] user = factory_user_model_with_contact(user_with_token) patch_token_info(TestJwtClaims.public_bceid_user, monkeypatch) affidavit_info = TestAffidavit.get_test_affidavit_with_contact() AffidavitService.create_affidavit(affidavit_info=affidavit_info) org = OrgService.create_org(TestOrgInfo.org_with_mailing_address(), user_id=user.id) org_dict = org.as_dict() assert org_dict['org_status'] == OrgStatus.PENDING_STAFF_REVIEW.value token_info = TestJwtClaims.get_test_user(sub=user.keycloak_guid, source=LoginSource.STAFF.value) patch_token_info(token_info, monkeypatch) tasks = TaskService.fetch_tasks(task_status=[TaskStatus.OPEN.value], page=1, limit=10) fetched_tasks = tasks['tasks'] fetched_task = fetched_tasks[0] task_info = {'relationshipStatus': TaskRelationshipStatus.ACTIVE.value} task: TaskModel = TaskModel.find_by_task_id(fetched_task['id']) task = TaskService.update_task(TaskService(task), task_info=task_info) dictionary = task.as_dict() user = UserModel.find_by_id(user.id) assert dictionary['status'] == TaskStatus.COMPLETED.value assert dictionary[ 'relationship_status'] == TaskRelationshipStatus.ACTIVE.value assert user.verified
def test_fetch_tasks(session): # pylint:disable=unused-argument """Assert that we can fetch all tasks.""" user = factory_user_model() task_type = TaskTypePrefix.NEW_ACCOUNT_STAFF_REVIEW.value task = TaskModel( name='TEST', date_submitted=datetime.now(), relationship_type=TaskRelationshipType.ORG.value, relationship_id=10, type=task_type, due_date=datetime.now(), status=TaskStatus.OPEN.value, related_to=user.id, relationship_status=TaskRelationshipStatus.PENDING_STAFF_REVIEW.value) session.add(task) session.commit() found_tasks, count = TaskModel.fetch_tasks( task_relationship_status=TaskRelationshipStatus.PENDING_STAFF_REVIEW. value, task_type=task_type, task_status=TaskStatus.OPEN.value, page=1, limit=10) assert found_tasks assert count == 1 for found_staff_task in found_tasks: assert found_staff_task.name == task.name
def fetch_tasks(**kwargs): """Search all tasks.""" task_type = kwargs.get('task_type') task_status = kwargs.get('task_status') or [TaskStatus.OPEN.value] task_relationship_status = kwargs.get('task_relationship_status') tasks = {'tasks': []} page: int = int(kwargs.get('page')) limit: int = int(kwargs.get('limit')) search_args = (task_type, task_status, task_relationship_status, page, limit) current_app.logger.debug('<fetch_tasks ') task_models, count = TaskModel.fetch_tasks(*search_args) # pylint: disable=unused-variable if not task_models: return tasks for task in task_models: task_dict = Task(task).as_dict(exclude=['user']) tasks['tasks'].append(task_dict) tasks['total'] = count tasks['page'] = page tasks['limit'] = limit current_app.logger.debug('>fetch_tasks ') return tasks
def test_create_org_by_verified_bceid_user(session, keycloak_mock, monkeypatch): # pylint:disable=unused-argument """Assert that an Org can be created.""" # Steps # 1. Create a pending affidavit # 2. Create org # 3. Approve Org, which will mark the affidavit as approved # 4. Same user create new org, which should be ACTIVE. user = factory_user_model_with_contact(user_info=TestUserInfo.user_bceid_tester) token_info = TestJwtClaims.get_test_user(sub=user.keycloak_guid, source=LoginSource.BCEID.value) patch_token_info(token_info, monkeypatch) affidavit_info = TestAffidavit.get_test_affidavit_with_contact() AffidavitService.create_affidavit(affidavit_info=affidavit_info) org = OrgService.create_org(TestOrgInfo.org_with_mailing_address(), user_id=user.id) org_dict = org.as_dict() assert org_dict['org_status'] == OrgStatus.PENDING_STAFF_REVIEW.value task_model = TaskModel.find_by_task_for_account(org_dict['id'], status=TaskStatus.OPEN.value) assert task_model.relationship_id == org_dict['id'] assert task_model.action == TaskAction.AFFIDAVIT_REVIEW.value task_info = { 'status': TaskStatus.OPEN.value, 'relationshipStatus': TaskRelationshipStatus.ACTIVE.value, } TaskService.update_task(TaskService(task_model), task_info) org_result: OrgModel = OrgModel.find_by_org_id(org_dict['id']) assert org_result.status_code == OrgStatus.ACTIVE.value
def send_staff_review_account_reminder( relationship_id, task_relationship_type=TaskRelationshipType.ORG.value): """Send staff review account reminder notification.""" current_app.logger.debug('<send_staff_review_account_reminder') user: UserModel = UserModel.find_by_jwt_token() recipient = current_app.config.get('STAFF_ADMIN_EMAIL') # Get task id that is related with the task. Task Relationship Type can be ORG, PRODUCT etc. task = TaskModel.find_by_task_relationship_id( task_relationship_type=task_relationship_type, relationship_id=relationship_id) context_path = f'review-account/{task.id}' app_url = f"{g.get('origin_url', '')}/{current_app.config.get('AUTH_WEB_TOKEN_CONFIRM_PATH')}" review_url = f'{app_url}/{context_path}' first_name = user.firstname last_name = user.lastname data = { 'emailAddresses': recipient, 'contextUrl': review_url, 'userFirstName': first_name, 'userLastName': last_name } try: publish_to_mailer('staffReviewAccount', org_id=relationship_id, data=data) current_app.logger.debug('<send_staff_review_account_reminder') except Exception as e: # noqa=B901 current_app.logger.error( '<send_staff_review_account_reminder failed') raise BusinessException(Error.FAILED_NOTIFICATION, None) from e
def put(task_id): """Update a task.""" request_json = request.get_json() token = g.jwt_oidc_token_info valid_format, errors = schema_utils.validate(request_json, 'task_request') if not valid_format: return {'message': schema_utils.serialize(errors)}, http_status.HTTP_400_BAD_REQUEST try: task = TaskService(TaskModel.find_by_task_id(task_id)) if task: # Update task and its relationships origin = request.environ.get('HTTP_ORIGIN', 'localhost') response, status = task.update_task(task_info=request_json, token_info=token, origin_url=origin).as_dict(), http_status.HTTP_200_OK else: response, status = {'message': 'The requested task could not be found.'}, \ http_status.HTTP_404_NOT_FOUND except BusinessException as exception: response, status = {'code': exception.code, 'message': exception.message}, exception.status_code return response, status
def test_approve_org(session, keycloak_mock, monkeypatch): # pylint:disable=unused-argument """Assert that an Affidavit can be approved.""" user = factory_user_model_with_contact( user_info=TestUserInfo.user_bceid_tester) token_info = TestJwtClaims.get_test_user(sub=user.keycloak_guid, source=LoginSource.BCEID.value) patch_token_info(token_info, monkeypatch) affidavit_info = TestAffidavit.get_test_affidavit_with_contact() AffidavitService.create_affidavit(affidavit_info=affidavit_info) org = OrgService.create_org(TestOrgInfo.org_with_mailing_address(), user_id=user.id) org_dict = org.as_dict() assert org_dict['org_status'] == OrgStatus.PENDING_STAFF_REVIEW.value task_model = TaskModel.find_by_task_for_account( org_dict['id'], status=TaskStatus.OPEN.value) assert task_model.relationship_id == org_dict['id'] assert task_model.action == TaskAction.AFFIDAVIT_REVIEW.value task_info = { 'status': TaskStatus.OPEN.value, 'relationshipStatus': TaskRelationshipStatus.ACTIVE.value, 'remarks': ['Test Remark'] } task = TaskService.update_task(TaskService(task_model), task_info) task_dict = task.as_dict() affidavit = AffidavitService.find_affidavit_by_org_id( task_dict['relationship_id']) assert affidavit['status'] == AffidavitStatus.APPROVED.value
def get(task_id): """Fetch task by id.""" try: task = TaskService(TaskModel.find_by_task_id(task_id=task_id)) response, status = task.as_dict(), http_status.HTTP_200_OK except BusinessException as exception: response, status = {'code': exception.code, 'message': exception.message}, exception.status_code return response, status
def close_task(task_id, remarks: [] = None, do_commit: bool = True): """Close a task.""" current_app.logger.debug('<close_task ') task_model: TaskModel = TaskModel.find_by_id(task_id) task_model.status = TaskStatus.CLOSED.value task_model.remarks = remarks task_model.flush() if do_commit: db.session.commit()
def test_finding_task_by_relationship_id(session): # pylint:disable=unused-argument """Assert that we can fetch all tasks.""" user = factory_user_model() task = TaskModel( name='TEST 1', date_submitted=datetime.now(), relationship_type=TaskRelationshipType.ORG.value, relationship_id=10, type=TaskTypePrefix.NEW_ACCOUNT_STAFF_REVIEW.value, status=TaskStatus.OPEN.value, related_to=user.id, relationship_status=TaskRelationshipStatus.PENDING_STAFF_REVIEW.value) task.save() found_task = TaskModel.find_by_task_relationship_id( task_relationship_type=TaskRelationshipType.ORG.value, relationship_id=10) assert found_task assert found_task.name == 'TEST 1' assert found_task.relationship_id == 10 assert found_task.status == TaskStatus.OPEN.value
def test_find_by_task_for_user(session): # pylint:disable=unused-argument """Assert that we can fetch all tasks.""" user = factory_user_model() task = TaskModel( name='TEST 1', date_submitted=datetime.now(), relationship_type=TaskRelationshipType.USER.value, relationship_id=user.id, type=TaskTypePrefix.BCEID_ADMIN.value, status=TaskStatus.OPEN.value, related_to=user.id, account_id=10, relationship_status=TaskRelationshipStatus.PENDING_STAFF_REVIEW.value) task.save() found_task = TaskModel.find_by_user_and_status( org_id=10, status=TaskStatus.OPEN.value) assert found_task assert found_task.name == 'TEST 1' assert found_task.relationship_id == user.id assert found_task.status == TaskStatus.OPEN.value
def test_task_creation(session, keycloak_mock, monkeypatch): # pylint:disable=unused-argument """Assert that affidavit reupload creates new task.""" user = factory_user_model_with_contact() token_info = TestJwtClaims.get_test_user(sub=user.keycloak_guid, source=LoginSource.BCEID.value) patch_token_info(token_info, monkeypatch) affidavit_info = TestAffidavit.get_test_affidavit_with_contact() AffidavitService.create_affidavit(affidavit_info=affidavit_info) org = OrgService.create_org(TestOrgInfo.org_with_mailing_address(), user_id=user.id) org_id = org.as_dict().get('id') task_model: TaskModel = TaskModel.find_by_task_for_account( org_id, TaskStatus.OPEN.value) assert task_model is not None, 'New Open should be generated' task_model.status = TaskStatus.HOLD.value # set current task to hold.Its a staff action new_affidavit_info = TestAffidavit.get_test_affidavit_with_contact() AffidavitService.create_affidavit(affidavit_info=new_affidavit_info) assert TaskModel.find_by_id( task_model.id).status == TaskStatus.CLOSED.value assert TaskModel.find_by_task_for_account( org_id, TaskStatus.OPEN.value) is not None
def test_fetch_tasks_pagination(session): # pylint:disable=unused-argument """Assert that we can fetch all tasks.""" user = factory_user_model() factory_task_models(6, user.id) task_type = TaskTypePrefix.NEW_ACCOUNT_STAFF_REVIEW.value found_tasks, count = TaskModel.fetch_tasks( task_relationship_status=TaskRelationshipStatus.PENDING_STAFF_REVIEW. value, task_type=task_type, task_status=TaskStatus.OPEN.value, page=3, limit=2) assert found_tasks assert count == 6
def test_find_task_by_id(session): # pylint:disable=unused-argument """Assert that we can fetch all tasks.""" user = factory_user_model() task_type = TaskTypePrefix.NEW_ACCOUNT_STAFF_REVIEW.value task = TaskModel(name='TEST', date_submitted=datetime.now(), relationship_type=TaskRelationshipType.ORG.value, relationship_id=10, type=task_type, due_date=datetime.now(), status=TaskStatus.OPEN.value, related_to=user.id) session.add(task) session.commit() found_task = TaskModel.find_by_task_id(task.id) assert found_task assert found_task.name == task.name
def _modify_task(user): # find users org. ideally only one org org_list = MembershipModel.find_orgs_for_user(user.identifier) org: OrgModel = next(iter(org_list or []), None) if org: # check if there is any holding tasks task_model: TaskModel = TaskModel.find_by_task_for_account( org.id, TaskStatus.HOLD.value) if task_model: task_type = TaskTypePrefix.NEW_ACCOUNT_STAFF_REVIEW.value task_info = { 'name': org.name, 'relationshipId': org.id, 'relatedTo': user.identifier, 'dateSubmitted': task_model.date_submitted, 'relationshipType': TaskRelationshipType.ORG.value, 'type': task_type, 'status': TaskStatus.OPEN.value, 'relationship_status': TaskRelationshipStatus.PENDING_STAFF_REVIEW.value } new_task = TaskService.create_task(task_info=task_info, do_commit=False) # Send notification mail to staff review task from auth_api.services import Org as OrgService # pylint:disable=cyclic-import, import-outside-toplevel OrgService.send_staff_review_account_reminder( relationship_id=org.id) remark = f'User Uploaded New affidavit .Created New task id: {new_task.identifier}' TaskService.close_task(task_model.id, remark)
def test_fetch_pending_tasks_descending(session): # pylint:disable=unused-argument """Assert that we can fetch all tasks.""" user = factory_user_model() task = TaskModel( name='TEST 1', date_submitted=datetime.now(), relationship_type=TaskRelationshipType.ORG.value, relationship_id=10, type=TaskTypePrefix.NEW_ACCOUNT_STAFF_REVIEW.value, status=TaskStatus.OPEN.value, related_to=user.id, relationship_status=TaskRelationshipStatus.PENDING_STAFF_REVIEW.value) task.save() task = TaskModel( name='TEST 2', date_submitted=datetime(2021, 5, 25), relationship_type=TaskRelationshipType.ORG.value, relationship_id=10, type=TaskTypePrefix.NEW_ACCOUNT_STAFF_REVIEW.value, status=TaskStatus.OPEN.value, related_to=user.id, relationship_status=TaskRelationshipStatus.PENDING_STAFF_REVIEW.value) task.save() task_type = TaskTypePrefix.NEW_ACCOUNT_STAFF_REVIEW.value found_tasks, count = TaskModel.fetch_tasks( task_relationship_status=TaskRelationshipStatus.PENDING_STAFF_REVIEW. value, task_type=task_type, task_status=TaskStatus.OPEN.value, page=1, limit=2) assert found_tasks assert found_tasks[0].name == 'TEST 2' assert found_tasks[1].name == 'TEST 1' assert count == 2