def update_from_json(self, update_data): award_dict = update_data.get("award", {}) if not isinstance(award_dict, dict): raise ValidationError(f"'award' expected to be a dictionary") for k, v in award_dict.items(): key_mapping = { "startDate": "start_date", "endDate": "end_date", "awardingOrganisationName": "awarding_organisation_name", "awardValue": "award_value", } if k in key_mapping: if k == "awardValue": try: v = decimal.Decimal(v) if v is not None else None except decimal.InvalidOperation: raise ValidationError(f"Failed to parse {v!r} as decimal for field {k!r}") elif k in ("startDate", "endDate",): if v is not None: try: v = datetime.datetime.strptime(v, DATE_FORMAT).date() except ValueError as e: raise ValidationError(f"Failed to parse {v!r} as date for field {k!r}: {e.args[0]}") setattr(self, key_mapping[k], v)
def _validates_data_complete_if_completed_at(self, key, value): if key == "award_value": if value is not None and value < 0: raise ValidationError(f"{key} must be greater than or equal to zero, got {value!r}") if self.completed_at and self.result == "awarded" and value in (None, "",): raise ValidationError( f"{key} cannot be None or empty if Outcome with result={self.result!r} is 'completed'." f" Received {value!r}" ) if self.result not in (None, "awarded",) and value is not None: raise ValidationError( f"{key} cannot be set for Outcomes with result={self.result!r}. Attempted to set value {value!r}" ) return value
def _assert_active_project(self, key, value): if self.project and self.project.locked_at: raise ValidationError('Cannot change attributes of a search under a project ({}) that ' 'has been locked.'.format(self.project_id)) if key == 'search_url' and value: # remove hostname etc so that stored URI is always relative to the base Search API URI in our config return force_relative_url(current_app.config['DM_SEARCH_API_URL'], value) else: return value
def test_api_validation_error_handler(app_with_mocked_logger): with app_with_mocked_logger.test_request_context('/'): try: raise ValidationError("Hippogriff") except ValidationError as e: response = validation_error_handler(e) assert json.loads(response.get_data()) == { "error": "Hippogriff", } assert response.status_code == 400 assert app_with_mocked_logger.logger.warning.mock_calls == []
def _validates_completed_at_data_complete_if_set(self, key, value): if key == "result" and value not in self.RESULT_CHOICES: raise ValidationError(f"{value!r} is not a valid choice for field {key!r}") result = value if key == "result" else self.result completed_at = value if key == "completed_at" else self.completed_at if result == "awarded" and completed_at is not None: failures = ", ".join( "{}={}".format(fkey, repr(getattr(self, fkey))) for fkey in ( "start_date", "end_date", "awarding_organisation_name", "award_value", ) if (getattr(self, fkey) in (None, "",)) ) if failures: raise ValidationError( f"Outcome with result={result!r} cannot be 'completed' with None or empty data fields," f" but {failures}" ) if result not in (None, "awarded",): failures = ", ".join( "{}={}".format(fkey, repr(getattr(self, fkey))) for fkey in ( "start_date", "end_date", "awarding_organisation_name", "award_value", ) if getattr(self, fkey) is not None ) if failures: raise ValidationError( f"Outcomes with result={result!r} cannot have award-related data fields set, but {failures}" ) return value
def filter_services(framework_slugs=None, statuses=None, lot_slug=None, location=None, role=None): if framework_slugs: services = Service.query.has_frameworks(*framework_slugs) else: services = Service.query.framework_is_live() if statuses: services = services.has_statuses(*statuses) location_key = "locations" if role: if lot_slug != 'digital-specialists': raise ValidationError( "Role only applies to Digital Specialists lot") location_key = role + "Locations" services = services.data_has_key(location_key) if location: if not lot_slug: raise ValidationError( "Lot must be specified to filter by location") if lot_slug == 'digital-specialists': if not role: raise ValidationError( "Role must be specified for Digital Specialists") services = services.data_key_contains_value(location_key, location) if lot_slug: services = services.in_lot(lot_slug) return services
def _assert_active_project(self, key, value): if self.locked_at: raise ValidationError('Cannot change project name after locking it ({})'.format(self.id)) return value