import os import shutil from pathlib import Path from django.apps import apps from django.conf import settings from django.db import connection from django.db.migrations.executor import MigrationExecutor from django.test import TestCase, TransactionTestCase, override_settings from documents.models import Document from documents.parsers import get_default_file_extension from documents.tests.utils import DirectoriesMixin class TestMigrations(TransactionTestCase): @property def app(self): return apps.get_containing_app_config(type(self).__module__).name migrate_from = None migrate_to = None def setUp(self): super(TestMigrations, self).setUp() assert self.migrate_from and self.migrate_to, \ "TestCase '{}' must define migrate_from and migrate_to properties".format(type(self).__name__) self.migrate_from = [(self.app, self.migrate_from)] self.migrate_to = [(self.app, self.migrate_to)] executor = MigrationExecutor(connection) old_apps = executor.loader.project_state(self.migrate_from).apps # Reverse to the original migration executor.migrate(self.migrate_from) self.setUpBeforeMigration(old_apps) # Run the migration to test executor = MigrationExecutor(connection) executor.loader.build_graph() # reload. executor.migrate(self.migrate_to) self.apps = executor.loader.project_state(self.migrate_to).apps def setUpBeforeMigration(self, apps): pass STORAGE_TYPE_UNENCRYPTED = "unencrypted" STORAGE_TYPE_GPG = "gpg" def source_path_before(self): if self.filename: fname = str(self.filename) else: fname = "{:07}.{}".format(self.pk, self.file_type) if self.storage_type == STORAGE_TYPE_GPG: fname += ".gpg" return os.path.join( settings.ORIGINALS_DIR, fname ) def file_type_after(self): return get_default_file_extension(self.mime_type) def source_path_after(doc): if doc.filename: fname = str(doc.filename) else: fname = "{:07}{}".format(doc.pk, file_type_after(doc)) if doc.storage_type == STORAGE_TYPE_GPG: fname += ".gpg" # pragma: no cover return os.path.join( settings.ORIGINALS_DIR, fname ) @override_settings(PASSPHRASE="test") class TestMigrateMimeType(DirectoriesMixin, TestMigrations): migrate_from = '1002_auto_20201111_1105' migrate_to = '1003_mime_types' def setUpBeforeMigration(self, apps): Document = apps.get_model("documents", "Document") doc = Document.objects.create(title="test", file_type="pdf", filename="file1.pdf") self.doc_id = doc.id shutil.copy(os.path.join(os.path.dirname(__file__), "samples", "simple.pdf"), source_path_before(doc)) doc2 = Document.objects.create(checksum="B", file_type="pdf", storage_type=STORAGE_TYPE_GPG) self.doc2_id = doc2.id shutil.copy(os.path.join(os.path.dirname(__file__), "samples", "documents", "originals", "0000004.pdf.gpg"), source_path_before(doc2)) def testMimeTypesMigrated(self): Document = self.apps.get_model('documents', 'Document') doc = Document.objects.get(id=self.doc_id) self.assertEqual(doc.mime_type, "application/pdf") doc2 = Document.objects.get(id=self.doc2_id) self.assertEqual(doc2.mime_type, "application/pdf") @override_settings(PASSPHRASE="test") class TestMigrateMimeTypeBackwards(DirectoriesMixin, TestMigrations): migrate_from = '1003_mime_types' migrate_to = '1002_auto_20201111_1105' def setUpBeforeMigration(self, apps): Document = apps.get_model("documents", "Document") doc = Document.objects.create(title="test", mime_type="application/pdf", filename="file1.pdf") self.doc_id = doc.id shutil.copy(os.path.join(os.path.dirname(__file__), "samples", "simple.pdf"), source_path_after(doc)) def testMimeTypesReverted(self): Document = self.apps.get_model('documents', 'Document') doc = Document.objects.get(id=self.doc_id) self.assertEqual(doc.file_type, "pdf")