From aba75e73db6a0baca1b721698ca24f026bb4a745 Mon Sep 17 00:00:00 2001 From: Andrew Godwin Date: Wed, 9 Jul 2014 23:53:16 -0700 Subject: [1.7.x] Fixed #22970: Incorrect dependencies for existing migrated apps --- tests/migrations/models.py | 8 ++++ tests/migrations/test_autodetector.py | 43 +++++++++++++++++++++- .../test_migrations_no_changes/0003_third.py | 11 +++++- 3 files changed, 59 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/migrations/models.py b/tests/migrations/models.py index 87165ab6e3..fc063f5cb0 100644 --- a/tests/migrations/models.py +++ b/tests/migrations/models.py @@ -42,3 +42,11 @@ class UnserializableModel(models.Model): class Meta: # Disable auto loading of this model as we load it on our own apps = Apps() + + +class UnmigratedModel(models.Model): + """ + A model that is in a migration-less app (which this app is + if its migrations directory has not been repointed) + """ + pass diff --git a/tests/migrations/test_autodetector.py b/tests/migrations/test_autodetector.py index b2ea4187cf..667021d46f 100644 --- a/tests/migrations/test_autodetector.py +++ b/tests/migrations/test_autodetector.py @@ -4,7 +4,8 @@ from django.db.migrations.autodetector import MigrationAutodetector from django.db.migrations.questioner import MigrationQuestioner from django.db.migrations.state import ProjectState, ModelState from django.db.migrations.graph import MigrationGraph -from django.db import models +from django.db.migrations.loader import MigrationLoader +from django.db import models, connection from django.contrib.auth.models import AbstractBaseUser @@ -56,6 +57,7 @@ class AutodetectorTests(TestCase): third_thing = ModelState("thirdapp", "Thing", [("id", models.AutoField(primary_key=True))]) book = ModelState("otherapp", "Book", [("id", models.AutoField(primary_key=True)), ("author", models.ForeignKey("testapp.Author")), ("title", models.CharField(max_length=200))]) book_proxy_fk = ModelState("otherapp", "Book", [("id", models.AutoField(primary_key=True)), ("author", models.ForeignKey("thirdapp.AuthorProxy")), ("title", models.CharField(max_length=200))]) + book_migrations_fk = ModelState("otherapp", "Book", [("id", models.AutoField(primary_key=True)), ("author", models.ForeignKey("migrations.UnmigratedModel")), ("title", models.CharField(max_length=200))]) book_with_no_author = ModelState("otherapp", "Book", [("id", models.AutoField(primary_key=True)), ("title", models.CharField(max_length=200))]) book_with_author_renamed = ModelState("otherapp", "Book", [("id", models.AutoField(primary_key=True)), ("author", models.ForeignKey("testapp.Writer")), ("title", models.CharField(max_length=200))]) book_with_field_and_author_renamed = ModelState("otherapp", "Book", [("id", models.AutoField(primary_key=True)), ("writer", models.ForeignKey("testapp.Writer")), ("title", models.CharField(max_length=200))]) @@ -1005,3 +1007,42 @@ class AutodetectorTests(TestCase): self.assertOperationTypes(changes, 'testapp', 0, ["CreateModel", "CreateModel"]) self.assertOperationAttributes(changes, 'testapp', 0, 0, name="Author") self.assertOperationAttributes(changes, 'testapp', 0, 1, name="Aardvark") + + def test_first_dependency(self): + """ + Tests that a dependency to an app with no migrations uses __first__. + """ + # Load graph + loader = MigrationLoader(connection) + # Make state + before = self.make_project_state([]) + after = self.make_project_state([self.book_migrations_fk]) + after.real_apps = ["migrations"] + autodetector = MigrationAutodetector(before, after) + changes = autodetector._detect_changes(graph=loader.graph) + # Right number of migrations? + self.assertNumberMigrations(changes, 'otherapp', 1) + self.assertOperationTypes(changes, 'otherapp', 0, ["CreateModel"]) + self.assertOperationAttributes(changes, 'otherapp', 0, 0, name="Book") + # Right dependencies? + self.assertEqual(changes['otherapp'][0].dependencies, [("migrations", "__first__")]) + + @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations"}) + def test_last_dependency(self): + """ + Tests that a dependency to an app with existing migrations uses __first__. + """ + # Load graph + loader = MigrationLoader(connection) + # Make state + before = self.make_project_state([]) + after = self.make_project_state([self.book_migrations_fk]) + after.real_apps = ["migrations"] + autodetector = MigrationAutodetector(before, after) + changes = autodetector._detect_changes(graph=loader.graph) + # Right number of migrations? + self.assertNumberMigrations(changes, 'otherapp', 1) + self.assertOperationTypes(changes, 'otherapp', 0, ["CreateModel"]) + self.assertOperationAttributes(changes, 'otherapp', 0, 0, name="Book") + # Right dependencies? + self.assertEqual(changes['otherapp'][0].dependencies, [("migrations", "__last__")]) diff --git a/tests/migrations/test_migrations_no_changes/0003_third.py b/tests/migrations/test_migrations_no_changes/0003_third.py index f8f3db9386..2418bd5e9f 100644 --- a/tests/migrations/test_migrations_no_changes/0003_third.py +++ b/tests/migrations/test_migrations_no_changes/0003_third.py @@ -16,8 +16,15 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ], - options={ - }, + options={}, + bases=(models.Model,), + ), + migrations.CreateModel( + name='UnmigratedModel', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ], + options={}, bases=(models.Model,), ), migrations.DeleteModel( -- cgit v1.3