import inspect from unittest import mock from django.test import TestCase, override_settings from arches.app.const import ExtensionType from arches.app.utils.module_importer import get_directories, get_class_from_modulename from arches.test.utils import sync_overridden_test_settings_to_arches # these tests can be run from the command line via # python manage.py test tests.utils.test_module_importer --settings="tests.test_settings" def patched_arches_applications(): return ["arches_for_music", "arches_for_dance"] @mock.patch( "arches.app.utils.module_importer.list_arches_app_names", patched_arches_applications, ) class GetDirectoriesTests(TestCase): @override_settings( APP_NAME="hiphop", FUNCTION_LOCATIONS=[ "arches.app.functions", # Include an example where one of the installed apps is explicitly given "arches_for_music.pkg.extensions.functions", "hiphop.functions", ], ) def test_arches_application_extension_explicit(self): with sync_overridden_test_settings_to_arches(): function_dirs = get_directories(ExtensionType.FUNCTIONS) self.assertEqual( function_dirs, [ "arches_for_music.functions", "arches_for_music.pkg.extensions.functions", "arches_for_dance.functions", "arches_for_dance.pkg.extensions.functions", "hiphop.functions", "arches.app.functions", ], ) @override_settings( APP_NAME="hiphop", SEARCH_COMPONENT_LOCATIONS=[ # Same, but poorly ordered. "hiphop.search_components", "arches_for_music.search_components", "arches.app.search.components", ], ) def test_arches_application_extension_explicit_poorly_ordered(self): with sync_overridden_test_settings_to_arches(): search_dirs = get_directories(ExtensionType.SEARCH_COMPONENTS) self.assertEqual( search_dirs, [ "arches_for_music.search_components", "arches_for_music.pkg.extensions.search_components", "arches_for_dance.search_components", "arches_for_dance.pkg.extensions.search_components", "hiphop.search_components", "arches.app.search.components", ], ) @override_settings( APP_NAME="hiphop", ETL_MODULE_LOCATIONS=[ # App not given. "arches.app.etl_modules", ], ) def test_arches_application_extension_implicit(self): with sync_overridden_test_settings_to_arches(): etl_modules = get_directories(ExtensionType.ETL_MODULES) self.assertEqual( etl_modules, [ "arches_for_music.etl_modules", "arches_for_music.pkg.extensions.etl_modules", "arches_for_dance.etl_modules", "arches_for_dance.pkg.extensions.etl_modules", "arches.app.etl_modules", ], ) @override_settings( APP_NAME="hiphop", DATATYPE_LOCATIONS=[], # Nothing given. ) def test_arches_application_extension_core_arches_implicit(self): with sync_overridden_test_settings_to_arches(): datatypes = get_directories(ExtensionType.DATATYPES) self.assertEqual( datatypes, [ "arches_for_music.datatypes", "arches_for_music.pkg.extensions.datatypes", "arches_for_dance.datatypes", "arches_for_dance.pkg.extensions.datatypes", "arches.app.datatypes", ], ) class GetClassFromModuleNameTests(TestCase): @override_settings(DATATYPE_LOCATIONS=["nonexistent_module"]) def test_nonexistent_module(self): with sync_overridden_test_settings_to_arches(): with self.assertRaises(ModuleNotFoundError): get_class_from_modulename( "nonexistent_module", "BaseDataType", ExtensionType.DATATYPES, ) @override_settings(DATATYPE_LOCATIONS=["tests.fixtures.datatypes"]) def test_module_without_url_datatype(self): with sync_overridden_test_settings_to_arches(): result = get_class_from_modulename( "url", "URLDataType", ExtensionType.DATATYPES, ) self.assertTrue(inspect.isclass(result))