From 735dd6df1486ca8eb0bc0f1104e625e280898840 Mon Sep 17 00:00:00 2001 From: chase mateusiak Date: Tue, 12 Dec 2023 16:18:53 -0600 Subject: [PATCH] modules and filter tests passing --- .../api/filters/BindingFilter.py | 6 +- .../api/filters/ExpressionFilter.py | 6 +- .../api/filters/ExpressionManualQCFilter.py | 8 +- .../api/filters/ExpressionSourceFilter.py | 2 +- .../api/filters/GenomicFeatureFilter.py | 8 +- .../api/filters/PromoterSetSigFilter.py | 14 +- .../regulatory_data/api/filters/__init__.py | 12 + .../serializers/PromoterSetSigSerializer.py | 2 +- ..._fileformat_id_bindingsource_fileformat.py | 17 + ...leformat_id_expressionsource_fileformat.py | 17 + ...d_id_promotersetsig_background_and_more.py | 31 ++ .../regulatory_data/models/BaseModel.py | 6 + .../regulatory_data/models/BindingSource.py | 2 +- .../regulatory_data/models/Expression.py | 2 +- .../models/ExpressionSource.py | 2 +- .../regulatory_data/models/PromoterSetSig.py | 9 +- .../regulatory_data/tests/factories.py | 25 +- .../regulatory_data/tests/test_filters.py | 510 ++++++++++++++++++ 18 files changed, 642 insertions(+), 37 deletions(-) create mode 100644 yeastregulatorydb/regulatory_data/migrations/0002_rename_fileformat_id_bindingsource_fileformat.py create mode 100644 yeastregulatorydb/regulatory_data/migrations/0003_rename_fileformat_id_expressionsource_fileformat.py create mode 100644 yeastregulatorydb/regulatory_data/migrations/0004_rename_background_id_promotersetsig_background_and_more.py create mode 100644 yeastregulatorydb/regulatory_data/tests/test_filters.py diff --git a/yeastregulatorydb/regulatory_data/api/filters/BindingFilter.py b/yeastregulatorydb/regulatory_data/api/filters/BindingFilter.py index 5b1841a..086903f 100644 --- a/yeastregulatorydb/regulatory_data/api/filters/BindingFilter.py +++ b/yeastregulatorydb/regulatory_data/api/filters/BindingFilter.py @@ -8,13 +8,14 @@ class BindingFilter(django_filters.FilterSet): id = django_filters.NumberFilter() pk = django_filters.NumberFilter() regulator = django_filters.NumberFilter() - regulator_locus_tag = django_filters.CharFilter(field_name="regulator__locus_tag", lookup_expr="iexact") - regulator_symbol = django_filters.CharFilter(field_name="regulator__symbol", lookup_expr="iexact") + regulator_locus_tag = django_filters.CharFilter(field_name="regulator__regulator__locus_tag", lookup_expr="iexact") + regulator_symbol = django_filters.CharFilter(field_name="regulator__regulator__symbol", lookup_expr="iexact") batch = django_filters.CharFilter(lookup_expr="iexact") # pylint: enable=R0801 replicate = django_filters.NumberFilter() source = django_filters.NumberFilter() source_orig_id = django_filters.CharFilter(lookup_expr="iexact") + strain = django_filters.CharFilter(lookup_expr="iexact") lab = django_filters.CharFilter(field_name="source__lab", lookup_expr="iexact") assay = django_filters.CharFilter(field_name="source__assay", lookup_expr="iexact") workflow = django_filters.CharFilter(field_name="source__workflow", lookup_expr="iexact") @@ -32,6 +33,7 @@ class Meta: "replicate", "source", "source_orig_id", + "strain", "lab", "assay", "workflow", diff --git a/yeastregulatorydb/regulatory_data/api/filters/ExpressionFilter.py b/yeastregulatorydb/regulatory_data/api/filters/ExpressionFilter.py index 081e24c..b8a95b6 100644 --- a/yeastregulatorydb/regulatory_data/api/filters/ExpressionFilter.py +++ b/yeastregulatorydb/regulatory_data/api/filters/ExpressionFilter.py @@ -8,8 +8,8 @@ class ExpressionFilter(django_filters.FilterSet): id = django_filters.NumberFilter() pk = django_filters.NumberFilter() regulator = django_filters.NumberFilter() - regulator_locus_tag = django_filters.CharFilter(field_name="regulator__locus_tag", lookup_expr="iexact") - regulator_symbol = django_filters.CharFilter(field_name="regulator__symbol", lookup_expr="iexact") + regulator_locus_tag = django_filters.CharFilter(field_name="regulator__regulator__locus_tag", lookup_expr="iexact") + regulator_symbol = django_filters.CharFilter(field_name="regulator__regulator__symbol", lookup_expr="iexact") batch = django_filters.CharFilter(field_name="batch", lookup_expr="iexact") # pylint: enable=R0801 replicate = django_filters.NumberFilter() @@ -17,7 +17,7 @@ class ExpressionFilter(django_filters.FilterSet): mechanism = django_filters.CharFilter(lookup_expr="iexact") restriction = django_filters.CharFilter(lookup_expr="iexact") time = django_filters.NumberFilter(field_name="time") - source = django_filters.CharFilter(lookup_expr="iexact") + source = django_filters.NumberFilter() lab = django_filters.CharFilter(field_name="source__lab", lookup_expr="iexact") assay = django_filters.CharFilter(field_name="source__assay", lookup_expr="iexact") workflow = django_filters.CharFilter(field_name="source__workflow", lookup_expr="iexact") diff --git a/yeastregulatorydb/regulatory_data/api/filters/ExpressionManualQCFilter.py b/yeastregulatorydb/regulatory_data/api/filters/ExpressionManualQCFilter.py index 4d49354..944825a 100644 --- a/yeastregulatorydb/regulatory_data/api/filters/ExpressionManualQCFilter.py +++ b/yeastregulatorydb/regulatory_data/api/filters/ExpressionManualQCFilter.py @@ -9,16 +9,18 @@ class ExpressionManualQCFilter(django_filters.FilterSet): expression = django_filters.NumberFilter() strain_verified = django_filters.ChoiceFilter(choices=[("yes", "yes"), ("no", "no"), ("unverified", "unverified")]) regulator_locus_tag = django_filters.CharFilter( - field_name="expression__regulator__locus_tag", lookup_expr="iexact" + field_name="expression__regulator__regulator__locus_tag", lookup_expr="iexact" + ) + regulator_symbol = django_filters.CharFilter( + field_name="expression__regulator__regulator__symbol", lookup_expr="iexact" ) - regulator_symbol = django_filters.CharFilter(field_name="expression__regulator__symbol", lookup_expr="iexact") batch = django_filters.CharFilter(field_name="expression__batch", lookup_expr="iexact") replicate = django_filters.NumberFilter(field_name="expression__replicate") control = django_filters.CharFilter(field_name="expression__control", lookup_expr="iexact") mechanism = django_filters.CharFilter(field_name="expression__mechanism", lookup_expr="iexact") restriction = django_filters.CharFilter(field_name="expression__restriction", lookup_expr="iexact") time = django_filters.NumberFilter(field_name="expression__time") - source = django_filters.CharFilter(field_name="expression__source", lookup_expr="iexact") + source = django_filters.NumberFilter(field_name="expression__source__id") lab = django_filters.CharFilter(field_name="expression__source__lab", lookup_expr="iexact") assay = django_filters.CharFilter(field_name="expression__source__assay", lookup_expr="iexact") workflow = django_filters.CharFilter(field_name="expression__source__workflow", lookup_expr="iexact") diff --git a/yeastregulatorydb/regulatory_data/api/filters/ExpressionSourceFilter.py b/yeastregulatorydb/regulatory_data/api/filters/ExpressionSourceFilter.py index e217742..41e5f86 100644 --- a/yeastregulatorydb/regulatory_data/api/filters/ExpressionSourceFilter.py +++ b/yeastregulatorydb/regulatory_data/api/filters/ExpressionSourceFilter.py @@ -7,7 +7,7 @@ class ExpressionSourceFilter(django_filters.FilterSet): id = django_filters.NumberFilter() pk = django_filters.NumberFilter() fileformat_id = django_filters.NumberFilter() - fileformat = django_filters.CharFilter(field_name="fileformat_id__fileformat", lookup_expr="iexact") + fileformat = django_filters.CharFilter(field_name="fileformat__fileformat", lookup_expr="iexact") lab = django_filters.CharFilter(lookup_expr="iexact") assay = django_filters.CharFilter(lookup_expr="iexact") workflow = django_filters.CharFilter(lookup_expr="iexact") diff --git a/yeastregulatorydb/regulatory_data/api/filters/GenomicFeatureFilter.py b/yeastregulatorydb/regulatory_data/api/filters/GenomicFeatureFilter.py index e249a67..57422d5 100644 --- a/yeastregulatorydb/regulatory_data/api/filters/GenomicFeatureFilter.py +++ b/yeastregulatorydb/regulatory_data/api/filters/GenomicFeatureFilter.py @@ -9,9 +9,9 @@ class GenomicFeatureFilter(django_filters.FilterSet): end = django_filters.NumberFilter() strand = django_filters.CharFilter(lookup_expr="exact") type = django_filters.CharFilter(lookup_expr="iexact") - gene_biotype = django_filters.CharFilter(lookup_expr="iexact") + biotype = django_filters.CharFilter(lookup_expr="iexact") locus_tag = django_filters.CharFilter(lookup_expr="iexact") - gene = django_filters.CharFilter(lookup_expr="iexact") + symbol = django_filters.CharFilter(lookup_expr="iexact") source = django_filters.CharFilter(lookup_expr="iexact") alias = django_filters.CharFilter(lookup_expr="iexact") note = django_filters.CharFilter(lookup_expr="iexact") @@ -24,9 +24,9 @@ class Meta: "end", "strand", "type", - "gene_biotype", + "biotype", "locus_tag", - "gene", + "symbol", "source", "alias", "note", diff --git a/yeastregulatorydb/regulatory_data/api/filters/PromoterSetSigFilter.py b/yeastregulatorydb/regulatory_data/api/filters/PromoterSetSigFilter.py index 9362f9e..8f23bfc 100644 --- a/yeastregulatorydb/regulatory_data/api/filters/PromoterSetSigFilter.py +++ b/yeastregulatorydb/regulatory_data/api/filters/PromoterSetSigFilter.py @@ -7,12 +7,16 @@ class PromoterSetSigFilter(django_filters.FilterSet): id = django_filters.NumberFilter() pk = django_filters.NumberFilter() binding = django_filters.NumberFilter() - promoter_id = django_filters.NumberFilter() - promoter_name = django_filters.CharFilter(field_name="promoter_id__name", lookup_expr="iexact") - background_id = django_filters.NumberFilter(field_name="background_id") + promoter = django_filters.NumberFilter() + promoter_name = django_filters.CharFilter(field_name="promoter__name", lookup_expr="iexact") + background = django_filters.NumberFilter() background_name = django_filters.CharFilter(field_name="background_id__name", lookup_expr="iexact") - regulator_locus_tag = django_filters.CharFilter(field_name="binding__regulator__locus_tag", lookup_expr="iexact") - regulator_symbol = django_filters.CharFilter(field_name="binding__regulator__symbol", lookup_expr="iexact") + regulator_locus_tag = django_filters.CharFilter( + field_name="binding__regulator__regulator__locus_tag", lookup_expr="iexact" + ) + regulator_symbol = django_filters.CharFilter( + field_name="binding__regulator__regulator__symbol", lookup_expr="iexact" + ) batch = django_filters.CharFilter(field_name="binding__batch", lookup_expr="iexact") replicate = django_filters.NumberFilter(field_name="binding__replicate") source = django_filters.NumberFilter(field_name="binding__source") diff --git a/yeastregulatorydb/regulatory_data/api/filters/__init__.py b/yeastregulatorydb/regulatory_data/api/filters/__init__.py index e69de29..7e7361e 100644 --- a/yeastregulatorydb/regulatory_data/api/filters/__init__.py +++ b/yeastregulatorydb/regulatory_data/api/filters/__init__.py @@ -0,0 +1,12 @@ +from .BindingFilter import BindingFilter +from .BindingManualQCFilter import BindingManualQCFilter +from .BindingSourceFilter import BindingSourceFilter +from .CallingCardsBackgroundFilter import CallingCardsBackgroundFilter +from .ExpressionFilter import ExpressionFilter +from .ExpressionManualQCFilter import ExpressionManualQCFilter +from .ExpressionSourceFilter import ExpressionSourceFilter +from .FileFormatFilter import FileFormatFilter +from .GenomicFeatureFilter import GenomicFeatureFilter +from .PromoterSetFilter import PromoterSetFilter +from .PromoterSetSigFilter import PromoterSetSigFilter +from .RegulatorFilter import RegulatorFilter diff --git a/yeastregulatorydb/regulatory_data/api/serializers/PromoterSetSigSerializer.py b/yeastregulatorydb/regulatory_data/api/serializers/PromoterSetSigSerializer.py index 4270258..1292ced 100644 --- a/yeastregulatorydb/regulatory_data/api/serializers/PromoterSetSigSerializer.py +++ b/yeastregulatorydb/regulatory_data/api/serializers/PromoterSetSigSerializer.py @@ -18,4 +18,4 @@ class Meta: fields = "__all__" def get_background_id(self, obj): - return obj.background_id.id if obj.background_id else "undefined" + return obj.background.id if obj.background else "undefined" diff --git a/yeastregulatorydb/regulatory_data/migrations/0002_rename_fileformat_id_bindingsource_fileformat.py b/yeastregulatorydb/regulatory_data/migrations/0002_rename_fileformat_id_bindingsource_fileformat.py new file mode 100644 index 0000000..26d0d9d --- /dev/null +++ b/yeastregulatorydb/regulatory_data/migrations/0002_rename_fileformat_id_bindingsource_fileformat.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2.8 on 2023-12-12 18:50 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("regulatory_data", "0001_initial"), + ] + + operations = [ + migrations.RenameField( + model_name="bindingsource", + old_name="fileformat_id", + new_name="fileformat", + ), + ] diff --git a/yeastregulatorydb/regulatory_data/migrations/0003_rename_fileformat_id_expressionsource_fileformat.py b/yeastregulatorydb/regulatory_data/migrations/0003_rename_fileformat_id_expressionsource_fileformat.py new file mode 100644 index 0000000..31baf1e --- /dev/null +++ b/yeastregulatorydb/regulatory_data/migrations/0003_rename_fileformat_id_expressionsource_fileformat.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2.8 on 2023-12-12 18:53 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("regulatory_data", "0002_rename_fileformat_id_bindingsource_fileformat"), + ] + + operations = [ + migrations.RenameField( + model_name="expressionsource", + old_name="fileformat_id", + new_name="fileformat", + ), + ] diff --git a/yeastregulatorydb/regulatory_data/migrations/0004_rename_background_id_promotersetsig_background_and_more.py b/yeastregulatorydb/regulatory_data/migrations/0004_rename_background_id_promotersetsig_background_and_more.py new file mode 100644 index 0000000..f55a406 --- /dev/null +++ b/yeastregulatorydb/regulatory_data/migrations/0004_rename_background_id_promotersetsig_background_and_more.py @@ -0,0 +1,31 @@ +# Generated by Django 4.2.8 on 2023-12-12 21:56 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("regulatory_data", "0003_rename_fileformat_id_expressionsource_fileformat"), + ] + + operations = [ + migrations.RenameField( + model_name="promotersetsig", + old_name="background_id", + new_name="background", + ), + migrations.RenameField( + model_name="promotersetsig", + old_name="promoter_id", + new_name="promoter", + ), + migrations.AlterField( + model_name="expression", + name="control", + field=models.CharField( + choices=[("undefined", "undefined"), ("wt", "wt"), ("wt_meta", "wt_meta")], + default="undefined", + help_text="Intended for micro-array data, this field records the control strain used to generate the relative intensity data", + ), + ), + ] diff --git a/yeastregulatorydb/regulatory_data/models/BaseModel.py b/yeastregulatorydb/regulatory_data/models/BaseModel.py index 0158c08..c97c167 100644 --- a/yeastregulatorydb/regulatory_data/models/BaseModel.py +++ b/yeastregulatorydb/regulatory_data/models/BaseModel.py @@ -46,6 +46,12 @@ class MyModel(BaseModel): class Meta: abstract = True + def save(self, *args, **kwargs): + # If the record is being created, set the modifier to the uploader + if self._state.adding: + self.modifier = self.uploader + super().save(*args, **kwargs) + @receiver(pre_save, sender=BaseModel) def update_modified_date(sender, instance, **kwargs): # pylint: disable=unused-argument diff --git a/yeastregulatorydb/regulatory_data/models/BindingSource.py b/yeastregulatorydb/regulatory_data/models/BindingSource.py index 1ce2ce7..e559656 100644 --- a/yeastregulatorydb/regulatory_data/models/BindingSource.py +++ b/yeastregulatorydb/regulatory_data/models/BindingSource.py @@ -15,7 +15,7 @@ class BindingSource(BaseModel): Store binding data source information """ - fileformat_id = models.ForeignKey( + fileformat = models.ForeignKey( "FileFormat", on_delete=models.CASCADE, help_text="Foreign key to the FileFormat table", diff --git a/yeastregulatorydb/regulatory_data/models/Expression.py b/yeastregulatorydb/regulatory_data/models/Expression.py index d6aad37..1acaadb 100644 --- a/yeastregulatorydb/regulatory_data/models/Expression.py +++ b/yeastregulatorydb/regulatory_data/models/Expression.py @@ -23,7 +23,7 @@ class Expression(BaseModel, FileUploadMixin): ) replicate = models.PositiveIntegerField(default=1, help_text="Replicate number") control = models.CharField( - choices=[("undefined", "undefined"), ("wt", "wt"), ("wt_mata", "wt_mata")], + choices=[("undefined", "undefined"), ("wt", "wt"), ("wt_meta", "wt_meta")], default="undefined", help_text="Intended for micro-array data, this field records the " "control strain used to generate the relative intensity data", diff --git a/yeastregulatorydb/regulatory_data/models/ExpressionSource.py b/yeastregulatorydb/regulatory_data/models/ExpressionSource.py index cc25f24..8b1debb 100644 --- a/yeastregulatorydb/regulatory_data/models/ExpressionSource.py +++ b/yeastregulatorydb/regulatory_data/models/ExpressionSource.py @@ -15,7 +15,7 @@ class ExpressionSource(BaseModel): Store expression data source information """ - fileformat_id = models.ForeignKey( + fileformat = models.ForeignKey( "FileFormat", on_delete=models.CASCADE, help_text="foreign key to the fileformat table" ) lab = models.CharField( diff --git a/yeastregulatorydb/regulatory_data/models/PromoterSetSig.py b/yeastregulatorydb/regulatory_data/models/PromoterSetSig.py index 1a88211..e06c2b8 100644 --- a/yeastregulatorydb/regulatory_data/models/PromoterSetSig.py +++ b/yeastregulatorydb/regulatory_data/models/PromoterSetSig.py @@ -16,12 +16,12 @@ class PromoterSetSig(BaseModel, FileUploadMixin): """ binding = models.ForeignKey("Binding", on_delete=models.CASCADE, help_text="foreign key to the 'Binding' table") - promoter_id = models.ForeignKey( + promoter = models.ForeignKey( "PromoterSet", on_delete=models.CASCADE, help_text="foreign key to the 'promoter' table" ) # note: in the serializer, when a user makes a GET request, a null value # is transformed to the string 'undefined' prior to returning to client - background_id = models.ForeignKey( + background = models.ForeignKey( "CallingCardsBackground", on_delete=models.CASCADE, blank=True, @@ -34,10 +34,7 @@ class PromoterSetSig(BaseModel, FileUploadMixin): file = models.FileField(upload_to="temp", help_text="A file which stores data on " "regulator/DNA interaction") def __str__(self): - return ( - f"pk:{self.pk};binding:{self.binding};" - f"promoter_id:{self.promoter_id};background_id:{self.background_id}" - ) + return f"pk:{self.pk};binding:{self.binding};" f"promoter_id:{self.promoter};background:{self.background}" class Meta: db_table = "promotersetsig" diff --git a/yeastregulatorydb/regulatory_data/tests/factories.py b/yeastregulatorydb/regulatory_data/tests/factories.py index 3907f28..584e17d 100644 --- a/yeastregulatorydb/regulatory_data/tests/factories.py +++ b/yeastregulatorydb/regulatory_data/tests/factories.py @@ -1,5 +1,5 @@ import faker -from factory import Faker, SubFactory +from factory import Faker, LazyFunction, SubFactory from factory.django import DjangoModelFactory, FileField from yeastregulatorydb.users.tests.factories import UserFactory @@ -23,6 +23,13 @@ fake = faker.Faker() +def sentence_with_max_chars(max_chars=100): + sentence = fake.sentence(nb_words=10) + if len(sentence) > max_chars: + sentence = sentence[:max_chars].rsplit(" ", 1)[0] + "." + return sentence + + class ChrMapFactory(DjangoModelFactory): uploader = SubFactory(UserFactory) modifier = SubFactory(UserFactory) @@ -97,7 +104,7 @@ class Meta: class ExpressionSourceFactory(DjangoModelFactory): uploader = SubFactory(UserFactory) modifier = SubFactory(UserFactory) - fileformat_id = SubFactory(FileFormatFactory) + fileformat = SubFactory(FileFormatFactory) lab = Faker("word") assay = Faker("word") workflow = Faker("word") @@ -107,7 +114,7 @@ class ExpressionSourceFactory(DjangoModelFactory): class Meta: model = ExpressionSource - django_get_or_create = ["fileformat_id"] + django_get_or_create = ["fileformat"] class ExpressionFactory(DjangoModelFactory): @@ -158,7 +165,7 @@ class Meta: class BindingSourceFactory(DjangoModelFactory): uploader = SubFactory(UserFactory) modifier = SubFactory(UserFactory) - fileformat_id = SubFactory(FileFormatFactory) + fileformat = SubFactory(FileFormatFactory) lab = Faker("pystr", max_chars=20) assay = Faker("pystr", max_chars=20) workflow = Faker("pystr", max_chars=50) @@ -168,7 +175,7 @@ class BindingSourceFactory(DjangoModelFactory): class Meta: model = BindingSource - django_get_or_create = ["fileformat_id", "lab", "assay", "workflow"] + django_get_or_create = ["fileformat", "lab", "assay", "workflow"] class BindingFactory(DjangoModelFactory): @@ -211,7 +218,7 @@ class PromoterSetFactory(DjangoModelFactory): modifier = SubFactory(UserFactory) name = Faker("pystr", max_chars=10) file = FileField(filename="testfile.bed.gz") - notes = Faker("sentence", nb_words=10) + notes = LazyFunction(sentence_with_max_chars) class Meta: model = PromoterSet @@ -222,11 +229,11 @@ class PromoterSetSigFactory(DjangoModelFactory): uploader = SubFactory(UserFactory) modifier = SubFactory(UserFactory) binding = SubFactory(BindingFactory) - promoter_id = SubFactory(PromoterSetFactory) - background_id = SubFactory(CallingCardsBackgroundFactory) + promoter = SubFactory(PromoterSetFactory) + background = SubFactory(CallingCardsBackgroundFactory) filetype = SubFactory(FileFormatFactory) file = FileField(filename="testfile.tsv.gz") class Meta: model = PromoterSetSig - django_get_or_create = ["binding", "promoter_id", "background_id"] + django_get_or_create = ["binding", "promoter", "background"] diff --git a/yeastregulatorydb/regulatory_data/tests/test_filters.py b/yeastregulatorydb/regulatory_data/tests/test_filters.py new file mode 100644 index 0000000..1ba364b --- /dev/null +++ b/yeastregulatorydb/regulatory_data/tests/test_filters.py @@ -0,0 +1,510 @@ +import pytest + +from yeastregulatorydb.regulatory_data.api.filters import ( + BindingFilter, + BindingManualQCFilter, + BindingSourceFilter, + CallingCardsBackgroundFilter, + ExpressionFilter, + ExpressionManualQCFilter, + ExpressionSourceFilter, + FileFormatFilter, + GenomicFeatureFilter, + PromoterSetFilter, + PromoterSetSigFilter, + RegulatorFilter, +) +from yeastregulatorydb.regulatory_data.models import ( + Binding, + BindingManualQC, + BindingSource, + CallingCardsBackground, + ChrMap, + Expression, + ExpressionManualQC, + ExpressionSource, + FileFormat, + GenomicFeature, + PromoterSet, + PromoterSetSig, + Regulator, +) + +from .factories import ( + BindingFactory, + BindingManualQCFactory, + BindingSourceFactory, + CallingCardsBackgroundFactory, + ChrMapFactory, + ExpressionFactory, + ExpressionManualQCFactory, + ExpressionSourceFactory, + FileFormatFactory, + GenomicFeatureFactory, + PromoterSetFactory, + PromoterSetSigFactory, + RegulatorFactory, +) + + +@pytest.mark.django_db +def test_binding_filter(): + # Create some bindings using the factory + regulator1 = RegulatorFactory() + regulator2 = RegulatorFactory() + source1 = BindingSourceFactory() + source2 = BindingSourceFactory() + binding1 = BindingFactory( + regulator=regulator1, id=1, batch="batch1", replicate=1, source=source1, source_orig_id="1", strain="strain1" + ) + binding2 = BindingFactory( + regulator=regulator2, id=2, batch="batch2", replicate=2, source=source2, source_orig_id="2", strain="strain2" + ) + + # Define the filter parameters and their expected values + filter_params = [ + {"id": 1}, + {"regulator": regulator1.id}, + {"regulator_locus_tag": regulator1.regulator.locus_tag}, + {"regulator_symbol": regulator1.regulator.symbol}, + {"batch": "batch1"}, + {"replicate": 1}, + {"source": source1.id}, + {"source_orig_id": "1"}, + {"strain": "strain1"}, + {"lab": source1.lab}, + {"assay": source1.assay}, + {"workflow": source1.workflow}, + ] + + # Apply each filter and check if it returns the expected bindings + for params in filter_params: + f = BindingFilter(params, queryset=Binding.objects.all()) + assert binding1 in f.qs + assert binding2 not in f.qs + + +@pytest.mark.django_db +def test_binding_manual_qc_filter(): + # Create some bindings using the factory + regulator1 = RegulatorFactory() + regulator2 = RegulatorFactory() + bindingsource1 = BindingSourceFactory() + binding1 = BindingFactory(regulator=regulator1, id=1, batch="batch1", source=bindingsource1) + bindingsource2 = BindingSourceFactory() + binding2 = BindingFactory(regulator=regulator2, id=2, batch="batch2", source=bindingsource2) + binding_manual_qc1 = BindingManualQCFactory( + binding=binding1, + id=1, + rank_response_pass=True, + best_response_pass=True, + data_usable=True, + passing_replicate=True, + ) + binding_manual_qc2 = BindingManualQCFactory( + binding=binding2, + id=2, + rank_response_pass=False, + best_response_pass=False, + data_usable=False, + passing_replicate=False, + ) + + # Define the filter parameters and their expected values + filter_params = [ + {"id": 1}, + {"pk": 1}, + {"binding": binding1.id}, + {"rank_response_pass": True}, + {"best_response_pass": True}, + {"data_usable": True}, + {"passing_replicate": True}, + ] + + # Apply each filter and check if it returns the expected bindings + for params in filter_params: + f = BindingManualQCFilter(params, queryset=BindingManualQC.objects.all()) + assert binding_manual_qc1 in f.qs + assert binding_manual_qc2 not in f.qs + + +@pytest.mark.django_db +def test_binding_source_filter(): + # Create some binding sources using the factory + + fileformat1 = FileFormatFactory(fileformat="fileformat1") + fileformat2 = FileFormatFactory(fileformat="fileformat2") + binding_source1 = BindingSourceFactory( + id=1, + fileformat=fileformat1, + lab="lab1", + assay="assay1", + workflow="workflow1", + ) + binding_source2 = BindingSourceFactory( + id=2, + fileformat=fileformat2, + lab="lab2", + assay="assay2", + workflow="workflow2", + ) + + # Define the filter parameters and their expected values + filter_params = [ + {"id": 1}, + {"pk": 1}, + {"fileformat_id": fileformat1.id}, + {"fileformat": "fileformat1"}, + {"lab": "lab1"}, + {"assay": "assay1"}, + {"workflow": "workflow1"}, + ] + + # Apply each filter and check if it returns the expected binding sources + for params in filter_params: + f = BindingSourceFilter(params, queryset=BindingSource.objects.all()) + assert binding_source1 in f.qs + assert binding_source2 not in f.qs + + +@pytest.mark.django_db +def test_calling_cards_background_filter(): + # Create some CallingCardsBackground instances using the factory + background1 = CallingCardsBackgroundFactory( + id=1, + name="name1", + genomic_inserts=10, + mito_inserts=20, + plasmid_inserts=30, + notes="notes1", + ) + background2 = CallingCardsBackgroundFactory( + id=2, + name="name2", + genomic_inserts=40, + mito_inserts=50, + plasmid_inserts=60, + notes="notes2", + ) + + # Define the filter parameters and their expected values + filter_params = [ + {"name": "name1"}, + ] + + # Apply each filter and check if it returns the expected backgrounds + for params in filter_params: + f = CallingCardsBackgroundFilter(params, queryset=CallingCardsBackground.objects.all()) + assert background1 in f.qs + assert background2 not in f.qs + + +@pytest.mark.django_db +def test_expression_filter(): + # Create some expressions using the factory + regulator1 = RegulatorFactory() + regulator2 = RegulatorFactory() + source1 = ExpressionSourceFactory() + source2 = ExpressionSourceFactory() + expression1 = ExpressionFactory( + regulator=regulator1, + id=1, + batch="batch1", + replicate=1, + control="undefined", + mechanism="gev", + restriction="P", + time=1, + source=source1, + ) + expression2 = ExpressionFactory( + regulator=regulator2, + id=2, + batch="batch2", + replicate=2, + control="wt", + mechanism="zev", + restriction="M", + time=2, + source=source2, + ) + + # Define the filter parameters and their expected values + filter_params = [ + {"id": 1}, + {"pk": 1}, + {"regulator": regulator1.id}, + {"regulator_locus_tag": regulator1.regulator.locus_tag}, + {"regulator_symbol": regulator1.regulator.symbol}, + {"batch": "batch1"}, + {"replicate": 1}, + {"control": "undefined"}, + {"mechanism": "gev"}, + {"restriction": "P"}, + {"time": 1}, + {"source": source1.id}, + {"lab": source1.lab}, + {"assay": source1.assay}, + {"workflow": source1.workflow}, + ] + + # Apply each filter and check if it returns the expected expressions + for params in filter_params: + f = ExpressionFilter(params, queryset=Expression.objects.all()) + assert expression1 in f.qs + assert expression2 not in f.qs + + +@pytest.mark.django_db +def test_expression_manual_qc_filter(): + # Create some expressions using the factory + regulator1 = RegulatorFactory() + regulator2 = RegulatorFactory() + source1 = ExpressionSourceFactory() + source2 = ExpressionSourceFactory() + expression1 = ExpressionFactory( + regulator=regulator1, + id=1, + batch="batch1", + replicate=1, + control="undefined", + mechanism="gev", + restriction="P", + time=1, + source=source1, + ) + expression2 = ExpressionFactory( + regulator=regulator2, + id=2, + batch="batch2", + replicate=2, + control="wt", + mechanism="zev", + restriction="M", + time=2, + source=source2, + ) + manual_qc1 = ExpressionManualQCFactory(id=1, expression=expression1, strain_verified="yes") + manual_qc2 = ExpressionManualQCFactory(id=2, expression=expression2, strain_verified="no") + + # Define the filter parameters and their expected values + filter_params = [ + {"id": 1}, + {"pk": 1}, + {"expression": expression1.id}, + {"strain_verified": manual_qc1.strain_verified}, + {"regulator_locus_tag": regulator1.regulator.locus_tag}, + {"regulator_symbol": regulator1.regulator.symbol}, + {"batch": expression1.batch}, + {"replicate": expression1.replicate}, + {"control": expression1.control}, + {"mechanism": expression1.mechanism}, + {"restriction": expression1.restriction}, + {"time": expression1.time}, + {"source": source1.id}, + {"lab": source1.lab}, + {"assay": source1.assay}, + {"workflow": source1.workflow}, + ] + + # Apply each filter and check if it returns the expected ExpressionManualQC instances + for params in filter_params: + f = ExpressionManualQCFilter(params, queryset=ExpressionManualQC.objects.all()) + assert manual_qc1 in f.qs + assert manual_qc2 not in f.qs + + +@pytest.mark.django_db +def test_expression_source_filter(): + # Create some ExpressionSource instances using the factory + fileformat1 = FileFormatFactory(fileformat="fileformat1") + fileformat2 = FileFormatFactory(fileformat="fileformat2") + expression_source1 = ExpressionSourceFactory( + id=1, + fileformat=fileformat1, + lab="lab1", + assay="assay1", + workflow="workflow1", + ) + expression_source2 = ExpressionSourceFactory( + id=2, + fileformat=fileformat2, + lab="lab2", + assay="assay2", + workflow="workflow2", + ) + + # Define the filter parameters and their expected values + filter_params = [ + {"id": 1}, + {"pk": 1}, + {"fileformat_id": fileformat1.id}, + {"fileformat": "fileformat1"}, + {"lab": "lab1"}, + {"assay": "assay1"}, + {"workflow": "workflow1"}, + ] + + # Apply each filter and check if it returns the expected ExpressionSource instances + for params in filter_params: + f = ExpressionSourceFilter(params, queryset=ExpressionSource.objects.all()) + assert expression_source1 in f.qs + assert expression_source2 not in f.qs + + +@pytest.mark.django_db +def test_file_format_filter(): + # Create some FileFormat instances using the factory + fileformat1 = FileFormatFactory(fileformat="fileformat1") + fileformat2 = FileFormatFactory(fileformat="fileformat2") + + # Define the filter parameters and their expected values + filter_params = [ + {"fileformat": "fileformat1"}, + ] + + # Apply each filter and check if it returns the expected FileFormat instances + for params in filter_params: + f = FileFormatFilter(params, queryset=FileFormat.objects.all()) + assert fileformat1 in f.qs + assert fileformat2 not in f.qs + + +@pytest.mark.django_db +def test_genomic_feature_filter(): + # Create some GenomicFeature instances using the factory + chr1 = ChrMapFactory(ucsc="chr1") + chr2 = ChrMapFactory(ucsc="chr2") + genomic_feature1 = GenomicFeatureFactory( + chr=chr1, + start=1, + end=100, + strand="+", + type="type1", + biotype="biotype1", + locus_tag="tag1", + symbol="gene1", + source="source1", + alias="alias1", + note="note1", + ) + genomic_feature2 = GenomicFeatureFactory( + chr=chr2, + start=101, + end=200, + strand="-", + type="type2", + biotype="biotype2", + locus_tag="tag2", + symbol="gene2", + source="source2", + alias="alias2", + note="note2", + ) + + # Define the filter parameters and their expected values + filter_params = [ + {"chr": "chr1"}, + {"start": 1}, + {"end": 100}, + {"strand": "+"}, + {"type": "type1"}, + {"biotype": "biotype1"}, + {"locus_tag": "tag1"}, + {"symbol": "gene1"}, + {"source": "source1"}, + {"alias": "alias1"}, + {"note": "note1"}, + ] + + # Apply each filter and check if it returns the expected GenomicFeature instances + for params in filter_params: + f = GenomicFeatureFilter(params, queryset=GenomicFeature.objects.all()) + assert genomic_feature1 in f.qs + assert genomic_feature2 not in f.qs + + +@pytest.mark.django_db +def test_promoter_set_filter(): + # Create some PromoterSet instances using the factory + promoter_set1 = PromoterSetFactory(name="set1") + promoter_set2 = PromoterSetFactory(name="set2") + + # Define the filter parameters and their expected values + filter_params = [ + {"name": promoter_set1.name}, + ] + + # Apply each filter and check if it returns the expected PromoterSet instances + for params in filter_params: + f = PromoterSetFilter(params, queryset=PromoterSet.objects.all()) + assert promoter_set1 in f.qs + assert promoter_set2 not in f.qs + + +@pytest.mark.django_db +def test_promoter_set_sig_filter(): + # Create some PromoterSetSig instances using the factory + regulator1 = RegulatorFactory() + regulator2 = RegulatorFactory() + promoter1 = PromoterSetFactory(name="promoter1") + promoter2 = PromoterSetFactory(name="promoter2") + background1 = CallingCardsBackgroundFactory(name="bg1") + background2 = CallingCardsBackgroundFactory(name="bg2") + bindingsource1 = BindingSourceFactory(lab="lab1", assay="assay1", workflow="workflow1") + bindingsource2 = BindingSourceFactory(lab="lab2", assay="assay2", workflow="workflow2") + binding1 = BindingFactory(regulator=regulator1, batch="batch1", replicate=1, source=bindingsource1) + binding2 = BindingFactory(regulator=regulator2, batch="batch2", replicate=2, source=bindingsource2) + promoter_set_sig1 = PromoterSetSigFactory(id=1, binding=binding1, promoter=promoter1, background=background1) + promoter_set_sig2 = PromoterSetSigFactory(id=2, binding=binding2, promoter=promoter2, background=background2) + + # Define the filter parameters and their expected values + filter_params = [ + {"id": promoter_set_sig1.id}, + {"pk": promoter_set_sig1.pk}, + {"binding": binding1.id}, + {"promoter": promoter1.id}, + {"promoter_name": "promoter1"}, + {"background": background1.id}, + {"background_name": background1.name}, + {"regulator_locus_tag": regulator1.regulator.locus_tag}, + {"regulator_symbol": regulator1.regulator.symbol}, + {"batch": "batch1"}, + {"replicate": 1}, + {"source": bindingsource1.id}, + {"lab": "lab1"}, + {"assay": "assay1"}, + {"workflow": "workflow1"}, + ] + + # Apply each filter and check if it returns the expected PromoterSetSig instances + for params in filter_params: + f = PromoterSetSigFilter(params, queryset=PromoterSetSig.objects.all()) + assert promoter_set_sig1 in f.qs + assert promoter_set_sig2 not in f.qs + + +@pytest.mark.django_db +def test_regulator_filter(): + # Create some Regulator instances using the factory + regulator1 = RegulatorFactory( + id=1, regulator__locus_tag="tag1", regulator__symbol="symbol1", under_development=True + ) + regulator2 = RegulatorFactory( + id=2, regulator__locus_tag="tag2", regulator__symbol="symbol2", under_development=False + ) + + # Define the filter parameters and their expected values + filter_params = [ + {"id": 1}, + {"pk": 1}, + {"regulator_locus_tag": "tag1"}, + {"regulator_symbol": "symbol1"}, + {"under_development": True}, + ] + + # Apply each filter and check if it returns the expected Regulator instances + for params in filter_params: + f = RegulatorFilter(params, queryset=Regulator.objects.all()) + assert regulator1 in f.qs + assert regulator2 not in f.qs