def test_process_warns_if_intent_or_entities_not_in_domain(
    regex_message_handler: RegexMessageHandler,
    intent: Text,
    entities: Optional[Text],
    expected_intent: Text,
    domain_entities: List[Text],
):
    # construct text according to pattern
    text = INTENT_MESSAGE_PREFIX + intent  # do not add a confidence value
    if entities is not None:
        text += json.dumps(entities)
    message = Message(data={TEXT: text})

    # construct domain from expected intent/entities
    domain = Domain(
        intents=[expected_intent],
        entities=domain_entities,
        slots=[],
        responses={},
        action_names=[],
        forms={},
    )

    # expect a warning
    with pytest.warns(UserWarning):
        results = regex_message_handler.process([message], domain)
    unpacked_message = results[0]

    if "wrong" not in intent:
        assert unpacked_message.data[INTENT][INTENT_NAME_KEY] == intent
        if "wrong" in entities:
            assert unpacked_message.data[ENTITIES] is not None
            assert len(unpacked_message.data[ENTITIES]) == 0
    else:
        assert unpacked_message == message
def regex_message_handler(
        default_model_storage: ModelStorage,
        default_execution_context: ExecutionContext) -> RegexMessageHandler:
    return RegexMessageHandler.create(
        config={},
        model_storage=default_model_storage,
        resource=Resource("unused"),
        execution_context=default_execution_context,
    )
def test_regex_message_handler_adds_extractor_name(
        regex_message_handler: RegexMessageHandler, text: Text):

    message = Message(
        data={
            TEXT: text,
            INTENT: "bla"
        },
        features=[
            Features(
                features=np.zeros((1, 1)),
                feature_type=FEATURE_TYPE_SENTENCE,
                attribute=TEXT,
                origin="nlu-pipeline",
            )
        ],
    )
    parsed_messages = regex_message_handler.process([message])

    for message in parsed_messages:

        for entity in message.get(ENTITIES):
            assert entity[EXTRACTOR] == RegexMessageHandler.__name__
def test_process_unpacks_attributes_from_single_message_and_fallsback_if_needed(
    regex_message_handler: RegexMessageHandler,
    confidence: Optional[Text],
    entities: Optional[Text],
    expected_confidence: float,
    expected_entities: Optional[List[Dict[Text, Any]]],
    should_warn: bool,
):

    # dummy intent
    expected_intent = "my-intent"

    # construct text according to pattern
    text = " \t  " + INTENT_MESSAGE_PREFIX + expected_intent
    if confidence is not None:
        text += f"@{confidence}"
    if entities is not None:
        text += entities
    text += " \t "

    # create a message with some dummy attributes and features
    message = Message(
        data={
            TEXT: text,
            INTENT: "extracted-from-the-pattern-text-via-nlu"
        },
        features=[
            Features(
                features=np.zeros((1, 1)),
                feature_type=FEATURE_TYPE_SENTENCE,
                attribute=TEXT,
                origin="nlu-pipeline",
            )
        ],
    )

    # construct domain from expected intent/entities
    domain_entities = [
        item[ENTITY_ATTRIBUTE_TYPE] for item in expected_entities
    ]
    domain_intents = [expected_intent] if expected_intent is not None else []
    domain = Domain(
        intents=domain_intents,
        entities=domain_entities,
        slots=[],
        responses={},
        action_names=[],
        forms={},
    )

    # extract information
    if should_warn:
        with pytest.warns(UserWarning):
            results = regex_message_handler.process([message], domain)
    else:
        results = regex_message_handler.process([message], domain)

    assert len(results) == 1
    unpacked_message = results[0]

    assert not unpacked_message.features

    assert set(unpacked_message.data.keys()) == {
        TEXT,
        INTENT,
        INTENT_RANKING_KEY,
        ENTITIES,
    }

    assert unpacked_message.data[TEXT] == message.data[TEXT].strip()

    assert set(unpacked_message.data[INTENT].keys()) == {
        INTENT_NAME_KEY,
        PREDICTED_CONFIDENCE_KEY,
    }
    assert unpacked_message.data[INTENT][INTENT_NAME_KEY] == expected_intent
    assert (unpacked_message.data[INTENT][PREDICTED_CONFIDENCE_KEY] ==
            expected_confidence)

    intent_ranking = unpacked_message.data[INTENT_RANKING_KEY]
    assert len(intent_ranking) == 1
    assert intent_ranking[0] == {
        INTENT_NAME_KEY: expected_intent,
        PREDICTED_CONFIDENCE_KEY: expected_confidence,
    }
    if expected_entities:
        entity_data: List[Dict[Text, Any]] = unpacked_message.data[ENTITIES]
        assert all(
            set(item.keys()) == {
                ENTITY_ATTRIBUTE_VALUE,
                ENTITY_ATTRIBUTE_TYPE,
                ENTITY_ATTRIBUTE_START,
                ENTITY_ATTRIBUTE_END,
            } for item in entity_data)
        assert set(
            (item[ENTITY_ATTRIBUTE_TYPE], item[ENTITY_ATTRIBUTE_VALUE])
            for item in expected_entities) == set(
                (item[ENTITY_ATTRIBUTE_TYPE], item[ENTITY_ATTRIBUTE_VALUE])
                for item in entity_data)
    else:
        assert unpacked_message.data[ENTITIES] is not None
        assert len(unpacked_message.data[ENTITIES]) == 0