def test_unlock_tasks_for_validation_raises_error_if_user_doesnt_own_the_lock( self, mock_task): mock_task.return_value = self.unlock_task_stub validated_task = ValidatedTask() validated_task.task_id = 1 validated_tasks = [validated_task] unlock_dto = UnlockAfterValidationDTO() unlock_dto.project_id = 1 unlock_dto.validated_tasks = validated_tasks unlock_dto.user_id = 12 # Act / Assert with self.assertRaises(ValidatorServiceError): ValidatorService.unlock_tasks_after_validation(unlock_dto)
def test_unlock_tasks_for_validation_raises_error_if_task_not_found( self, mock_task): # Arrange mock_task.return_value = None validated_task = ValidatedTask() validated_task.task_id = 1 validated_tasks = [validated_task] unlock_dto = UnlockAfterValidationDTO() unlock_dto.project_id = 1 unlock_dto.validated_tasks = validated_tasks # Act / Assert with self.assertRaises(NotFound): ValidatorService.unlock_tasks_after_validation(unlock_dto)
def test_lock_tasks_raises_error_if_project_validator_only_and_user_not_validator( self, mock_project, mock_task, mock_user): # Arrange task_stub = Task() task_stub.task_status = TaskStatus.MAPPED.value mock_task.return_value = task_stub mock_project.return_value = False, ValidatingNotAllowed.USER_NOT_VALIDATOR mock_user.return_value = True lock_dto = LockForValidationDTO() lock_dto.project_id = 1 lock_dto.task_ids = [1, 2] lock_dto.user_id = 1234 with self.assertRaises(ValidatorServiceError): ValidatorService.lock_tasks_for_validation(lock_dto)
def get(self, project_id): """ Get all mapped tasks for a project grouped by username --- tags: - tasks produces: - application/json parameters: - name: project_id in: path description: Unique project ID required: true type: integer default: 1 responses: 200: description: Mapped tasks returned 500: description: Internal Server Error """ try: mapped_tasks = ValidatorService.get_mapped_tasks_by_user( project_id) return mapped_tasks.to_primitive(), 200 except Exception as e: error_msg = f"Task Lock API - unhandled error: {str(e)}" current_app.logger.critical(error_msg) return {"Error": "Unable to fetch mapped tasks"}, 500
def post(self, project_id): """ Invalidate all mapped tasks on a project --- tags: - tasks produces: - application/json parameters: - in: header name: Authorization description: Base64 encoded session token required: true type: string default: Token sessionTokenHere== - name: project_id in: path description: Unique project ID required: true type: integer default: 1 responses: 200: description: All mapped tasks invalidated 401: description: Unauthorized - Invalid credentials 403: description: Forbidden 500: description: Internal Server Error """ try: authenticated_user_id = token_auth.current_user() ProjectAdminService.is_user_action_permitted_on_project( authenticated_user_id, project_id) except ValueError as e: error_msg = f"TasksActionsInvalidateAllAPI POST: {str(e)}" return {"Error": error_msg}, 403 try: ValidatorService.invalidate_all_tasks(project_id, authenticated_user_id) return {"Success": "All tasks invalidated"}, 200 except Exception as e: error_msg = f"TasksActionsInvalidateAllAPI POST - unhandled error: {str(e)}" current_app.logger.critical(error_msg) return {"Error": "Unable to invalidate all tasks"}, 500
def test_unlock_tasks_for_validation_raises_error_if_task_not_locked( self, mock_task): # Arrange self.unlock_task_stub.task_locked = False mock_task.return_value = self.unlock_task_stub validated_task = ValidatedTask() validated_task.task_id = 1 validated_tasks = [validated_task] unlock_dto = UnlockAfterValidationDTO() unlock_dto.project_id = 1 unlock_dto.validated_tasks = validated_tasks # Act / Assert with self.assertRaises(ValidatorServiceError): ValidatorService.unlock_tasks_after_validation(unlock_dto)
def test_lock_tasks_raises_error_if_user_has_not_accepted_license( self, mock_project, mock_task, mock_user): # Arrange task_stub = Task() task_stub.task_status = TaskStatus.MAPPED.value mock_task.return_value = task_stub mock_project.return_value = ( False, ValidatingNotAllowed.USER_NOT_ACCEPTED_LICENSE, ) mock_user.return_value = True lock_dto = LockForValidationDTO() lock_dto.project_id = 1 lock_dto.task_ids = [1, 2] lock_dto.user_id = 123 lock_dto.mapped_by = 1234 with self.assertRaises(UserLicenseError): ValidatorService.lock_tasks_for_validation(lock_dto)
def test_user_can_validate_task_returns_true_when_user_not_a_pm_and_not_validating_own_task( self, mock_user): # Arrange mock_user.return_value = False user_id = 5678 mapped_by = 1234 # act user_can_validate_task = ValidatorService._user_can_validate_task( user_id, mapped_by) # assert self.assertTrue(user_can_validate_task)
def post(self, project_id): """ Set tasks as validated --- tags: - tasks produces: - application/json parameters: - in: header name: Authorization description: Base64 encoded session token required: true type: string default: Token sessionTokenHere== - in: header name: Accept-Language description: Language user is requesting type: string required: true default: en - name: project_id in: path description: Project ID the task is associated with required: true type: integer default: 1 - in: body name: body required: true description: JSON object for unlocking a task schema: properties: validatedTasks: type: array items: schema: $ref: "#/definitions/ValidatedTask" responses: 200: description: Task unlocked 400: description: Client Error 401: description: Unauthorized - Invalid credentials 403: description: Forbidden 404: description: Task not found 500: description: Internal Server Error """ try: validated_dto = UnlockAfterValidationDTO(request.get_json()) validated_dto.project_id = project_id validated_dto.user_id = token_auth.current_user() validated_dto.preferred_locale = request.environ.get( "HTTP_ACCEPT_LANGUAGE") validated_dto.validate() except DataError as e: current_app.logger.error(f"Error validating request: {str(e)}") return {"Error": "Task unlock failed"}, 400 try: tasks = ValidatorService.unlock_tasks_after_validation( validated_dto) return tasks.to_primitive(), 200 except ValidatorServiceError: return {"Error": "Task unlock failed"}, 403 except NotFound: return {"Error": "Task unlock failed"}, 404 except Exception as e: error_msg = f"Validator Lock API - unhandled error: {str(e)}" current_app.logger.critical(error_msg) return {"Error": "Task unlock failed"}, 500
def post(self, project_id): """ Lock tasks for validation --- tags: - tasks produces: - application/json parameters: - in: header name: Authorization description: Base64 encoded session token required: true type: string default: Token sessionTokenHere== - in: header name: Accept-Language description: Language user is requesting type: string required: true default: en - name: project_id in: path description: Project ID the tasks are associated with required: true type: integer default: 1 - in: body name: body required: true description: JSON object for locking task(s) schema: properties: taskIds: type: array items: type: integer description: Array of taskIds for locking default: [1,2] responses: 200: description: Task(s) locked for validation 400: description: Client Error 401: description: Unauthorized - Invalid credentials 403: description: Forbidden 404: description: Task not found 409: description: User has not accepted license terms of project 500: description: Internal Server Error """ try: validator_dto = LockForValidationDTO(request.get_json()) validator_dto.project_id = project_id validator_dto.user_id = token_auth.current_user() validator_dto.preferred_locale = request.environ.get( "HTTP_ACCEPT_LANGUAGE") validator_dto.validate() except DataError as e: current_app.logger.error(f"Error validating request: {str(e)}") return {"Error": "Unable to lock task"}, 400 try: tasks = ValidatorService.lock_tasks_for_validation(validator_dto) return tasks.to_primitive(), 200 except ValidatorServiceError as e: error_msg = f"Validator Lock API - {str(e)}" return {"Error": error_msg}, 403 except NotFound: return {"Error": "Task not found"}, 404 except UserLicenseError: return {"Error": "User not accepted license terms"}, 409 except Exception as e: error_msg = f"Validator Lock API - unhandled error: {str(e)}" current_app.logger.critical(error_msg) return {"Error": "Unable to lock task"}, 500
def get(self, username): """ Get invalidated tasks either mapped by user or invalidated by user --- tags: - tasks produces: - application/json parameters: - in: header name: Authorization description: Base64 encoded session token required: true type: string default: Token sessionTokenHere== - in: header name: Accept-Language description: Language user is requesting type: string required: true default: en - name: username in: path description: The users username required: true type: string - in: query name: asValidator description: treats user as validator, rather than mapper, if true type: string - in: query name: sortBy description: field to sort by, defaults to action_date type: string - in: query name: sortDirection description: direction of sort, defaults to desc type: string - in: query name: page description: Page of results user requested type: integer - in: query name: pageSize description: Size of page, defaults to 10 type: integer - in: query name: project description: Optional project filter type: integer - in: query name: closed description: Optional filter for open/closed invalidations type: boolean responses: 200: description: Invalidated tasks user has invalidated 404: description: No invalidated tasks 500: description: Internal Server Error """ try: sort_column = {"updatedDate": "updated_date", "projectId": "project_id"} if request.args.get("sortBy", "updatedDate") in sort_column: sort_column = sort_column[request.args.get("SortBy", "updatedDate")] else: sort_column = sort_column["updatedDate"] # closed needs to be set to True, False, or None closed = None if request.args.get("closed") == "true": closed = True elif request.args.get("closed") == "false": closed = False # sort direction should only be desc or asc if request.args.get("sortDirection") in ["asc", "desc"]: sort_direction = request.args.get("sortDirection") else: sort_direction = "desc" invalidated_tasks = ValidatorService.get_user_invalidated_tasks( request.args.get("asValidator") == "true", username, request.environ.get("HTTP_ACCEPT_LANGUAGE"), closed, request.args.get("project", None, type=int), request.args.get("page", None, type=int), request.args.get("pageSize", None, type=int), sort_column, sort_direction, ) return invalidated_tasks.to_primitive(), 200 except NotFound: return {"Error": "No invalidated tasks"}, 404 except Exception as e: error_msg = f"TasksQueriesMappedAPI - unhandled error: {str(e)}" current_app.logger.critical(error_msg) return {"Error": "Unable to fetch invalidated tasks for user"}, 500