def tearDown(self) -> None: """ Clean up all dependencies after tests""" for alias in self.aliases: try: if AttrAlias.get_by_user_id(self.user.id): alias.delete() alias.commit() except Exception: pass for attr in self.attributes: try: if Attributes.get_by_id(attr.id): attr.delete() attr.commit() except Exception: pass for sub_theme in self.sub_themes: try: if SubTheme.get_by_id(sub_theme.id): sub_theme.delete() sub_theme.commit() except Exception: pass for unit in self.units: try: if Unit.get_by_id(unit.id): unit.delete() unit.commit() except Exception: pass try: if Theme.get_by_id(self.theme.id): self.theme.delete() self.theme.commit() except Exception: pass self.client.post('/logout', headers=self.auth_header) if self.user: if Users.find_by_id(self.user.id): try: self.user.delete() self.user.commit() except Exception: pass self.app_context.pop()
def get(self) -> (dict, HTTPStatus): """ Check for triggered alerts. :return: On success, an HTTP response with a JSON body content containing the maximum and minimum alerts that have been exceeded with an HTTP status code of 200 (OK), otherwise an HTTP response with a JSON body content containing an appropriate error message and appropriate an HTTP status code """ args = self.reqparser.parse_args() # Use current user_id if not user_id was parsed if "user_id" not in args: user = Users.find_by_email(get_jwt_identity()) if user: args["user_id"] = user.id else: # Return Error current user id not found return (dict(error="User id not found for Current user, " "User session may have timed out"), HTTPStatus.INTERNAL_SERVER_ERROR) else: user = Users.find_by_id(args["user_id"]) if not user: # Return error Parsed User Id not found return dict(error="User with id {} not found.".format( args["user_id"])), HTTPStatus.NOT_FOUND # Check Attribute exists if not Attributes.get_by_id(args["attribute_id"]): # Return Error Attribute ID not found return dict(error="Attribute id {} not found.".format( args["attribute_id"])), HTTPStatus.NOT_FOUND # Get Attribute Max and Minimums attribute_range = AttributeRange.get_by_attr_id(args["attribute_id"]) if not attribute_range: # Return eroor Attribute range not found return (dict(error="Attribute range not found", **args), HTTPStatus.NOT_FOUND) # Check Alerts max_alerts = AlertWidgetModel.get_max_alerts(attribute_range, user_id=user.id) min_alerts = AlertWidgetModel.get_min_alerts(attribute_range, user_id=user.id) return dict(max=max_alerts, min=min_alerts), 200
def args_db_checker(self, args) -> None: """ Check parsed Arguments and dependencies and Create appropriate RFC-7807 JSON Error Response :param args: Parsed Arguments in GET request """ invalid_params = [] if "user_id" in args: # Create JSON Error message if User does not exist if not Users.find_by_id(args["user_id"]) and args["user_id"] >= 0: invalid_params.append({ "name": "user_id", "value": args["user_id"], "reason": "User Not Found", "code": 404, "rollback": "Theme Tree will not contain Attribute Aliases" }) if "theme_id" in args: # Create JSON Error message if Theme does not exist if not Theme.get_by_id(args["theme_id"]): invalid_params.append({ "name": "theme_id", "value": args["theme_id"], "reason": "Theme Not Found", "code": 404, "rollback": "A Themes will be return in the Theme Tree" }) if invalid_params: # Put Error message in response self.response = [{ "error": dict(type='Request entries not found', title="Unable to fetch dB entries for parsed arguments", invalid_params=invalid_params) }]
def post(self) -> (dict, HTTPStatus): """ Create an alert. :return: On success return the new alert Id and an HTTP status code 201 (Created), Otherwise return an error with the appropriate HTTP status code """ args = self.reqparser.parse_args() if "user_id" not in args: # Not user_id in args get current user_id user = Users.find_by_email(get_jwt_identity()) if user: args["user_id"] = user.id else: # Return Error current user id not found return (dict(error="User id not found for Current user, " "User session may have timed out"), HTTPStatus.INTERNAL_SERVER_ERROR) elif not Users.find_by_id(args["user_id"]): # User not found return an error return dict(error="User id {} not found".format( args["user_id"])), HTTPStatus.NOT_FOUND if "max_threshold" not in args and "min_threshold" not in args: # No Threshold value in args at least one is required return an error return dict( error="A Threshold value is required"), HTTPStatus.BAD_REQUEST # Create AlertModel alert_model = AlertWidgetModel(args["user_id"], args["widget_id"], args["attribute_id"], args["max_threshold"], args["min_threshold"], args["activated"]) if not alert_model: # Unable to create AlertModel return an error return dict(error="Unable to create Alert", args=args), \ HTTPStatus.INTERNAL_SERVER_ERROR # Persist Alert to database alert_model.save() alert_model.commit() return dict(id=alert_model.id), HTTPStatus.CREATED
def post(self) -> ({str: str}, HTTPStatus): """ Update AttrAlias (Attribute Alias) if it exists otherwise create an AttrAlias :param attribute_id: Parent Attribute id to alias :param user_id: Owner user id :param name: Alias for Attribute name :param table_name: Alias for Attribute table_name :param unit_id: Id of unit to be used :param description: Custom user description for Attribute :return: AttrAlias with an HTTPstatus code OK (200) or an error message and a the appropriate HTTPStatus code """ args = self.reqpaser.parse_args() attribute = Attributes.get_by_id(args["attribute_id"]) if not attribute: return {"error": "Attribute Not Found."}, HTTPStatus.NOT_FOUND user = Users.find_by_id(args["user_id"]) if not user: return {"error": "User Not Found."}, HTTPStatus.NOT_FOUND alias = AttrAlias.get_by(user_id=args["user_id"], attribute_id=args["attribute_id"]) if alias: alias.name = args["name"] if "name" in args else alias.name alias.table_name = args["table_name"] if "table_name" in args else alias.table_name alias.unit_id = args["unit_id"] if "unit_id" in args else alias.unit_id alias.description = args["description"] if "description" in args else alias.description else: alias = AttrAlias(args["attribute_id"], args["user_id"], name=args.get("name"), table_name=args.get("table_name"), description=args.get("description")) try: alias.save() alias.commit() except Exception as e: logger.error("failed to persist attribute alias", e) return {"error": "Failed to commit attribute alias to database", "exception": e}, HTTPStatus.INTERNAL_SERVER_ERROR return alias.json(), HTTPStatus.OK
def get(self) -> ({str: str}, HTTPStatus): """ Fetch AttrAlias (Attribute Alias) from the database :param attribute_id: Parent Attribute id :param user_id: Owner user id :return: AttrAlias with an HTTPstatus code OK (200) or an error message and a the appropriate HTTPStatus code """ args = self.reqpaser.parse_args() attribute = Attributes.get_by_id(args["attribute_id"]) if not attribute: return {"error": "Attribute Not Found."}, HTTPStatus.NOT_FOUND user = Users.find_by_id(args["user_id"]) if not user: return {"error": "User Not Found."}, HTTPStatus.NOT_FOUND alias = AttrAlias.get_by(user_id=args["user_id"], attribute_id=args["attribute_id"]) if not alias: return attribute.json(), HTTPStatus.OK return alias.json(), HTTPStatus.OK
def check_min_and_max_alert_widgets(attribute_range_entry: db.Model): """ Send emails to users for alert widgets that have been triggered :param attribute_range_entry: Entry in the attribute range table """ if attribute_range_entry.maximum: max_alerts = AlertWidgetModel.get_max_alerts(attribute_range_entry) for alert in max_alerts: user_details = Users.find_by_id(alert["user_id"]) if user_details: attr = Attributes.get_by_id(attribute_range_entry.attribute_id) if attr: if not send_alert_email( user_details.email, user_details.fullname, attr.name, attribute_range_entry.maximum, attribute_range_entry.maximum_recorded_date, attribute_range_entry.maximum_sensor_id, alert["max_threshold"], "exceeded"): logger.error("Server error prevented the " "sending of a max alert email " "to {} regarding attribute with " "id {}".format( user_details.email, attribute_range_entry.attribute_id)) else: logger.error("Could not send max alert email to " "user with id {} as the attribute with " "id {} does not exist ".format( alert["user_id"], attribute_range_entry.attribute_id)) else: logger.error("Could not send max alert email to " "user with id {} as the user does " "not exist ".format(alert["user_id"])) if attribute_range_entry.minimum: min_alerts = AlertWidgetModel.get_min_alerts(attribute_range_entry) for alert in min_alerts: user_details = Users.find_by_id(alert["user_id"]) if user_details: attr = Attributes.get_by_id(attribute_range_entry.attribute_id) if attr: if not send_alert_email( user_details.email, user_details.fullname, attr.name, attribute_range_entry.minimum, attribute_range_entry.minimum_recorded_date, attribute_range_entry.minimum_sensor_id, alert["min_threshold"], "fell short of"): logger.error("Server error prevented the sending of " "a min alert email to {} regarding " "attribute with id {}".format( user_details.email, attribute_range_entry.attribute_id)) else: logger.error("Could not send min alert email to " "user with id {} as the attribute with " "id {} does not exist ".format( alert["user_id"], attribute_range_entry.attribute_id)) else: logger.error("Could not send min alert email to " "user with id {} as the user does " "not exist ".format(alert["user_id"]))