'executor.detect_soft_applied() detects ManyToManyField tables from an
AddField operation. This checks the case of AddField in a migration
with other operations (0001) and the case of AddField in its own
migration (0002).'

@override_settings(MIGRATION_MODULES={'migrations': 'migrations.test_add_many_to_many_field_initial'})
def test_detect_soft_applied_add_field_manytomanyfield(self):

    tables = ['migrations_project', 'migrations_task', 'migrations_project_tasks', 'migrations_task_projects']
    executor = MigrationExecutor(connection)
    executor.migrate([('migrations', '0001_initial')])
    executor.migrate([('migrations', None)], fake=True)
    for table in tables[:3]:
        self.assertTableExists(table)
    migration = executor.loader.get_migration('migrations', '0001_initial')
    self.assertIs(executor.detect_soft_applied(None, migration)[0], True)
    migration = executor.loader.get_migration('migrations', '0002_initial')
    self.assertIs(executor.detect_soft_applied(None, migration)[0], False)
    executor.loader.build_graph()
    executor.migrate([('migrations', '0001_initial')], fake=True)
    executor.migrate([('migrations', '0002_initial')])
    executor.loader.build_graph()
    executor.migrate([('migrations', None)], fake=True)
    migration = executor.loader.get_migration('migrations', '0002_initial')
    self.assertIs(executor.detect_soft_applied(None, migration)[0], True)
    with connection.schema_editor() as editor:
        for table in tables[2:]:
            editor.execute((editor.sql_delete_table % {'table': table}))
    migration = executor.loader.get_migration('migrations', '0001_initial')
    self.assertIs(executor.detect_soft_applied(None, migration)[0], False)
    with connection.schema_editor() as editor:
        for table in tables[:2]:
            editor.execute((editor.sql_delete_table % {'table': table}))
    for table in tables:
        self.assertTableNotExists(table)
