diff --git a/scripts/seed_data.py b/scripts/seed_data.py index f7c035f..4db4c1c 100644 --- a/scripts/seed_data.py +++ b/scripts/seed_data.py @@ -135,24 +135,36 @@ def run_with_namespace( *, config: Optional[DatabaseConfig] = None, ) -> None: + if not hasattr(args, "verbose"): + args.verbose = 0 + if not hasattr(args, "dry_run"): + args.dry_run = False + _configure_logging(args) - if not any((args.currencies, args.units, args.theme, args.defaults)): + currencies = bool(getattr(args, "currencies", False)) + units = bool(getattr(args, "units", False)) + theme = bool(getattr(args, "theme", False)) + defaults = bool(getattr(args, "defaults", False)) + dry_run = bool(getattr(args, "dry_run", False)) + + if not any((currencies, units, theme, defaults)): logger.info("No seeding options provided; exiting") return config = config or DatabaseConfig.from_env() + with psycopg2.connect(config.application_dsn()) as conn: conn.autocommit = True with conn.cursor() as cursor: - if args.currencies: - _seed_currencies(cursor, dry_run=args.dry_run) - if args.units: - _seed_units(cursor, dry_run=args.dry_run) - if args.theme: - _seed_theme(cursor, dry_run=args.dry_run) - if args.defaults: - _seed_defaults(cursor, dry_run=args.dry_run) + if currencies: + _seed_currencies(cursor, dry_run=dry_run) + if units: + _seed_units(cursor, dry_run=dry_run) + if theme: + _seed_theme(cursor, dry_run=dry_run) + if defaults: + _seed_defaults(cursor, dry_run=dry_run) def _seed_currencies(cursor, *, dry_run: bool) -> None: diff --git a/tests/unit/test_seed_data.py b/tests/unit/test_seed_data.py new file mode 100644 index 0000000..87094b9 --- /dev/null +++ b/tests/unit/test_seed_data.py @@ -0,0 +1,46 @@ +import argparse +from unittest import mock + +import scripts.seed_data as seed_data +from scripts.seed_data import DatabaseConfig + + +def test_run_with_namespace_handles_missing_theme_flag_without_actions() -> None: + args = argparse.Namespace(currencies=False, units=False, defaults=False) + config = mock.create_autospec(DatabaseConfig) + config.application_dsn.return_value = "postgresql://example" + + with ( + mock.patch("scripts.seed_data._configure_logging") as configure_logging, + mock.patch("scripts.seed_data.psycopg2.connect") as connect_mock, + mock.patch.object(seed_data.logger, "info") as info_mock, + ): + seed_data.run_with_namespace(args, config=config) + + configure_logging.assert_called_once() + connect_mock.assert_not_called() + info_mock.assert_called_with("No seeding options provided; exiting") + + +def test_run_with_namespace_seeds_defaults_without_theme_flag() -> None: + args = argparse.Namespace( + currencies=False, units=False, defaults=True, dry_run=False) + config = mock.create_autospec(DatabaseConfig) + config.application_dsn.return_value = "postgresql://example" + + connection_mock = mock.MagicMock() + cursor_context = mock.MagicMock() + cursor_mock = mock.MagicMock() + connection_mock.__enter__.return_value = connection_mock + connection_mock.cursor.return_value = cursor_context + cursor_context.__enter__.return_value = cursor_mock + + with ( + mock.patch("scripts.seed_data._configure_logging"), + mock.patch("scripts.seed_data.psycopg2.connect", return_value=connection_mock) as connect_mock, + mock.patch("scripts.seed_data._seed_defaults") as seed_defaults, + ): + seed_data.run_with_namespace(args, config=config) + + connect_mock.assert_called_once_with(config.application_dsn()) + seed_defaults.assert_called_once_with(cursor_mock, dry_run=False)