From 7bdd92410c2318b8035012b5b14e3350101ba4e0 Mon Sep 17 00:00:00 2001 From: Oliver Stolpe Date: Tue, 10 Sep 2024 16:20:08 +0200 Subject: [PATCH] feat: upgrade to sodar core v1 (#1973) --- backend/beaconsite/tests/test_views.py | 20 +- backend/cases_import/models/executors.py | 2 +- .../tests/test_models_executor.py | 2 +- backend/cases_qc/tests/test_views_api.py | 2 +- backend/genepanels/forms.py | 7 +- backend/genepanels/tests/test_models.py | 6 +- backend/genepanels/tests/test_views.py | 24 +- .../commands/create_variant_summary.py | 19 -- .../commands/drop_variant_summary.py | 19 -- backend/seqmeta/tests/test_models.py | 2 +- backend/seqmeta/tests/test_views.py | 8 +- backend/varannos/tests/test_models.py | 2 +- backend/varannos/tests/test_views.py | 6 +- .../users/management/commands/initdev.py | 2 +- .../migrations/0110_drop_variant_summary.py | 103 ++++++ .../migrations/0111_create_variant_summary.py | 80 +++++ backend/variants/tests/helpers.py | 2 +- .../variants/tests/test_views_ajax_presets.py | 299 +++++++----------- utils/docker/docker-entrypoint.sh | 2 - 19 files changed, 347 insertions(+), 260 deletions(-) delete mode 100644 backend/maintenance/management/commands/create_variant_summary.py delete mode 100644 backend/maintenance/management/commands/drop_variant_summary.py create mode 100644 backend/variants/migrations/0110_drop_variant_summary.py create mode 100644 backend/variants/migrations/0111_create_variant_summary.py diff --git a/backend/beaconsite/tests/test_views.py b/backend/beaconsite/tests/test_views.py index 4966a2998..8cb08bac7 100644 --- a/backend/beaconsite/tests/test_views.py +++ b/backend/beaconsite/tests/test_views.py @@ -4,10 +4,10 @@ from django.urls import reverse from beaconsite.models import Consortium, Site -from variants.tests.helpers import ViewTestBase +from variants.tests.helpers import TestViewsBase -class TestIndexView(ViewTestBase): +class TestIndexView(TestViewsBase): def test_render(self): with self.login(self.superuser): response = self.client.get(reverse("beaconsite:index")) @@ -18,7 +18,7 @@ def test_render(self): self.assertEqual(response.context["site_list"][0].pk, self.site.pk) -class TestConsortiumListView(ViewTestBase): +class TestConsortiumListView(TestViewsBase): def test_render(self): with self.login(self.superuser): response = self.client.get(reverse("beaconsite:consortium-list")) @@ -27,7 +27,7 @@ def test_render(self): self.assertEqual(response.context["object_list"][0].pk, self.consortium.pk) -class TestConsortiumCreateView(ViewTestBase): +class TestConsortiumCreateView(TestViewsBase): def test_render(self): with self.login(self.superuser): response = self.client.get(reverse("beaconsite:consortium-create")) @@ -60,7 +60,7 @@ def test_create(self): self.assertEqual(Consortium.objects.count(), 2) -class TestConsortiumUpdateView(ViewTestBase): +class TestConsortiumUpdateView(TestViewsBase): def test_render(self): with self.login(self.superuser): response = self.client.get( @@ -110,7 +110,7 @@ def test_update(self): self.assertEqual([self.project.pk], [p.pk for p in self.consortium.projects.all()]) -class TestConsortiumDeleteView(ViewTestBase): +class TestConsortiumDeleteView(TestViewsBase): def test_render(self): with self.login(self.superuser): response = self.client.get( @@ -139,7 +139,7 @@ def test_delete(self): self.assertEqual(Consortium.objects.all().count(), 0) -class TestSiteListView(ViewTestBase): +class TestSiteListView(TestViewsBase): def test_render(self): with self.login(self.superuser): response = self.client.get(reverse("beaconsite:site-list")) @@ -148,7 +148,7 @@ def test_render(self): self.assertEqual(response.context["object_list"][0].pk, self.site.pk) -class TestSiteCreateView(ViewTestBase): +class TestSiteCreateView(TestViewsBase): def test_render(self): with self.login(self.superuser): response = self.client.get(reverse("beaconsite:site-create")) @@ -184,7 +184,7 @@ def test_create(self): self.assertEqual(Site.objects.count(), 2) -class TestSiteUpdateView(ViewTestBase): +class TestSiteUpdateView(TestViewsBase): def test_render(self): with self.login(self.superuser): response = self.client.get( @@ -246,7 +246,7 @@ def test_update(self): self.assertEqual([self.consortium.pk], [s.pk for s in self.site.consortia.all()]) -class TestSiteDeleteView(ViewTestBase): +class TestSiteDeleteView(TestViewsBase): def test_render(self): with self.login(self.superuser): response = self.client.get( diff --git a/backend/cases_import/models/executors.py b/backend/cases_import/models/executors.py index f539cfc3d..512f8cd7b 100644 --- a/backend/cases_import/models/executors.py +++ b/backend/cases_import/models/executors.py @@ -136,7 +136,7 @@ def __init__(self, project: Project): def _build_fs_options(self, project: Project) -> FileSystemOptions: """Build `FileSystemOptions` from project settings.""" app_settings = AppSettingAPI() - kwargs = {"app_name": "cases_import", "project": project} + kwargs = {"plugin_name": "cases_import", "project": project} path = app_settings.get(setting_name="import_data_path", **kwargs) or None if not path: diff --git a/backend/cases_import/tests/test_models_executor.py b/backend/cases_import/tests/test_models_executor.py index 51eb40ad9..1abac3c63 100644 --- a/backend/cases_import/tests/test_models_executor.py +++ b/backend/cases_import/tests/test_models_executor.py @@ -51,7 +51,7 @@ def _setUpExecutor(self, action, fac_kwargs=None): app_settings = AppSettingAPI() app_settings.set( - app_name="cases_import", + plugin_name="cases_import", setting_name="import_data_protocol", value="file", project=self.project, diff --git a/backend/cases_qc/tests/test_views_api.py b/backend/cases_qc/tests/test_views_api.py index ada8e82e4..87eccfc84 100644 --- a/backend/cases_qc/tests/test_views_api.py +++ b/backend/cases_qc/tests/test_views_api.py @@ -91,7 +91,7 @@ def _setUpExecutor(self, fac_kwargs: typing.Dict[str, str]): app_settings = AppSettingAPI() app_settings.set( - app_name="cases_import", + plugin_name="cases_import", setting_name="import_data_protocol", value="file", project=self.project, diff --git a/backend/genepanels/forms.py b/backend/genepanels/forms.py index 436638c50..491435849 100644 --- a/backend/genepanels/forms.py +++ b/backend/genepanels/forms.py @@ -24,8 +24,11 @@ def __init__(self, *args, **kwargs): self.fields["genes"] = self._build_genes_field() def _build_genes_field(self): - rows = [entry.symbol for entry in self.instance.genepanelentry_set.all()] - initial_value = "\n".join(rows) + if self.instance.pk: + rows = [entry.symbol for entry in self.instance.genepanelentry_set.all()] + initial_value = "\n".join(rows) + else: + initial_value = "" return forms.CharField( label="Genes", widget=forms.Textarea, diff --git a/backend/genepanels/tests/test_models.py b/backend/genepanels/tests/test_models.py index 2380cf354..4d18a3725 100644 --- a/backend/genepanels/tests/test_models.py +++ b/backend/genepanels/tests/test_models.py @@ -24,7 +24,9 @@ def test_create(self): def test_get_absolute_url(self): category = GenePanelCategoryFactory() - self.assertEqual(category.get_absolute_url(), f"/genepanels/category/{category.sodar_uuid}") + self.assertEqual( + category.get_absolute_url(), f"/genepanels/category/{category.sodar_uuid}/" + ) def test_str(self): category = GenePanelCategoryFactory() @@ -46,7 +48,7 @@ def test_create(self): def test_get_absolute_url(self): panel = GenePanelFactory() - self.assertEqual(panel.get_absolute_url(), f"/genepanels/panel/{panel.sodar_uuid}") + self.assertEqual(panel.get_absolute_url(), f"/genepanels/panel/{panel.sodar_uuid}/") def test_get_hgnc_list(self): panel = GenePanelFactory() diff --git a/backend/genepanels/tests/test_views.py b/backend/genepanels/tests/test_views.py index d20fd094d..59701a09b 100644 --- a/backend/genepanels/tests/test_views.py +++ b/backend/genepanels/tests/test_views.py @@ -10,7 +10,7 @@ GenePanelEntryFactory, GenePanelFactory, ) -from variants.tests.helpers import ViewTestBase +from variants.tests.helpers import TestViewsBase ANNONARS_GENE_RESPONSE = { "TTN": { @@ -54,7 +54,7 @@ def _set_annonars_mocker(self, mock_): ) -class IndexViewTest(ViewTestBase): +class IndexViewTest(TestViewsBase): def setUp(self): super().setUp() self.panel = GenePanelFactory() @@ -67,7 +67,7 @@ def test_render(self): self.assertEquals(response.context["show_retired"], False) -class GenePanelCategoryListView(ViewTestBase): +class GenePanelCategoryListView(TestViewsBase): def setUp(self): super().setUp() self.panel = GenePanelFactory() @@ -88,7 +88,7 @@ def test_render_show_retired(self): self.assertEquals(response.context["show_retired"], True) -class GenePanelCategoryCreateView(ViewTestBase): +class GenePanelCategoryCreateView(TestViewsBase): def test_render(self): with self.login(self.superuser): response = self.client.get(reverse("genepanels:category-create")) @@ -117,7 +117,7 @@ def test_create(self): self.assertEqual(GenePanelCategory.objects.count(), 1) -class GenePanelCategoryUpdateView(ViewTestBase): +class GenePanelCategoryUpdateView(TestViewsBase): def setUp(self): super().setUp() self.panel = GenePanelFactory() @@ -164,7 +164,7 @@ def test_update(self): self.assertEqual(getattr(self.category, key), post_data[key]) -class GenePanelCategoryDeleteView(ViewTestBase): +class GenePanelCategoryDeleteView(TestViewsBase): def setUp(self): super().setUp() self.category = GenePanelCategoryFactory() @@ -197,7 +197,7 @@ def test_delete(self): self.assertEqual(GenePanelCategory.objects.all().count(), 0) -class GenePanelCreateView(AnnonarsMockerMixin, ViewTestBase): +class GenePanelCreateView(AnnonarsMockerMixin, TestViewsBase): def setUp(self): super().setUp() self.category = GenePanelCategoryFactory() @@ -300,7 +300,7 @@ def test_create_with_gene_list_including_nonexistent_gene(self, mock): ) -class GenePanelUpdateView(AnnonarsMockerMixin, ViewTestBase): +class GenePanelUpdateView(AnnonarsMockerMixin, TestViewsBase): def setUp(self): super().setUp() self.panel = GenePanelFactory(state=GenePanelState.DRAFT.value) @@ -356,7 +356,7 @@ def test_update(self, mock): self.assertEqual(self.panel.category, self.category) -class GenePanelDeleteView(ViewTestBase): +class GenePanelDeleteView(TestViewsBase): def setUp(self): super().setUp() self.panel = GenePanelFactory(state=GenePanelState.DRAFT.value) @@ -437,7 +437,7 @@ def test_post_non_draft_state(self, state): self.assertEqual(GenePanel.objects.count(), 1) -class GenePanelReleaseView(ViewTestBase): +class GenePanelReleaseView(TestViewsBase): def setUp(self): super().setUp() self.panel = GenePanelFactory(state=GenePanelState.DRAFT.value, version_minor=2) @@ -527,7 +527,7 @@ def test_post_non_draft_state(self, state): self.assertEqual(self.old_panel.state, GenePanelState.ACTIVE.value) -class GenePanelRetireView(ViewTestBase): +class GenePanelRetireView(TestViewsBase): def setUp(self): super().setUp() self.panel = GenePanelFactory(state=GenePanelState.ACTIVE.value, version_minor=2) @@ -608,7 +608,7 @@ def test_post_non_active_state(self, state): self.assertEqual(self.panel.state, state) -class GenePanelCopyAsDraftView(ViewTestBase): +class GenePanelCopyAsDraftView(TestViewsBase): def setUp(self): super().setUp() self.panel = GenePanelFactory(state=GenePanelState.ACTIVE.value, version_minor=2) diff --git a/backend/maintenance/management/commands/create_variant_summary.py b/backend/maintenance/management/commands/create_variant_summary.py deleted file mode 100644 index 9b730a0ff..000000000 --- a/backend/maintenance/management/commands/create_variant_summary.py +++ /dev/null @@ -1,19 +0,0 @@ -"""Django command for creating the variant summary.""" - -from django.core.management.base import BaseCommand -from django.db import transaction - -import variants.models as models - - -class Command(BaseCommand): - """Implementation of creating variant summary.""" - - #: Help message displayed on the command line. - help = "Create the variants summary." - - @transaction.atomic - def handle(self, *args, **options): - """Perform creating the statistics.""" - models.create_variants_smallvariantsummary() - self.stdout.write(self.style.SUCCESS("Done creating variant summary.")) diff --git a/backend/maintenance/management/commands/drop_variant_summary.py b/backend/maintenance/management/commands/drop_variant_summary.py deleted file mode 100644 index 8e0ed407f..000000000 --- a/backend/maintenance/management/commands/drop_variant_summary.py +++ /dev/null @@ -1,19 +0,0 @@ -"""Django command for dropping the variant summary.""" - -from django.core.management.base import BaseCommand -from django.db import transaction - -import variants.models as models - - -class Command(BaseCommand): - """Implementation of dropping variant summary.""" - - #: Help message displayed on the command line. - help = "Drop the variants summary." - - @transaction.atomic - def handle(self, *args, **options): - """Perform dropping the statistics.""" - models.drop_variants_smallvariantsummary() - self.stdout.write(self.style.SUCCESS("Done dropping variant summary.")) diff --git a/backend/seqmeta/tests/test_models.py b/backend/seqmeta/tests/test_models.py index 96acef346..22492066e 100644 --- a/backend/seqmeta/tests/test_models.py +++ b/backend/seqmeta/tests/test_models.py @@ -12,7 +12,7 @@ def test_create(self): def test_get_absolute_url(self): kit = EnrichmentKitFactory() - self.assertEqual(kit.get_absolute_url(), f"/seqmeta/enrichmentkit/{kit.sodar_uuid}") + self.assertEqual(kit.get_absolute_url(), f"/seqmeta/enrichmentkit/{kit.sodar_uuid}/") def test_str(self): kit = EnrichmentKitFactory() diff --git a/backend/seqmeta/tests/test_views.py b/backend/seqmeta/tests/test_views.py index 74d2ea2bb..6dd4e0af3 100644 --- a/backend/seqmeta/tests/test_views.py +++ b/backend/seqmeta/tests/test_views.py @@ -1,10 +1,10 @@ from django.urls import reverse from seqmeta.tests.factories import TargetBedFileFactory -from variants.tests.helpers import ViewTestBase +from variants.tests.helpers import TestViewsBase -class IndexViewTest(ViewTestBase): +class IndexViewTest(TestViewsBase): def setUp(self): super().setUp() self.targetbedfile = TargetBedFileFactory() @@ -17,7 +17,7 @@ def test_render(self): self.assertEqual(response.context["object_list"].count(), 1) -class EnrichmentKitListViewTest(ViewTestBase): +class EnrichmentKitListViewTest(TestViewsBase): def setUp(self): super().setUp() self.targetbedfile = TargetBedFileFactory() @@ -30,7 +30,7 @@ def test_render(self): self.assertEqual(response.context["object_list"].count(), 1) -class EnrichmentKitDetailView(ViewTestBase): +class EnrichmentKitDetailView(TestViewsBase): def setUp(self): super().setUp() self.targetbedfile = TargetBedFileFactory() diff --git a/backend/varannos/tests/test_models.py b/backend/varannos/tests/test_models.py index bea8b47b9..4567fe96b 100644 --- a/backend/varannos/tests/test_models.py +++ b/backend/varannos/tests/test_models.py @@ -17,7 +17,7 @@ def test_create(self): def test_get_absolute_url(self): obj = VarAnnoSetFactory() - self.assertEqual(obj.get_absolute_url(), f"/varannos/varannoset/details/{obj.sodar_uuid}") + self.assertEqual(obj.get_absolute_url(), f"/varannos/varannoset/details/{obj.sodar_uuid}/") def test_days_since_modification(self): with freeze_time((datetime.now() - timedelta(days=10)).strftime("%Y-%m-%d")): diff --git a/backend/varannos/tests/test_views.py b/backend/varannos/tests/test_views.py index f564fc875..833fbdd8a 100644 --- a/backend/varannos/tests/test_views.py +++ b/backend/varannos/tests/test_views.py @@ -1,10 +1,10 @@ from django.urls import reverse from varannos.tests.factories import VarAnnoSetFactory -from variants.tests.helpers import ViewTestBase +from variants.tests.helpers import TestViewsBase -class TestVarAnnoSetListView(ViewTestBase): +class TestVarAnnoSetListView(TestViewsBase): def setUp(self): super().setUp() self.varannoset = VarAnnoSetFactory(project=self.project) @@ -18,7 +18,7 @@ def test_render(self): self.assertIsNotNone(response.context["object_list"]) -class TestVarAnnoSetDetailView(ViewTestBase): +class TestVarAnnoSetDetailView(TestViewsBase): def setUp(self): super().setUp() self.varannoset = VarAnnoSetFactory(project=self.project) diff --git a/backend/varfish/users/management/commands/initdev.py b/backend/varfish/users/management/commands/initdev.py index 8424e45b5..e9e0cff02 100644 --- a/backend/varfish/users/management/commands/initdev.py +++ b/backend/varfish/users/management/commands/initdev.py @@ -282,7 +282,7 @@ def _create_project( for setting_name, value in setting_value.items(): if project_settings.get(setting_name) != value: app_settings.set( - app_name="cases_import", + plugin_name="cases_import", setting_name=setting_name, value=value, project=project, diff --git a/backend/variants/migrations/0110_drop_variant_summary.py b/backend/variants/migrations/0110_drop_variant_summary.py new file mode 100644 index 000000000..845f16ee5 --- /dev/null +++ b/backend/variants/migrations/0110_drop_variant_summary.py @@ -0,0 +1,103 @@ +# Generated by Django 4.2.16 on 2024-10-09 13:00 + +from django.db import connection, migrations, utils +from django.db.migrations.recorder import MigrationRecorder + + +def is_migration_applied(app_name, migration_name): + recorder = MigrationRecorder(connection) + try: + return recorder.migration_qs.filter(app=app_name, name=migration_name).exists() + except utils.ProgrammingError: + return False # migration table does not exist yet + + +if not is_migration_applied("projectroles", "0001_initial"): + run_before = [] # fresh installation, will run projectroles squashed migrations +elif is_migration_applied("projectroles", "0032_alter_appsetting_value"): + run_before = [] # critical projectroles migration already applied +else: + # We will not execute the squashed projectroles migration 0001..0032 and the + # projectroles migration 0032 has not been applied yet. + run_before = [ + ("projectroles", "0032_alter_appsetting_value"), + ] + + +SQL_OUTER = r""" +DROP MATERIALIZED VIEW IF EXISTS variants_smallvariantsummary; + +CREATE MATERIALIZED VIEW variants_smallvariantsummary +AS + %s +WITH NO DATA; + +CREATE UNIQUE INDEX variants_smallvariantsummary_id ON variants_smallvariantsummary(id); +CREATE INDEX variants_smallvariantsummary_coord ON variants_smallvariantsummary( + release, chromosome, start, "end", bin, reference, alternative +); +""" + + +SQL_INNER = r""" +WITH excluded_case_ids AS ( + SELECT DISTINCT variants_case.id AS case_id + FROM variants_case + JOIN projectroles_project ON variants_case.project_id = projectroles_project.id + JOIN projectroles_appsetting ON + projectroles_project.id = projectroles_appsetting.project_id AND + projectroles_appsetting.name = 'exclude_from_inhouse_db' AND + projectroles_appsetting.value = '1' +) +SELECT + row_number() OVER (PARTITION BY true) AS id, + release, + chromosome, + start, + "end", + bin, + reference, + alternative, + sum(num_hom_ref) AS count_hom_ref, + sum(num_het) AS count_het, + sum(num_hom_alt) AS count_hom_alt, + sum(num_hemi_ref) AS count_hemi_ref, + sum(num_hemi_alt) AS count_hemi_alt +FROM ( + SELECT DISTINCT + variants.release, + variants.chromosome, + variants.start, + variants."end", + variants.bin, + variants.reference, + variants.alternative, + variants.num_hom_ref, + variants.num_het, + variants.num_hom_alt, + variants.num_hemi_ref, + variants.num_hemi_alt, + variants.case_id + FROM variants_smallvariant AS variants + WHERE NOT EXISTS (SELECT 1 from excluded_case_ids AS e WHERE e.case_id = variants.case_id) +) AS variants_per_case +GROUP BY (release, chromosome, start, "end", bin, reference, alternative) +""" + + +class Migration(migrations.Migration): + + dependencies = [ + ("variants", "0109_alter_clearexpiredexportedfilesbgjob_bg_job_and_more"), + ] + + run_before = run_before + + operations = [ + migrations.RunSQL( + """ + DROP MATERIALIZED VIEW IF EXISTS variants_smallvariantsummary; + """, + SQL_OUTER % SQL_INNER, + ) + ] diff --git a/backend/variants/migrations/0111_create_variant_summary.py b/backend/variants/migrations/0111_create_variant_summary.py new file mode 100644 index 000000000..76294c0ac --- /dev/null +++ b/backend/variants/migrations/0111_create_variant_summary.py @@ -0,0 +1,80 @@ +# Generated by Django 4.2.16 on 2024-10-09 13:00 + +from django.db import migrations + +SQL_OUTER = r""" +DROP MATERIALIZED VIEW IF EXISTS variants_smallvariantsummary; + +CREATE MATERIALIZED VIEW variants_smallvariantsummary +AS + %s +WITH NO DATA; + +CREATE UNIQUE INDEX variants_smallvariantsummary_id ON variants_smallvariantsummary(id); +CREATE INDEX variants_smallvariantsummary_coord ON variants_smallvariantsummary( + release, chromosome, start, "end", bin, reference, alternative +); +""" + + +SQL_INNER = r""" +WITH excluded_case_ids AS ( + SELECT DISTINCT variants_case.id AS case_id + FROM variants_case + JOIN projectroles_project ON variants_case.project_id = projectroles_project.id + JOIN projectroles_appsetting ON + projectroles_project.id = projectroles_appsetting.project_id AND + projectroles_appsetting.name = 'exclude_from_inhouse_db' AND + projectroles_appsetting.value = '1' +) +SELECT + row_number() OVER (PARTITION BY true) AS id, + release, + chromosome, + start, + "end", + bin, + reference, + alternative, + sum(num_hom_ref) AS count_hom_ref, + sum(num_het) AS count_het, + sum(num_hom_alt) AS count_hom_alt, + sum(num_hemi_ref) AS count_hemi_ref, + sum(num_hemi_alt) AS count_hemi_alt +FROM ( + SELECT DISTINCT + variants.release, + variants.chromosome, + variants.start, + variants."end", + variants.bin, + variants.reference, + variants.alternative, + variants.num_hom_ref, + variants.num_het, + variants.num_hom_alt, + variants.num_hemi_ref, + variants.num_hemi_alt, + variants.case_id + FROM variants_smallvariant AS variants + WHERE NOT EXISTS (SELECT 1 from excluded_case_ids AS e WHERE e.case_id = variants.case_id) +) AS variants_per_case +GROUP BY (release, chromosome, start, "end", bin, reference, alternative) +""" + + +class Migration(migrations.Migration): + + dependencies = [ + ("variants", "0110_drop_variant_summary"), + ("projectroles", "0032_alter_appsetting_value"), + ] + + operations = [ + migrations.RunSQL( + SQL_OUTER % SQL_INNER, + """ + DROP MATERIALIZED VIEW IF EXISTS variants_smallvariantsummary; + """, + ) + ] diff --git a/backend/variants/tests/helpers.py b/backend/variants/tests/helpers.py index d4821d8d4..89f6a61d4 100644 --- a/backend/variants/tests/helpers.py +++ b/backend/variants/tests/helpers.py @@ -155,7 +155,7 @@ def run_count_query( return result -class ViewTestBase(TestCase): +class TestViewsBase(TestCase): def setUp(self): self.superuser = self.make_user("superuser") self.superuser.is_superuser = True diff --git a/backend/variants/tests/test_views_ajax_presets.py b/backend/variants/tests/test_views_ajax_presets.py index 6b4a2bf32..dba76f253 100644 --- a/backend/variants/tests/test_views_ajax_presets.py +++ b/backend/variants/tests/test_views_ajax_presets.py @@ -1,5 +1,3 @@ -from unittest.mock import MagicMock, patch - from django.conf import settings from django.urls import reverse from projectroles.tests.test_permissions_api import ProjectAPIPermissionTestBase @@ -121,20 +119,16 @@ def setUp(self): def test_post(self): data = {"presetset": self.presetset.sodar_uuid, "label": "my label"} - with patch( - "variants.models.presets.FrequencyPresetsManager.create_as_copy_of_factory_preset", - MagicMock(return_value=FrequencyPresetsFactory.build()), - ) as mock_create: - with self.login(self.superuser): - response = self.client.post( - reverse( - "variants:ajax-frequencypresets-clonefactorypresets", - kwargs={"name": "the-name"}, - ), - data=data, - ) + with self.login(self.superuser): + response = self.client.post( + reverse( + "variants:ajax-frequencypresets-clonefactorypresets", + kwargs={"name": "the-name"}, + ), + data=data, + ) self.assertEqual(response.status_code, 201) - mock_create.assert_called_with("the-name", data["label"], self.presetset) + self.assertEqual(response.json()["presetset"], str(self.presetset.sodar_uuid)) class TestFrequencyPresetsCloneOtherAjaxView(ApiViewTestBase): @@ -149,22 +143,16 @@ def test_post(self): "presetset": self.presetset.sodar_uuid, "label": "my label", } - with patch( - "variants.models.presets.FrequencyPresetsManager.create_as_copy_of_other_preset", - MagicMock(return_value=FrequencyPresetsFactory.build()), - ) as mock_create: - with self.login(self.superuser): - response = self.client.post( - reverse( - "variants:ajax-frequencypresets-cloneother", - kwargs={"frequencypresets": self.frequencypresets.sodar_uuid}, - ), - data=data, - ) + with self.login(self.superuser): + response = self.client.post( + reverse( + "variants:ajax-frequencypresets-cloneother", + kwargs={"frequencypresets": self.frequencypresets.sodar_uuid}, + ), + data=data, + ) self.assertEqual(response.status_code, 201) - mock_create.assert_called_with( - self.frequencypresets, presetset=self.presetset, label=data["label"] - ) + self.assertEqual(response.json()["presetset"], str(self.presetset.sodar_uuid)) class TestImpactPresetsListCreateAjaxView(ApiViewTestBase): @@ -253,20 +241,16 @@ def setUp(self): def test_post(self): data = {"presetset": self.presetset.sodar_uuid, "label": "my label"} - with patch( - "variants.models.presets.ImpactPresetsManager.create_as_copy_of_factory_preset", - MagicMock(return_value=ImpactPresetsFactory.build()), - ) as mock_create: - with self.login(self.superuser): - response = self.client.post( - reverse( - "variants:ajax-impactpresets-clonefactorypresets", - kwargs={"name": "the-name"}, - ), - data=data, - ) + with self.login(self.superuser): + response = self.client.post( + reverse( + "variants:ajax-impactpresets-clonefactorypresets", + kwargs={"name": "the-name"}, + ), + data=data, + ) self.assertEqual(response.status_code, 201) - mock_create.assert_called_with("the-name", data["label"], self.presetset) + self.assertEqual(response.json()["presetset"], str(self.presetset.sodar_uuid)) class TestImpactPresetsCloneOtherAjaxView(ApiViewTestBase): @@ -281,22 +265,16 @@ def test_post(self): "presetset": self.presetset.sodar_uuid, "label": "my label", } - with patch( - "variants.models.presets.ImpactPresetsManager.create_as_copy_of_other_preset", - MagicMock(return_value=ImpactPresetsFactory.build()), - ) as mock_create: - with self.login(self.superuser): - response = self.client.post( - reverse( - "variants:ajax-impactpresets-cloneother", - kwargs={"impactpresets": self.impactpresets.sodar_uuid}, - ), - data=data, - ) + with self.login(self.superuser): + response = self.client.post( + reverse( + "variants:ajax-impactpresets-cloneother", + kwargs={"impactpresets": self.impactpresets.sodar_uuid}, + ), + data=data, + ) self.assertEqual(response.status_code, 201) - mock_create.assert_called_with( - self.impactpresets, presetset=self.presetset, label=data["label"] - ) + self.assertEqual(response.json()["presetset"], str(self.presetset.sodar_uuid)) class TestQualityPresetsListCreateAjaxView(ApiViewTestBase): @@ -385,20 +363,16 @@ def setUp(self): def test_post(self): data = {"presetset": self.presetset.sodar_uuid, "label": "my label"} - with patch( - "variants.models.presets.QualityPresetsManager.create_as_copy_of_factory_preset", - MagicMock(return_value=QualityPresetsFactory.build()), - ) as mock_create: - with self.login(self.superuser): - response = self.client.post( - reverse( - "variants:ajax-qualitypresets-clonefactorypresets", - kwargs={"name": "the-name"}, - ), - data=data, - ) + with self.login(self.superuser): + response = self.client.post( + reverse( + "variants:ajax-qualitypresets-clonefactorypresets", + kwargs={"name": "the-name"}, + ), + data=data, + ) self.assertEqual(response.status_code, 201) - mock_create.assert_called_with("the-name", data["label"], self.presetset) + self.assertEqual(response.json()["presetset"], str(self.presetset.sodar_uuid)) class TestQualityPresetsCloneOtherAjaxView(ApiViewTestBase): @@ -413,22 +387,16 @@ def test_post(self): "presetset": self.presetset.sodar_uuid, "label": "my label", } - with patch( - "variants.models.presets.QualityPresetsManager.create_as_copy_of_other_preset", - MagicMock(return_value=QualityPresetsFactory.build()), - ) as mock_create: - with self.login(self.superuser): - response = self.client.post( - reverse( - "variants:ajax-qualitypresets-cloneother", - kwargs={"qualitypresets": self.qualitypresets.sodar_uuid}, - ), - data=data, - ) + with self.login(self.superuser): + response = self.client.post( + reverse( + "variants:ajax-qualitypresets-cloneother", + kwargs={"qualitypresets": self.qualitypresets.sodar_uuid}, + ), + data=data, + ) self.assertEqual(response.status_code, 201) - mock_create.assert_called_with( - self.qualitypresets, presetset=self.presetset, label=data["label"] - ) + self.assertEqual(response.json()["presetset"], str(self.presetset.sodar_uuid)) class TestChromosomePresetsListCreateAjaxView(ApiViewTestBase): @@ -517,20 +485,16 @@ def setUp(self): def test_post(self): data = {"presetset": self.presetset.sodar_uuid, "label": "my label"} - with patch( - "variants.models.presets.ChromosomePresetsManager.create_as_copy_of_factory_preset", - MagicMock(return_value=ChromosomePresetsFactory.build()), - ) as mock_create: - with self.login(self.superuser): - response = self.client.post( - reverse( - "variants:ajax-chromosomepresets-clonefactorypresets", - kwargs={"name": "the-name"}, - ), - data=data, - ) + with self.login(self.superuser): + response = self.client.post( + reverse( + "variants:ajax-chromosomepresets-clonefactorypresets", + kwargs={"name": "the-name"}, + ), + data=data, + ) self.assertEqual(response.status_code, 201) - mock_create.assert_called_with("the-name", data["label"], self.presetset) + self.assertEqual(response.json()["presetset"], str(self.presetset.sodar_uuid)) class TestChromosomePresetsCloneOtherAjaxView(ApiViewTestBase): @@ -545,22 +509,16 @@ def test_post(self): "presetset": self.presetset.sodar_uuid, "label": "my label", } - with patch( - "variants.models.presets.ChromosomePresetsManager.create_as_copy_of_other_preset", - MagicMock(return_value=ChromosomePresetsFactory.build()), - ) as mock_create: - with self.login(self.superuser): - response = self.client.post( - reverse( - "variants:ajax-chromosomepresets-cloneother", - kwargs={"chromosomepresets": self.chromosomepresets.sodar_uuid}, - ), - data=data, - ) + with self.login(self.superuser): + response = self.client.post( + reverse( + "variants:ajax-chromosomepresets-cloneother", + kwargs={"chromosomepresets": self.chromosomepresets.sodar_uuid}, + ), + data=data, + ) self.assertEqual(response.status_code, 201) - mock_create.assert_called_with( - self.chromosomepresets, presetset=self.presetset, label=data["label"] - ) + self.assertEqual(response.json()["presetset"], str(self.presetset.sodar_uuid)) class TestFlagsEtcPresetsListCreateAjaxView(ApiViewTestBase): @@ -649,20 +607,16 @@ def setUp(self): def test_post(self): data = {"presetset": self.presetset.sodar_uuid, "label": "my label"} - with patch( - "variants.models.presets.FlagsEtcPresetsManager.create_as_copy_of_factory_preset", - MagicMock(return_value=FlagsEtcPresetsFactory.build()), - ) as mock_create: - with self.login(self.superuser): - response = self.client.post( - reverse( - "variants:ajax-flagsetcpresets-clonefactorypresets", - kwargs={"name": "the-name"}, - ), - data=data, - ) + with self.login(self.superuser): + response = self.client.post( + reverse( + "variants:ajax-flagsetcpresets-clonefactorypresets", + kwargs={"name": "the-name"}, + ), + data=data, + ) self.assertEqual(response.status_code, 201) - mock_create.assert_called_with("the-name", data["label"], self.presetset) + self.assertEqual(response.json()["presetset"], str(self.presetset.sodar_uuid)) class TestFlagsEtcPresetsCloneOtherAjaxView(ApiViewTestBase): @@ -677,22 +631,16 @@ def test_post(self): "presetset": self.presetset.sodar_uuid, "label": "my label", } - with patch( - "variants.models.presets.FlagsEtcPresetsManager.create_as_copy_of_other_preset", - MagicMock(return_value=FlagsEtcPresetsFactory.build()), - ) as mock_create: - with self.login(self.superuser): - response = self.client.post( - reverse( - "variants:ajax-flagsetcpresets-cloneother", - kwargs={"flagsetcpresets": self.flagsetcpresets.sodar_uuid}, - ), - data=data, - ) + with self.login(self.superuser): + response = self.client.post( + reverse( + "variants:ajax-flagsetcpresets-cloneother", + kwargs={"flagsetcpresets": self.flagsetcpresets.sodar_uuid}, + ), + data=data, + ) self.assertEqual(response.status_code, 201) - mock_create.assert_called_with( - self.flagsetcpresets, presetset=self.presetset, label=data["label"] - ) + self.assertEqual(response.json()["presetset"], str(self.presetset.sodar_uuid)) class TestQuickPresetsListCreateAjaxView(ApiViewTestBase): @@ -781,20 +729,16 @@ def setUp(self): def test_post(self): data = {"label": "my label"} - with patch( - "variants.models.presets.QuickPresetsManager.create_as_copy_of_other_preset", - MagicMock(return_value=QuickPresetsFactory.build()), - ) as mock_create: - with self.login(self.superuser): - response = self.client.post( - reverse( - "variants:ajax-quickpresets-cloneother", - kwargs={"quickpresets": self.quickpresets.sodar_uuid}, - ), - data=data, - ) + with self.login(self.superuser): + response = self.client.post( + reverse( + "variants:ajax-quickpresets-cloneother", + kwargs={"quickpresets": self.quickpresets.sodar_uuid}, + ), + data=data, + ) self.assertEqual(response.status_code, 201) - mock_create.assert_called_with(self.quickpresets, label=data["label"]) + self.assertEqual(response.json()["presetset"], str(self.quickpresets.presetset.sodar_uuid)) class TestPresetSetListCreateAjaxView(ApiViewTestBase): @@ -895,19 +839,16 @@ def test_delete(self): class TestPresetSetCloneFactoryPresetsAjaxView(ApiViewTestBase): def test_post(self): data = {"project": self.project.sodar_uuid, "label": "my label"} - with patch( - "variants.models.presets.PresetSetManager.create_as_copy_of_factory_preset_set", - MagicMock(return_value=PresetSetFactory.build()), - ) as mock_create: - with self.login(self.superuser): - response = self.client.post( - reverse( - "variants:ajax-presetset-clonefactorypresets", - ), - data=data, - ) + with self.login(self.superuser): + response = self.client.post( + reverse( + "variants:ajax-presetset-clonefactorypresets", + ), + data=data, + ) self.assertEqual(response.status_code, 201) - mock_create.assert_called_with(project=self.project, label=data["label"]) + self.assertEqual(response.json()["project"], str(self.project.sodar_uuid)) + self.assertEqual(PresetSet.objects.count(), 1) class TestPresetSetCloneOtherAjaxView(ApiViewTestBase): @@ -917,17 +858,15 @@ def setUp(self): def test_post(self): data = {"project": self.project.sodar_uuid, "label": "my label"} - with patch( - "variants.models.presets.PresetSetManager.create_as_copy_of_other_preset_set", - MagicMock(return_value=PresetSetFactory.build()), - ) as mock_create: - with self.login(self.superuser): - response = self.client.post( - reverse( - "variants:ajax-presetset-cloneother", - kwargs={"presetset": self.presetset.sodar_uuid}, - ), - data=data, - ) + self.assertEqual(PresetSet.objects.count(), 1) + with self.login(self.superuser): + response = self.client.post( + reverse( + "variants:ajax-presetset-cloneother", + kwargs={"presetset": self.presetset.sodar_uuid}, + ), + data=data, + ) self.assertEqual(response.status_code, 201) - mock_create.assert_called_with(self.presetset, project=self.project, label=data["label"]) + self.assertEqual(response.json()["project"], str(self.project.sodar_uuid)) + self.assertEqual(PresetSet.objects.count(), 2) diff --git a/utils/docker/docker-entrypoint.sh b/utils/docker/docker-entrypoint.sh index 2d75fcec6..6d918fa06 100644 --- a/utils/docker/docker-entrypoint.sh +++ b/utils/docker/docker-entrypoint.sh @@ -60,9 +60,7 @@ if [[ "$1" == wsgi ]]; then cd $APP_DIR >&2 echo "VARFISH MIGRATIONS BEGIN" - python manage.py drop_variant_summary python manage.py migrate - python manage.py create_variant_summary >&2 echo "VARFISH MIGRATIONS END" exec gunicorn \