diff options
| author | Andrew Godwin <andrew@aeracode.org> | 2014-06-07 18:17:31 -0700 |
|---|---|---|
| committer | Andrew Godwin <andrew@aeracode.org> | 2014-06-07 18:18:18 -0700 |
| commit | b568bdf8da30fe5940a31add9f3a2b8029ecb04d (patch) | |
| tree | 3a967585f311e72c9bc9fb265a736dc7771e0dff /tests | |
| parent | 83fe38ae30fe6053f378c4adfc4387f2e8bd030c (diff) | |
[1.7.x] Fixed #22750, #22248: Model renaming now also alters field FKs
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/migrations/test_autodetector.py | 33 | ||||
| -rw-r--r-- | tests/migrations/test_base.py | 14 | ||||
| -rw-r--r-- | tests/migrations/test_operations.py | 58 |
3 files changed, 36 insertions, 69 deletions
diff --git a/tests/migrations/test_autodetector.py b/tests/migrations/test_autodetector.py index 629acbd610..6d163873ad 100644 --- a/tests/migrations/test_autodetector.py +++ b/tests/migrations/test_autodetector.py @@ -75,9 +75,7 @@ class AutodetectorTests(TestCase): return output def assertNumberMigrations(self, changes, app_label, number): - if not changes.get(app_label, None): - self.fail("No migrations found for %s\n%s" % (app_label, self.repr_changes(changes))) - if len(changes[app_label]) != number: + if len(changes.get(app_label, [])) != number: self.fail("Incorrect number of migrations (%s) for %s (expected %s)\n%s" % ( len(changes[app_label]), app_label, @@ -283,7 +281,7 @@ class AutodetectorTests(TestCase): changes = autodetector._detect_changes() # Right number of migrations for model rename? - self.assertEqual(len(changes['testapp']), 1) + self.assertNumberMigrations(changes, 'testapp', 1) # Right number of actions? migration = changes['testapp'][0] self.assertEqual(len(migration.operations), 1) @@ -292,17 +290,9 @@ class AutodetectorTests(TestCase): self.assertEqual(action.__class__.__name__, "RenameModel") self.assertEqual(action.old_name, "Author") self.assertEqual(action.new_name, "Writer") - - # Right number of migrations for related field rename? - self.assertEqual(len(changes['otherapp']), 1) - # Right number of actions? - migration = changes['otherapp'][0] - self.assertEqual(len(migration.operations), 1) - # Right action? - action = migration.operations[0] - self.assertEqual(action.__class__.__name__, "AlterField") - self.assertEqual(action.name, "author") - self.assertEqual(action.field.rel.to, "testapp.Writer") + # Now that RenameModel handles related fields too, there should be + # no AlterField for the related field. + self.assertNumberMigrations(changes, 'otherapp', 0) def test_rename_model_with_renamed_rel_field(self): """ @@ -314,9 +304,8 @@ class AutodetectorTests(TestCase): after = self.make_project_state([self.author_renamed_with_book, self.book_with_field_and_author_renamed]) autodetector = MigrationAutodetector(before, after, MigrationQuestioner({"ask_rename_model": True, "ask_rename": True})) changes = autodetector._detect_changes() - # Right number of migrations for model rename? - self.assertEqual(len(changes['testapp']), 1) + self.assertNumberMigrations(changes, 'testapp', 1) # Right number of actions? migration = changes['testapp'][0] self.assertEqual(len(migration.operations), 1) @@ -325,21 +314,17 @@ class AutodetectorTests(TestCase): self.assertEqual(action.__class__.__name__, "RenameModel") self.assertEqual(action.old_name, "Author") self.assertEqual(action.new_name, "Writer") - # Right number of migrations for related field rename? - self.assertEqual(len(changes['otherapp']), 1) + # Alter is already taken care of. + self.assertNumberMigrations(changes, 'otherapp', 1) # Right number of actions? migration = changes['otherapp'][0] - self.assertEqual(len(migration.operations), 2) + self.assertEqual(len(migration.operations), 1) # Right actions? action = migration.operations[0] self.assertEqual(action.__class__.__name__, "RenameField") self.assertEqual(action.old_name, "author") self.assertEqual(action.new_name, "writer") - action = migration.operations[1] - self.assertEqual(action.__class__.__name__, "AlterField") - self.assertEqual(action.name, "writer") - self.assertEqual(action.field.rel.to, "testapp.Writer") def test_fk_dependency(self): "Tests that having a ForeignKey automatically adds a dependency" diff --git a/tests/migrations/test_base.py b/tests/migrations/test_base.py index 2dba30b2aa..839929d087 100644 --- a/tests/migrations/test_base.py +++ b/tests/migrations/test_base.py @@ -46,3 +46,17 @@ class MigrationTestBase(TransactionTestCase): def assertIndexNotExists(self, table, columns): return self.assertIndexExists(table, columns, False) + + def assertFKExists(self, table, columns, to, value=True): + with connection.cursor() as cursor: + self.assertEqual( + value, + any( + c["foreign_key"] == to + for c in connection.introspection.get_constraints(cursor, table).values() + if c['columns'] == list(columns) + ), + ) + + def assertFKNotExists(self, table, columns, to, value=True): + return self.assertFKExists(table, columns, to, False) diff --git a/tests/migrations/test_operations.py b/tests/migrations/test_operations.py index 19d19e81b5..472d7b003e 100644 --- a/tests/migrations/test_operations.py +++ b/tests/migrations/test_operations.py @@ -245,68 +245,36 @@ class OperationTests(MigrationTestBase): """ Tests the RenameModel operation. """ - project_state = self.set_up_test_model("test_rnmo") + project_state = self.set_up_test_model("test_rnmo", related_model=True) # Test the state alteration operation = migrations.RenameModel("Pony", "Horse") new_state = project_state.clone() operation.state_forwards("test_rnmo", new_state) self.assertNotIn(("test_rnmo", "pony"), new_state.models) self.assertIn(("test_rnmo", "horse"), new_state.models) + # Remember, RenameModel also repoints all incoming FKs and M2Ms + self.assertEqual("test_rnmo.Horse", new_state.models["test_rnmo", "rider"].fields[1][1].rel.to) # Test the database alteration self.assertTableExists("test_rnmo_pony") self.assertTableNotExists("test_rnmo_horse") + if connection.features.supports_foreign_keys: + self.assertFKExists("test_rnmo_rider", ["pony_id"], ("test_rnmo_pony", "id")) + self.assertFKNotExists("test_rnmo_rider", ["pony_id"], ("test_rnmo_horse", "id")) with connection.schema_editor() as editor: operation.database_forwards("test_rnmo", editor, project_state, new_state) self.assertTableNotExists("test_rnmo_pony") self.assertTableExists("test_rnmo_horse") + if connection.features.supports_foreign_keys: + self.assertFKNotExists("test_rnmo_rider", ["pony_id"], ("test_rnmo_pony", "id")) + self.assertFKExists("test_rnmo_rider", ["pony_id"], ("test_rnmo_horse", "id")) # And test reversal with connection.schema_editor() as editor: operation.database_backwards("test_rnmo", editor, new_state, project_state) - self.assertTableExists("test_dlmo_pony") + self.assertTableExists("test_rnmo_pony") self.assertTableNotExists("test_rnmo_horse") - - # See #22248 - this will fail until that's fixed. - # - # def test_rename_model_with_related(self): - # """ - # Tests the real-world combo of a RenameModel operation with AlterField - # for a related field. - # """ - # project_state = self.set_up_test_model( - # "test_rnmowr", related_model=True) - # # Test the state alterations - # model_operation = migrations.RenameModel("Pony", "Horse") - # new_state = project_state.clone() - # model_operation.state_forwards("test_rnmowr", new_state) - # self.assertNotIn(("test_rnmowr", "pony"), new_state.models) - # self.assertIn(("test_rnmowr", "horse"), new_state.models) - - # self.assertEqual( - # "Pony", - # project_state.render().get_model("test_rnmowr", "rider") - # ._meta.get_field_by_name("pony")[0].rel.to._meta.object_name) - # field_operation = migrations.AlterField( - # "Rider", "pony", models.ForeignKey("Horse")) - # field_operation.state_forwards("test_rnmowr", new_state) - # self.assertEqual( - # "Horse", - # new_state.render().get_model("test_rnmowr", "rider") - # ._meta.get_field_by_name("pony")[0].rel.to._meta.object_name) - - # # Test the database alterations - # self.assertTableExists("test_rnmowr_pony") - # self.assertTableNotExists("test_rnmowr_horse") - # with connection.schema_editor() as editor: - # model_operation.database_forwards("test_rnmowr", editor, project_state, new_state) - # field_operation.database_forwards("test_rnmowr", editor, project_state, new_state) - # self.assertTableNotExists("test_rnmowr_pony") - # self.assertTableExists("test_rnmowr_horse") - # # And test reversal - # with connection.schema_editor() as editor: - # field_operation.database_backwards("test_rnmowr", editor, new_state, project_state) - # model_operation.database_backwards("test_rnmowr", editor, new_state, project_state) - # self.assertTableExists("test_rnmowr_pony") - # self.assertTableNotExists("test_rnmowr_horse") + if connection.features.supports_foreign_keys: + self.assertFKExists("test_rnmo_rider", ["pony_id"], ("test_rnmo_pony", "id")) + self.assertFKNotExists("test_rnmo_rider", ["pony_id"], ("test_rnmo_horse", "id")) def test_add_field(self): """ |
