Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions flags/conditions/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from django.contrib.auth import get_user_model
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
from django.db import OperationalError, ProgrammingError
from django.utils import dateparse

from flags.utils import strtobool
Expand Down Expand Up @@ -45,6 +46,13 @@ def validate_user(value):
UserModel.objects.get(**{UserModel.USERNAME_FIELD: value})
except UserModel.DoesNotExist as err:
raise ValidationError("Enter the username of a valid user.") from err
except (OperationalError, ProgrammingError):
# The user table may not exist yet, for example when the system checks
# run during a migration against a fresh database (before the auth
# tables are created). The username cannot be checked in that case, so
# skip validation rather than letting the database error abort the
# migration.
pass


def validate_date(value):
Expand Down
16 changes: 16 additions & 0 deletions flags/tests/test_conditions_validators.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
from unittest import mock

from django.contrib.auth import get_user_model
from django.core.exceptions import ValidationError
from django.db import OperationalError, ProgrammingError
from django.test import TestCase, override_settings

from flags.conditions.validators import (
Expand Down Expand Up @@ -82,6 +85,19 @@ def test_custom_user_invalid(self):
with self.assertRaises(ValidationError):
validate_user("nottestuser")

def test_user_table_missing_is_skipped(self):
# If the user table does not exist yet (for example when the system
# checks run during a migration against a fresh database), the lookup
# raises a database error. Validation should be skipped rather than
# letting that error abort the migration. See GH-96.
User = get_user_model()
for exc in (OperationalError, ProgrammingError):
with mock.patch.object(
User.objects, "get", side_effect=exc("relation does not exist")
):
# Must not raise.
validate_user("testuser")


class ValidateDateTestCase(TestCase):
def test_invalid_date_strings(self):
Expand Down