def test_models_validator_validate_with_no_events(caplog): """Tests given no events, the validate method does not write error messages.""" result = Validator(ModelSelector(module="ralph.models.edx")).validate( [], ignore_errors=False, fail_on_unknown=True) with caplog.at_level(logging.ERROR): assert list(result) == [] assert [] == [message for _, _, message in caplog.record_tuples]
def test_models_validator_validate_with_a_non_json_event_raises_an_exception( event, caplog): """Tests given a non JSON event, the validate method should raise a BadFormatException.""" result = Validator(ModelSelector(module="ralph.models.edx")).validate( [event], ignore_errors=False, fail_on_unknown=True) with caplog.at_level(logging.ERROR): with pytest.raises(BadFormatException): list(result)
def test_models_validator_validate_with_valid_events(ignore_errors, fail_on_unknown, event): """Tests given a valid event the validate method should yield it.""" event_str = event.json() event_dict = json.loads(event_str) validator = Validator(ModelSelector(module="ralph.models.edx")) result = validator.validate([event_str], ignore_errors, fail_on_unknown) assert json.loads(next(result)) == event_dict
def test_models_edx_edx_course_enrollment_mode_changed_selector_with_valid_event(event): """Tests given an edx.course.enrollment.mode_changed event the get_model method should return EdxCourseEnrollmentModeChanged model. """ event = json.loads(event.json()) assert ( ModelSelector(module="ralph.models.edx").get_model(event) is EdxCourseEnrollmentModeChanged )
def test_models_validator_validate_with_a_non_json_event_writes_an_error_message( event, caplog): """Tests given a non JSON event, the validate method should write an error message.""" result = Validator(ModelSelector(module="ralph.models.edx")).validate( [event], ignore_errors=True, fail_on_unknown=True) with caplog.at_level(logging.ERROR): assert list(result) == [] errors = ["Input event is not a valid JSON string"] assert errors == [message for _, _, message in caplog.record_tuples]
def test_models_edx_ui_edx_course_enrollment_upgrade_clicked_selector_with_valid_event( event, ): """Tests given an edx.course.enrollment.upgrade_clicked event the get_model method should return UIEdxCourseEnrollmentUpgradeClicked model. """ event = json.loads(event.json()) assert ( ModelSelector(module="ralph.models.edx").get_model(event) is UIEdxCourseEnrollmentUpgradeClicked )
def test_models_validator_validate_with_an_unknown_event_writes_an_error_message( event, caplog): """Tests given an unknown event the validate method should write an error message.""" result = Validator(ModelSelector(module="ralph.models.edx")).validate( [event], ignore_errors=False, fail_on_unknown=False, ) with caplog.at_level(logging.ERROR): assert list(result) == [] errors = ["No matching pydantic model found for input event"] assert errors == [message for _, _, message in caplog.record_tuples]
def validate(format_, ignore_errors, fail_on_unknown): """Validates input events of given format.""" logger.info( "Validating %s events (ignore_errors=%s | fail-on-unknown=%s)", format_, ignore_errors, fail_on_unknown, ) validator = Validator(ModelSelector(f"ralph.models.{format_}")) for event in validator.validate(sys.stdin, ignore_errors, fail_on_unknown): click.echo(event)
def test_models_validator_validate_with_invalid_page_close_event_raises_an_exception( caplog, ): """Tests given an event that match a pydantic model but fail at the model validation step, the validate method should raise a BadFormatException. """ result = Validator(ModelSelector(module="ralph.models.edx")).validate( [json.dumps({ "event_source": "browser", "event_type": "page_close" })], ignore_errors=False, fail_on_unknown=True, ) with caplog.at_level(logging.ERROR): with pytest.raises(BadFormatException): list(result)
def test_models_validator_validate_counter(caplog, event): """Tests given multiple events the validate method should log the total and invalid events.""" valid_event = event.json() invalid_event_1 = 1 invalid_event_2 = "" events = [invalid_event_1, valid_event, invalid_event_2] result = Validator(ModelSelector(module="ralph.models.edx")).validate( events, ignore_errors=True, fail_on_unknown=False) with caplog.at_level(logging.INFO): assert [valid_event] == list(result) assert ( "ralph.models.validator", logging.INFO, "Total events: 3, Invalid events: 2", ) in caplog.record_tuples
def test_models_validator_validate_with_an_invalid_page_close_event_writes_an_error_message( caplog, ): """Tests given an event that match a pydantic model but fail at the model validation step, the validate method should write an error message. """ result = Validator(ModelSelector(module="ralph.models.edx")).validate( [json.dumps({ "event_source": "browser", "event_type": "page_close" })], ignore_errors=True, fail_on_unknown=True, ) with caplog.at_level(logging.ERROR): assert list(result) == [] errors = ["Input event is not a valid UIPageClose event."] assert errors == [message for _, _, message in caplog.record_tuples]
def convert(from_, to_, ignore_errors, fail_on_unknown, **conversion_set_kwargs): """Converts input events to a given format.""" logger.info( "Converting %s events to %s format (ignore_errors=%s | fail-on-unknown=%s)", from_, to_, ignore_errors, fail_on_unknown, ) logger.debug("Converter parameters: %s", conversion_set_kwargs) converter = Converter( model_selector=ModelSelector(f"ralph.models.{from_}"), module=f"ralph.models.{from_}.converters.{to_}", **conversion_set_kwargs, ) for event in converter.convert(sys.stdin, ignore_errors, fail_on_unknown): click.echo(event)
def test_models_validator_validate_typing_cleanup(event): """Tests given a valid event with wrong field types, the validate method should fix them.""" valid_event_str = event.json() valid_event = json.loads(valid_event_str) valid_event["host"] = "1" valid_event["accept_language"] = "False" valid_event["context"]["course_user_tags"] = {"foo": "1"} valid_event["context"]["user_id"] = 123 invalid_event = copy.deepcopy(valid_event) invalid_event["host"] = 1 # not string invalid_event["accept_language"] = False # not string invalid_event["context"]["course_user_tags"] = {"foo": 1} # not string invalid_event["context"]["user_id"] = "123" # not integer invalid_event_str = json.dumps(invalid_event) validator = Validator(ModelSelector(module="ralph.models.edx")) result = validator.validate([invalid_event_str], ignore_errors=False, fail_on_unknown=True) assert json.loads(next(result)) == valid_event
def test_model_selector_server_event_get_model_with_valid_event(event): """Tests given a server event, the get_model method should return the corresponding model.""" event = json.loads(event.json()) assert ModelSelector(module="ralph.models.edx").get_model(event) is ServerEvent
def test_models_selector_model_selector_decision_tree(model_rules, decision_tree): """Given `model_rules` the ModelSelector should create the expected decision tree.""" model_selector = ModelSelector(module="ralph.models.edx") assert model_selector.get_decision_tree(model_rules) == decision_tree
def test_models_selector_model_selector_get_model_with_invalid_event(): """Tests given an invalid event the get_model method should raise UnknownEventException.""" with pytest.raises(UnknownEventException): ModelSelector(module="ralph.models.edx").get_model( {"invalid": "event"})
def test_models_selector_model_selector_build_model_rules(module, model_rules): """Given an imported module build_model_rules should return the corresponding model_rules.""" assert ModelSelector.build_model_rules(module) == model_rules