Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add error message for rasa validate when text is null in a response #8618

Merged
merged 11 commits into from
May 11, 2021
2 changes: 2 additions & 0 deletions changelog/7908.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Made `SchemaError` message available to validator so that the reason why reason schema validation fails during `rasa data validate` is displayed when response `text` value is `null`.
Added warning message when deprecated MappingPolicy format is used in the domain.
10 changes: 7 additions & 3 deletions rasa/shared/utils/pykwalify_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,23 @@

https://pykwalify.readthedocs.io/en/latest/extensions.html#extensions
"""
from typing import Any, List, Dict, Text
from typing import Any, List, Dict, Text, Union

from pykwalify.errors import SchemaError


def require_response_keys(responses: List[Dict[Text, Any]], _: Dict, __: Text) -> bool:
def require_response_keys(
responses: List[Dict[Text, Any]], _: Dict, __: Text
) -> Union[SchemaError, bool]:
"""Validates that response dicts have either the "text" key or the "custom" key."""
for response in responses:
if not isinstance(response, dict):
# this is handled by other validation rules
continue

if response.get("text") is None and not response.get("custom"):
raise SchemaError("Missing 'text' or 'custom' key in response.")
return SchemaError(
"Missing 'text' or 'custom' key in response or null 'text' value in response.",
)

return True
16 changes: 14 additions & 2 deletions rasa/validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,18 @@ def verify_nlu(self, ignore_warnings: bool = True) -> bool:
def verify_domain_validity(self) -> bool:
"""Checks whether the domain returned by the importer is empty.

An empty domain is invalid."""
An empty domain or one that uses deprecated Mapping Policy is invalid.
"""
if self.domain.is_empty():
return False

for intent_key, intent_dict in self.domain.intent_properties.items():
if "triggers" in intent_dict:
rasa.shared.utils.io.raise_warning(
f"The intent {intent_key} in the domain file is using the MappingPolicy format "
f"which has now been deprecated. "
f"Please migrate to RulePolicy."
)
return False
ancalita marked this conversation as resolved.
Show resolved Hide resolved

return not self.domain.is_empty()
return True
14 changes: 14 additions & 0 deletions tests/cli/test_rasa_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,20 @@ def test_validate_files_exit_early():
assert pytest_e.value.code == 1


def test_validate_files_invalid_domain():
args = {
"domain": "data/test_domains/default_with_mapping.yml",
"data": None,
"max_history": None,
"config": None,
}

with pytest.raises(SystemExit):
data.validate_files(namedtuple("Args", args.keys())(*args.values()))
with pytest.warns(UserWarning) as w:
assert "Please migrate to RulePolicy." in str(w[0].message)


def test_rasa_data_convert_nlu_to_yaml(
run_in_simple_project: Callable[..., RunResult],
):
Expand Down
35 changes: 35 additions & 0 deletions tests/shared/utils/test_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,41 @@ def test_validate_yaml_schema_raise_exception(file: Text, schema: Text):
)


def test_validate_yaml_schema_raise_exception_null_text():
domain = """
version: "2.0"
responses:
utter_ask_email:
- text: What is your email ID?
utter_ask_name:
- text: null
"""
with pytest.raises(validation_utils.YamlValidationException) as e:
validation_utils.validate_yaml_schema(domain, DOMAIN_SCHEMA_FILE)

assert (
"Missing 'text' or 'custom' key in response or null 'text' value in response."
in str(e.value)
)


def test_validate_yaml_schema_raise_exception_extra_hyphen_for_image():
domain = """
version: "2.0"
responses:
utter_cheer_up:
- image: https://i.imgur.com/nGF1K8f.jpg
- text: Here is something to cheer you up
"""
with pytest.raises(validation_utils.YamlValidationException) as e:
validation_utils.validate_yaml_schema(domain, DOMAIN_SCHEMA_FILE)

assert (
"Missing 'text' or 'custom' key in response or null 'text' value in response."
in str(e.value)
)


def test_example_training_data_is_valid():
demo_json = "data/examples/rasa/demo-rasa.json"
data = rasa.shared.utils.io.read_json_file(demo_json)
Expand Down
8 changes: 8 additions & 0 deletions tests/test_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,3 +257,11 @@ async def test_verify_there_is_not_example_repetition_in_intents():
)
validator = await Validator.from_importer(importer)
assert validator.verify_example_repetition_in_intents(False)


async def test_invalid_domain_mapping_policy():
importer = RasaFileImporter(
domain_path="data/test_domains/default_with_mapping.yml"
)
validator = await Validator.from_importer(importer)
assert validator.verify_domain_validity() is False