"""Step definitions for AI Models Credentials coverage tests.""" from behave import given, then, when from pydantic import ValidationError from cleveragents.domain.models.aimodelsproviders.ai_models_providers import ( ModelProviderConfigSchema, ) from cleveragents.domain.models.core.enums import ModelPublisher @given("the cleveragents package is available") def step_package_available(context): """Verify the cleveragents package is available.""" import cleveragents assert cleveragents is not None @when("I import ModelProviderOption from aimodelscredentials") def step_import_model_provider_option(context): """Import ModelProviderOption class.""" from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import ( ModelProviderOption, ) context.model_provider_option_class = ModelProviderOption context.imported_class = ModelProviderOption @then("the ModelProviderOption class should be available") def step_verify_class_available(context): """Verify ModelProviderOption class is available.""" assert context.model_provider_option_class is not None assert context.model_provider_option_class.__name__ == "ModelProviderOption" @then("I can create a ModelProviderOption with publishers, config, and priority") def step_create_full_model(context): """Create a ModelProviderOption with all fields.""" ModelProviderOption = context.model_provider_option_class # Create a sample config from cleveragents.domain.models.core.enums import ModelProvider config = ModelProviderConfigSchema( provider=ModelProvider.OPENAI, baseUrl="https://api.openai.com/v1" ) # Create publishers dictionary publishers = { "provider1": {ModelPublisher.OPENAI: True, ModelPublisher.ANTHROPIC: False}, "provider2": {ModelPublisher.GOOGLE: True}, } # Create the model model = ModelProviderOption(publishers=publishers, config=config, priority=1) assert model.priority == 1 assert model.publishers == publishers assert model.config == config @when("I create a ModelProviderOption with only priority set to {priority:d}") def step_create_minimal_model(context, priority): """Create a ModelProviderOption with minimal fields.""" from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import ( ModelProviderOption, ) context.model_instance = ModelProviderOption(priority=priority) @then("the ModelProviderOption should have priority {priority:d}") def step_verify_priority(context, priority): """Verify the priority field value.""" assert context.model_instance.priority == priority @then("the publishers dictionary should be empty") def step_verify_publishers_empty(context): """Verify publishers dictionary is empty.""" assert context.model_instance.publishers == {} @then("the config should be None") def step_verify_config_none(context): """Verify config is None.""" assert context.model_instance.config is None @when("I create a ModelProviderOption with complex publishers structure") def step_create_complex_publishers(context): """Create a ModelProviderOption with complex publishers.""" from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import ( ModelProviderOption, ) publishers = { "primary": { ModelPublisher.OPENAI: True, ModelPublisher.ANTHROPIC: True, ModelPublisher.GOOGLE: False, }, "secondary": {ModelPublisher.MISTRAL: True, ModelPublisher.PERPLEXITY: False}, "tertiary": {ModelPublisher.OPENAI: False}, } context.model_instance = ModelProviderOption(publishers=publishers, priority=2) context.expected_publishers = publishers @then("the publishers field should contain the expected dictionary structure") def step_verify_publishers_structure(context): """Verify the publishers structure.""" assert context.model_instance.publishers == context.expected_publishers @then("the ModelPublisher enum values should be properly handled") def step_verify_enum_handling(context): """Verify enum values are handled correctly.""" # Check that enum values are properly stored for _provider, publisher_dict in context.model_instance.publishers.items(): for _publisher, enabled in publisher_dict.items(): # With use_enum_values=True, the enum values should be used assert isinstance(enabled, bool) @when("I create a ModelProviderOption with a config object") def step_create_with_config(context): """Create a ModelProviderOption with config.""" from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import ( ModelProviderOption, ) from cleveragents.domain.models.core.enums import ModelProvider config = ModelProviderConfigSchema( provider=ModelProvider.OPENAI, baseUrl="https://api.openai.com/v1" ) context.model_instance = ModelProviderOption(config=config, priority=3) context.expected_config = config @then("the config field should contain the ModelProviderConfigSchema instance") def step_verify_config_instance(context): """Verify config contains the right instance.""" assert context.model_instance.config == context.expected_config @then("the config should be properly validated") def step_verify_config_validated(context): """Verify config is validated.""" from cleveragents.domain.models.core.enums import ModelProvider assert context.model_instance.config.provider == ModelProvider.OPENAI assert context.model_instance.config.base_url == "https://api.openai.com/v1" @when("I create a ModelProviderOption with strings containing whitespace") def step_create_with_whitespace(context): """Create model with whitespace in strings.""" from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import ( ModelProviderOption, ) # Note: The model doesn't have direct string fields, but we'll test with config from cleveragents.domain.models.core.enums import ModelProvider config = ModelProviderConfigSchema( provider=ModelProvider.OPENAI, baseUrl=" https://api.openai.com/v1 " ) context.model_instance = ModelProviderOption(config=config, priority=4) @then("the string fields should have whitespace stripped") def step_verify_whitespace_stripped(context): """Verify whitespace is stripped from strings.""" # The ModelProviderConfigSchema should handle its own whitespace stripping # based on its model_config settings assert context.model_instance.config.base_url == "https://api.openai.com/v1" @when("I create a ModelProviderOption instance") def step_create_instance(context): """Create a basic ModelProviderOption instance.""" from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import ( ModelProviderOption, ) context.model_instance = ModelProviderOption(priority=5) @when("I update its fields with new values") def step_update_fields(context): """Update model fields with new values.""" context.model_instance.priority = 10 context.model_instance.publishers = {"updated": {ModelPublisher.OPENAI: True}} @then("the assignment validation should be triggered") def step_verify_assignment_validation(context): """Verify assignment validation works.""" # The values should be updated and validated assert context.model_instance.priority == 10 @then("the values should be properly validated") def step_verify_values_validated(context): """Verify values are validated on assignment.""" assert context.model_instance.publishers == { "updated": {ModelPublisher.OPENAI: True} } @when("I create a ModelProviderOption using field aliases") def step_create_with_aliases(context): """Create model using field aliases (populate_by_name).""" from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import ( ModelProviderOption, ) # With populate_by_name=True, we can use field names directly data = {"priority": 6, "publishers": {}, "config": None} context.model_instance = ModelProviderOption(**data) @then("the fields should be populated correctly by name") def step_verify_populate_by_name(context): """Verify fields are populated by name.""" assert context.model_instance.priority == 6 assert context.model_instance.publishers == {} assert context.model_instance.config is None @when("I create a ModelProviderOption with ModelPublisher enums") def step_create_with_enums(context): """Create model with enum values.""" from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import ( ModelProviderOption, ) publishers = { "test": {ModelPublisher.OPENAI: True, ModelPublisher.ANTHROPIC: False} } context.model_instance = ModelProviderOption(publishers=publishers, priority=7) @then("the enum values should be used in serialization") def step_verify_enum_serialization(context): """Verify enum values in serialization.""" data = context.model_instance.model_dump() # With use_enum_values=True, enums should be serialized as their values assert isinstance(data["publishers"], dict) @then("the model should handle enum values properly") def step_verify_enum_handling_proper(context): """Verify proper enum handling.""" # The model should work with enum values assert context.model_instance.publishers["test"][ModelPublisher.OPENAI] is True @when("I create a ModelProviderOption with default fields") def step_create_with_defaults(context): """Create model with default fields.""" from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import ( ModelProviderOption, ) context.model_instance = ModelProviderOption(priority=8) @then("publishers should default to an empty dictionary") def step_verify_publishers_default(context): """Verify publishers defaults to empty dict.""" assert context.model_instance.publishers == {} @then("config should default to None") def step_verify_config_default(context): """Verify config defaults to None.""" assert context.model_instance.config is None @when("I try to create a ModelProviderOption with invalid priority") def step_create_invalid_priority(context): """Try to create model with invalid priority.""" from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import ( ModelProviderOption, ) try: # Priority should be an integer, not a string context.model_instance = ModelProviderOption(priority="invalid") context.validation_error = None except ValidationError as e: context.validation_error = e @then("a ModelProviderOption validation error should be raised") def step_verify_validation_error(context): """Verify validation error is raised.""" assert context.validation_error is not None @then("the error should indicate the priority field issue") def step_verify_priority_error(context): """Verify error is about priority field.""" error_dict = context.validation_error.errors()[0] assert "priority" in str(error_dict) @when("I examine the ModelProviderOption model_config") def step_examine_model_config(context): """Examine the model_config settings.""" from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import ( ModelProviderOption, ) context.model_config = ModelProviderOption.model_config @then("the ModelProviderOption str_strip_whitespace should be True") def step_verify_strip_whitespace_mpo(context): """Verify str_strip_whitespace setting for ModelProviderOption.""" cfg = getattr(context, "model_config", None) or context.model_instance.model_config assert cfg.get("str_strip_whitespace") is True @then("the ModelProviderOption validate_assignment should be True") def step_verify_validate_assignment_mpo(context): """Verify validate_assignment setting for ModelProviderOption.""" cfg = getattr(context, "model_config", None) or context.model_instance.model_config assert cfg.get("validate_assignment") is True @then("the ModelProviderOption arbitrary_types_allowed should be False") def step_verify_arbitrary_types_mpo(context): """Verify arbitrary_types_allowed setting for ModelProviderOption.""" cfg = getattr(context, "model_config", None) or context.model_instance.model_config assert cfg.get("arbitrary_types_allowed") is False @then("the ModelProviderOption populate_by_name should be True") def step_verify_populate_by_name_setting_mpo(context): """Verify populate_by_name setting for ModelProviderOption.""" cfg = getattr(context, "model_config", None) or context.model_instance.model_config assert cfg.get("populate_by_name") is True @then("the ModelProviderOption use_enum_values should be True") def step_verify_use_enum_values_mpo(context): """Verify use_enum_values setting for ModelProviderOption.""" cfg = getattr(context, "model_config", None) or context.model_instance.model_config assert cfg.get("use_enum_values") is True @when("I create a ModelProviderOption with nested publisher dictionaries") def step_create_nested_publishers(context): """Create model with nested publisher structures.""" from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import ( ModelProviderOption, ) publishers = { "level1": {ModelPublisher.OPENAI: True, ModelPublisher.ANTHROPIC: False}, "level2": {ModelPublisher.GOOGLE: True, ModelPublisher.MISTRAL: True}, } context.model_instance = ModelProviderOption(publishers=publishers, priority=9) context.nested_publishers = publishers @then("the nested structure should be properly maintained") def step_verify_nested_structure(context): """Verify nested structure is maintained.""" assert context.model_instance.publishers == context.nested_publishers @then("the ModelPublisher boolean values should work correctly") def step_verify_boolean_values(context): """Verify boolean values work correctly.""" assert context.model_instance.publishers["level1"][ModelPublisher.OPENAI] is True assert ( context.model_instance.publishers["level1"][ModelPublisher.ANTHROPIC] is False ) assert context.model_instance.publishers["level2"][ModelPublisher.GOOGLE] is True @when("I serialize a ModelProviderOption to dict") def step_serialize_to_dict(context): """Serialize ModelProviderOption to dictionary.""" from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import ( ModelProviderOption, ) from cleveragents.domain.models.core.enums import ModelProvider config = ModelProviderConfigSchema( provider=ModelProvider.OPENAI, baseUrl="https://api.openai.com/v1" ) model = ModelProviderOption( publishers={"test": {ModelPublisher.OPENAI: True}}, config=config, priority=10 ) context.original_model = model context.serialized_data = model.model_dump() @when("I deserialize it back to ModelProviderOption") def step_deserialize_from_dict(context): """Deserialize dictionary back to ModelProviderOption.""" from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import ( ModelProviderOption, ) context.deserialized_model = ModelProviderOption(**context.serialized_data) @then("the round-trip should preserve all data") def step_verify_round_trip(context): """Verify round-trip preserves data.""" assert context.deserialized_model.priority == context.original_model.priority # Note: Direct comparison might fail due to enum serialization assert ( context.deserialized_model.model_dump() == context.original_model.model_dump() ) @when("I explicitly set config to None in ModelProviderOption") def step_set_config_none(context): """Explicitly set config to None.""" from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import ( ModelProviderOption, ) context.model_instance = ModelProviderOption(config=None, priority=11) @then("the config field should accept None value") def step_verify_config_accepts_none(context): """Verify config accepts None.""" assert context.model_instance.config is None @then("the model should be valid") def step_verify_model_valid(context): """Verify model is valid.""" # Model should be valid with None config assert context.model_instance.priority == 11 @when("I try to create a ModelProviderOption without priority") def step_create_without_priority(context): """Try to create model without required priority field.""" from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import ( ModelProviderOption, ) try: context.model_instance = ModelProviderOption() context.validation_error = None except ValidationError as e: context.validation_error = e @then( "a ModelProviderOption validation error should be raised for missing required field" ) def step_verify_missing_field_error(context): """Verify error for missing required field.""" assert context.validation_error is not None error_dict = context.validation_error.errors()[0] assert "priority" in str(error_dict) assert "required" in str(error_dict).lower() or "missing" in str(error_dict).lower()