From db7b11f2b42d07ec4a2ccd321e9af23b00ff2de3 Mon Sep 17 00:00:00 2001 From: Ryan Hiebert Date: Thu, 17 Jan 2019 14:14:28 -0600 Subject: [PATCH] Enforce that the safe property must be valid (#9) It is acceptable for the safe property to not be given, and get the default. However, if the safe property is given, then it must be set correctly. Enforce this by ensuring that the value we will use is part of the Safe enum. --- HISTORY.rst | 1 + .../management/commands/safemigrate.py | 13 +++++++++++++ tests/safemigrate_test.py | 12 ++++++++++++ 3 files changed, 26 insertions(+) diff --git a/HISTORY.rst b/HISTORY.rst index 7defad8..3a27fb9 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -17,6 +17,7 @@ because they don't require any database changes. * Multiple dependent ``Safe.after_deploy`` migrations do not block deployment as long as there are no dependent ``Safe.before_deploy`` migrations. +* Enforce that any given value of safe is valid. 1.0 (2019-01-13) ++++++++++++++++ diff --git a/src/django_safemigrate/management/commands/safemigrate.py b/src/django_safemigrate/management/commands/safemigrate.py index e42d75f..6694a8c 100644 --- a/src/django_safemigrate/management/commands/safemigrate.py +++ b/src/django_safemigrate/management/commands/safemigrate.py @@ -45,6 +45,19 @@ def pre_migrate_receiver(self, *, plan, **_): # Pull the migrations into a new list migrations = [migration for migration, backward in plan] + + # Check for invalid safe properties + invalid = [ + migration for migration in migrations if safety(migration) not in Safe + ] + if invalid: + self.stdout.write(self.style.MIGRATE_HEADING("Invalid migrations:")) + for migration in invalid: + self.stdout.write(f" {migration.app_label}.{migration.name}") + raise CommandError( + "Aborting due to migrations with invalid safe properties." + ) + protected = [ migration for migration in migrations diff --git a/tests/safemigrate_test.py b/tests/safemigrate_test.py index a1ed747..1cd4539 100644 --- a/tests/safemigrate_test.py +++ b/tests/safemigrate_test.py @@ -250,3 +250,15 @@ def test_blocked_by_after_nonstrict(self, settings, receiver): ] receiver(plan=plan) assert len(plan) == 1 + + def test_string_invalid(self, receiver): + """Invalid settings of the safe property will raise an error.""" + plan = [(Migration("spam", "0001_initial", safe="before_deploy"), False)] + with pytest.raises(CommandError): + receiver(plan=plan) + + def test_boolean_invalid(self, receiver): + """Booleans are invalid for the safe property.""" + plan = [(Migration("spam", "0001_initial", safe=False), False)] + with pytest.raises(CommandError): + receiver(plan=plan)