diff --git a/basedosdados_api/api/v1/admin.py b/basedosdados_api/api/v1/admin.py index 14044172..bdd8a58f 100644 --- a/basedosdados_api/api/v1/admin.py +++ b/basedosdados_api/api/v1/admin.py @@ -29,9 +29,11 @@ EntityCategory, Dictionary, Pipeline, + Analysis, AnalysisType, DateTimeRange, Key, + QualityCheck, UUIDHIddenIdForm, ) @@ -526,7 +528,77 @@ class StatusAdmin(TabbedTranslationAdmin): ] -admin.site.register(AnalysisType) +class AnalysisTypeAdmin(TabbedTranslationAdmin): + readonly_fields = [ + "id", + ] + list_display = [ + "name", + "slug", + ] + search_fields = [ + "name", + "slug", + ] + + +class AnalysisAdmin(TabbedTranslationAdmin): + readonly_fields = [ + "id", + ] + list_display = [ + "name", + "analysis_type", + ] + search_fields = [ + "name", + "description", + ] + autocomplete_fields = ["analysis_type", "datasets", "themes", "tags"] + filter_horizontal = ["datasets", "themes", "tags"] + + +class KeyAdmin(admin.ModelAdmin): + readonly_fields = [ + "id", + ] + list_display = [ + "name", + "value", + ] + search_fields = [ + "name", + "value", + ] + + +class QualityCheckAdmin(TabbedTranslationAdmin): + readonly_fields = [ + "id", + ] + list_display = [ + "name", + "analysis", + "dataset", + "passed", + ] + search_fields = [ + "name", + "descriptiion", + ] + autocomplete_fields = [ + "analysis", + "dataset", + "table", + "column", + "key", + "raw_data_source", + "information_request", + ] + + +admin.site.register(Analysis, AnalysisAdmin) +admin.site.register(AnalysisType, AnalysisTypeAdmin) admin.site.register(Area, AreaAdmin) admin.site.register(Availability, AvailabilityAdmin) admin.site.register(BigQueryType) @@ -539,7 +611,7 @@ class StatusAdmin(TabbedTranslationAdmin): admin.site.register(Entity, EntityAdmin) admin.site.register(EntityCategory, EntityCategoryAdmin) admin.site.register(InformationRequest, InformationRequestAdmin) -admin.site.register(Key) +admin.site.register(Key, KeyAdmin) admin.site.register(Language, LanguageAdmin) admin.site.register(License, LicenseAdmin) admin.site.register(ObservationLevel, ObservationLevelAdmin) @@ -551,3 +623,4 @@ class StatusAdmin(TabbedTranslationAdmin): admin.site.register(Tag, TagAdmin) admin.site.register(Theme, ThemeAdmin) admin.site.register(Update, UpdateAdmin) +admin.site.register(QualityCheck, QualityCheckAdmin) diff --git a/basedosdados_api/api/v1/migrations/0008_analysis.py b/basedosdados_api/api/v1/migrations/0008_analysis.py new file mode 100644 index 00000000..a1fbb679 --- /dev/null +++ b/basedosdados_api/api/v1/migrations/0008_analysis.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Generated by Django 4.2.1 on 2023-05-06 18:26 + +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + ("v1", "0007_alter_entitycategory_options_and_more"), + ] + + operations = [ + migrations.CreateModel( + name="Analysis", + fields=[ + ( + "id", + models.UUIDField( + default=uuid.uuid4, primary_key=True, serialize=False + ), + ), + ( + "analysis_type", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="analyses", + to="v1.analysistype", + ), + ), + ], + options={ + "verbose_name": "Analysis", + "verbose_name_plural": "Analyses", + "db_table": "analysis", + "ordering": ["id"], + }, + ), + ] diff --git a/basedosdados_api/api/v1/migrations/0009_remove_analysistype_tag_remove_analysistype_tag_en_and_more.py b/basedosdados_api/api/v1/migrations/0009_remove_analysistype_tag_remove_analysistype_tag_en_and_more.py new file mode 100644 index 00000000..6a62cb3c --- /dev/null +++ b/basedosdados_api/api/v1/migrations/0009_remove_analysistype_tag_remove_analysistype_tag_en_and_more.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Generated by Django 4.2.1 on 2023-05-06 18:38 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("v1", "0008_analysis"), + ] + + operations = [ + migrations.RemoveField( + model_name="analysistype", + name="tag", + ), + migrations.RemoveField( + model_name="analysistype", + name="tag_en", + ), + migrations.RemoveField( + model_name="analysistype", + name="tag_es", + ), + migrations.RemoveField( + model_name="analysistype", + name="tag_pt", + ), + ] diff --git a/basedosdados_api/api/v1/migrations/0010_analysis_tags_analysis_themes_analysis_url_and_more.py b/basedosdados_api/api/v1/migrations/0010_analysis_tags_analysis_themes_analysis_url_and_more.py new file mode 100644 index 00000000..941602e7 --- /dev/null +++ b/basedosdados_api/api/v1/migrations/0010_analysis_tags_analysis_themes_analysis_url_and_more.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Generated by Django 4.2.1 on 2023-05-06 19:00 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ("v1", "0009_remove_analysistype_tag_remove_analysistype_tag_en_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="analysis", + name="tags", + field=models.ManyToManyField( + blank=True, + help_text="Tags are used to group analyses by topic", + related_name="analyses", + to="v1.tag", + ), + ), + migrations.AddField( + model_name="analysis", + name="themes", + field=models.ManyToManyField( + help_text="Themes are used to group analyses by topic", + related_name="analyses", + to="v1.theme", + ), + ), + migrations.AddField( + model_name="analysis", + name="url", + field=models.URLField(blank=True, max_length=255, null=True), + ), + migrations.AddField( + model_name="coverage", + name="analysis", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="coverages", + to="v1.analysis", + ), + ), + migrations.AddField( + model_name="observationlevel", + name="analysis", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="observation_levels", + to="v1.analysis", + ), + ), + ] diff --git a/basedosdados_api/api/v1/migrations/0011_alter_analysis_options_analysis_datasets_and_more.py b/basedosdados_api/api/v1/migrations/0011_alter_analysis_options_analysis_datasets_and_more.py new file mode 100644 index 00000000..f454978e --- /dev/null +++ b/basedosdados_api/api/v1/migrations/0011_alter_analysis_options_analysis_datasets_and_more.py @@ -0,0 +1,172 @@ +# Generated by Django 4.2.1 on 2023-05-06 19:40 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("v1", "0010_analysis_tags_analysis_themes_analysis_url_and_more"), + ] + + operations = [ + migrations.AlterModelOptions( + name="analysis", + options={ + "ordering": ["name"], + "verbose_name": "Analysis", + "verbose_name_plural": "Analyses", + }, + ), + migrations.AddField( + model_name="analysis", + name="datasets", + field=models.ManyToManyField( + help_text="Datasets used in the analysis", + related_name="analyses", + to="v1.dataset", + ), + ), + migrations.AddField( + model_name="analysis", + name="name", + field=models.CharField(blank=True, max_length=255, null=True), + ), + migrations.AddField( + model_name="analysis", + name="name_en", + field=models.CharField(blank=True, max_length=255, null=True), + ), + migrations.AddField( + model_name="analysis", + name="name_es", + field=models.CharField(blank=True, max_length=255, null=True), + ), + migrations.AddField( + model_name="analysis", + name="name_pt", + field=models.CharField(blank=True, max_length=255, null=True), + ), + migrations.AddField( + model_name="analysis", + name="published_by", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="analyses_published", + to=settings.AUTH_USER_MODEL, + ), + ), + migrations.CreateModel( + name="QualityCheck", + fields=[ + ( + "id", + models.UUIDField( + default=uuid.uuid4, primary_key=True, serialize=False + ), + ), + ("name", models.CharField(blank=True, max_length=255, null=True)), + ("name_pt", models.CharField(blank=True, max_length=255, null=True)), + ("name_en", models.CharField(blank=True, max_length=255, null=True)), + ("name_es", models.CharField(blank=True, max_length=255, null=True)), + ("description", models.CharField(max_length=255)), + ("description_pt", models.CharField(max_length=255, null=True)), + ("description_en", models.CharField(max_length=255, null=True)), + ("description_es", models.CharField(max_length=255, null=True)), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ( + "analysis", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="quality_checks", + to="v1.analysis", + ), + ), + ( + "column", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="quality_checks", + to="v1.column", + ), + ), + ( + "dataset", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="quality_checks", + to="v1.dataset", + ), + ), + ( + "information_request", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="quality_checks", + to="v1.informationrequest", + ), + ), + ( + "key", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="quality_checks", + to="v1.key", + ), + ), + ( + "pipeline", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="quality_checks", + to="v1.pipeline", + ), + ), + ( + "raw_data_source", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="quality_checks", + to="v1.rawdatasource", + ), + ), + ( + "table", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="quality_checks", + to="v1.table", + ), + ), + ], + options={ + "verbose_name": "Quality Check", + "verbose_name_plural": "Quality Checks", + "db_table": "quality_check", + "ordering": ["id"], + }, + ), + ] diff --git a/basedosdados_api/api/v1/migrations/0012_analysis_description_analysis_description_en_and_more.py b/basedosdados_api/api/v1/migrations/0012_analysis_description_analysis_description_en_and_more.py new file mode 100644 index 00000000..6d96df06 --- /dev/null +++ b/basedosdados_api/api/v1/migrations/0012_analysis_description_analysis_description_en_and_more.py @@ -0,0 +1,53 @@ +# Generated by Django 4.2.1 on 2023-05-06 19:47 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("v1", "0011_alter_analysis_options_analysis_datasets_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="analysis", + name="description", + field=models.TextField(blank=True, null=True), + ), + migrations.AddField( + model_name="analysis", + name="description_en", + field=models.TextField(blank=True, null=True), + ), + migrations.AddField( + model_name="analysis", + name="description_es", + field=models.TextField(blank=True, null=True), + ), + migrations.AddField( + model_name="analysis", + name="description_pt", + field=models.TextField(blank=True, null=True), + ), + migrations.AlterField( + model_name="qualitycheck", + name="description", + field=models.TextField(blank=True, null=True), + ), + migrations.AlterField( + model_name="qualitycheck", + name="description_en", + field=models.TextField(blank=True, null=True), + ), + migrations.AlterField( + model_name="qualitycheck", + name="description_es", + field=models.TextField(blank=True, null=True), + ), + migrations.AlterField( + model_name="qualitycheck", + name="description_pt", + field=models.TextField(blank=True, null=True), + ), + ] diff --git a/basedosdados_api/api/v1/migrations/0013_remove_analysis_published_by_analysis_authors_and_more.py b/basedosdados_api/api/v1/migrations/0013_remove_analysis_published_by_analysis_authors_and_more.py new file mode 100644 index 00000000..ca7c4e2c --- /dev/null +++ b/basedosdados_api/api/v1/migrations/0013_remove_analysis_published_by_analysis_authors_and_more.py @@ -0,0 +1,36 @@ +# Generated by Django 4.2.1 on 2023-05-06 19:51 + +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("v1", "0012_analysis_description_analysis_description_en_and_more"), + ] + + operations = [ + migrations.RemoveField( + model_name="analysis", + name="published_by", + ), + migrations.AddField( + model_name="analysis", + name="authors", + field=models.ManyToManyField( + blank=True, + help_text="People who performed and/or wrote the analysis", + related_name="analyses", + to=settings.AUTH_USER_MODEL, + ), + ), + migrations.AddField( + model_name="qualitycheck", + name="passed", + field=models.BooleanField( + default=False, help_text="Passed the quality check" + ), + ), + ] diff --git a/basedosdados_api/api/v1/models.py b/basedosdados_api/api/v1/models.py index 08b5c5a0..208b9d3f 100644 --- a/basedosdados_api/api/v1/models.py +++ b/basedosdados_api/api/v1/models.py @@ -86,7 +86,18 @@ class Coverage(BdmModel): related_name="coverages", ) key = models.ForeignKey( - "Key", blank=True, null=True, on_delete=models.CASCADE, related_name="coverages" + "Key", + blank=True, + null=True, + on_delete=models.CASCADE, + related_name="coverages", + ) + analysis = models.ForeignKey( + "Analysis", + blank=True, + null=True, + on_delete=models.CASCADE, + related_name="coverages", ) area = models.ForeignKey("Area", on_delete=models.CASCADE, related_name="coverages") @@ -109,6 +120,8 @@ def __str__(self): return f"Column: {self.column} - {self.area}" if self.coverage_type() == "key": return f"Key: {self.key} - {self.area}" + if self.coverage_type() == "analysis": + return f"Key: {self.key} - {self.area}" return str(self.id) @@ -128,6 +141,9 @@ def coverage_type(self): if self.key: return "key" + if self.analysis: + return "analysis" + coverage_type.short_description = "Coverage Type" def clean(self) -> None: @@ -144,9 +160,11 @@ def clean(self) -> None: count += 1 if self.key: count += 1 + if self.analysis: + count += 1 if count != 1: raise ValidationError( - "One and only one of 'table', 'raw_data_source', 'information_request', 'column' or 'key' must be set." # noqa + "One and only one of 'table', 'raw_data_source', 'information_request', 'column', 'key', 'analysis' must be set." # noqa ) @@ -204,11 +222,53 @@ class Meta: ordering = ["github_url"] +class Analysis(BdmModel): + id = models.UUIDField(primary_key=True, default=uuid4) + name = models.CharField(null=True, blank=True, max_length=255) + description = models.TextField(null=True, blank=True) + analysis_type = models.ForeignKey( + "AnalysisType", on_delete=models.CASCADE, related_name="analyses" + ) + datasets = models.ManyToManyField( + "Dataset", + related_name="analyses", + help_text="Datasets used in the analysis", + ) + themes = models.ManyToManyField( + "Theme", + related_name="analyses", + help_text="Themes are used to group analyses by topic", + ) + tags = models.ManyToManyField( + "Tag", + related_name="analyses", + blank=True, + help_text="Tags are used to group analyses by topic", + ) + authors = models.ManyToManyField( + Account, + related_name="analyses", + blank=True, + help_text="People who performed and/or wrote the analysis", + ) + url = models.URLField(blank=True, null=True, max_length=255) + + graphql_nested_filter_fields_whitelist = ["id"] + + def __str__(self): + return str(self.name) + + class Meta: + db_table = "analysis" + verbose_name = "Analysis" + verbose_name_plural = "Analyses" + ordering = ["name"] + + class AnalysisType(BdmModel): id = models.UUIDField(primary_key=True, default=uuid4) slug = models.SlugField(unique=True) name = models.CharField(max_length=255) - tag = models.CharField(max_length=255) graphql_nested_filter_fields_whitelist = ["id"] @@ -866,6 +926,13 @@ class ObservationLevel(BdmModel): on_delete=models.CASCADE, related_name="observation_levels", ) + analysis = models.ForeignKey( + "Analysis", + blank=True, + null=True, + on_delete=models.CASCADE, + related_name="observation_levels", + ) graphql_nested_filter_fields_whitelist = ["id"] @@ -887,9 +954,11 @@ def clean(self) -> None: count += 1 if self.information_request: count += 1 + if self.analysis: + count += 1 if count != 1: raise ValidationError( - "One and only one of 'table', 'raw_data_source', 'information_request' must be set." # noqa + "One and only one of 'table', 'raw_data_source', 'information_request', 'analysis' must be set." # noqa ) return super().clean() @@ -936,14 +1005,12 @@ def __str__(self): return f"{start_year}{start_month}{start_day}{start_hour}{start_minute}{start_second}{interval}\ {end_year}{end_month}{end_day}{end_hour}{end_minute}{end_second}" - class Meta: db_table = "datetime_range" verbose_name = "DateTime Range" verbose_name_plural = "DateTime Ranges" ordering = ["id"] - def clean(self) -> None: errors = {} @@ -1018,3 +1085,103 @@ def clean(self) -> None: raise ValidationError(errors) return super().clean() + +class QualityCheck(BdmModel): + id = models.UUIDField(primary_key=True, default=uuid4) + name = models.CharField(null=True, blank=True, max_length=255) + description = models.TextField(null=True, blank=True) + passed = models.BooleanField( + default=False, help_text="Passed the quality check" + ) + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + pipeline = models.ForeignKey( + "Pipeline", + on_delete=models.CASCADE, + related_name="quality_checks", + blank=True, + null=True, + ) + analysis = models.ForeignKey( + "Analysis", + blank=True, + null=True, + on_delete=models.CASCADE, + related_name="quality_checks", + ) + dataset = models.ForeignKey( + "Dataset", + blank=True, + null=True, + on_delete=models.CASCADE, + related_name="quality_checks", + ) + table = models.ForeignKey( + "Table", + blank=True, + null=True, + on_delete=models.CASCADE, + related_name="quality_checks", + ) + column = models.ForeignKey( + "Column", + blank=True, + null=True, + on_delete=models.CASCADE, + related_name="quality_checks", + ) + key = models.ForeignKey( + "Key", + blank=True, + null=True, + on_delete=models.CASCADE, + related_name="quality_checks", + ) + raw_data_source = models.ForeignKey( + "RawDataSource", + blank=True, + null=True, + on_delete=models.CASCADE, + related_name="quality_checks", + ) + information_request = models.ForeignKey( + "InformationRequest", + blank=True, + null=True, + on_delete=models.CASCADE, + related_name="quality_checks", + ) + + graphql_nested_filter_fields_whitelist = ["id"] + + def __str__(self): + return str(self.name) + + class Meta: + db_table = "quality_check" + verbose_name = "Quality Check" + verbose_name_plural = "Quality Checks" + ordering = ["id"] + + def clean(self) -> None: + count = 0 + if self.analysis: + count += 1 + if self.dataset: + count += 1 + if self.table: + count += 1 + if self.column: + count += 1 + if self.key: + count += 1 + if self.raw_data_source: + count += 1 + if self.information_request: + count += 1 + if count != 1: + raise ValidationError( + "One and only one of 'analysis', 'dataset, 'table', 'column', 'key, 'raw_data_source', 'information_request' must be set." # noqa + ) + return super().clean() + \ No newline at end of file diff --git a/basedosdados_api/api/v1/tests/test_models.py b/basedosdados_api/api/v1/tests/test_models.py index fa9e7e7d..246f7da6 100644 --- a/basedosdados_api/api/v1/tests/test_models.py +++ b/basedosdados_api/api/v1/tests/test_models.py @@ -12,6 +12,7 @@ RawDataSource, InformationRequest, DateTimeRange, + Analysis, ) @@ -79,12 +80,10 @@ def test_create_dataset( @pytest.mark.django_db -def test_create_table(tabela_bairros, observation_level_anual): +def test_create_table(tabela_bairros): """Test for Table.""" tabela_bairros.save() - tabela_bairros.observation_level.add(observation_level_anual) assert Table.objects.exists() - assert len(tabela_bairros.observation_level.all()) == 1 @pytest.mark.django_db @@ -106,8 +105,6 @@ def test_columns_create( def test_create_rawdatasource(raw_data_source, entity_escola, entity_anual): """Test for RawDataSource.""" raw_data_source.save() - raw_data_source.entities.add(entity_escola, entity_anual) - assert raw_data_source.entities.count() == 2 assert RawDataSource.objects.exists() @@ -115,7 +112,25 @@ def test_create_rawdatasource(raw_data_source, entity_escola, entity_anual): def test_create_information_request(pedido_informacao, entity_escola, entity_anual): """Test for InformationRequest.""" pedido_informacao.save() - pedido_informacao.entities.add(entity_escola, entity_anual) - assert pedido_informacao.entities.count() == 2 assert InformationRequest.objects.exists() + + +@pytest.mark.django_db +def test_create_analysis( + analise_bairros, + dataset_dados_mestres, + tema_saude, + tema_educacao, + tag_aborto, + tag_covid, + usuario_inicio, +): + """Test for Analysis.""" + analise_bairros.datasets.add(dataset_dados_mestres) + analise_bairros.themes.add(tema_saude, tema_educacao) + analise_bairros.tags.add(tag_aborto, tag_covid) + analise_bairros.authors.add(usuario_inicio) + analise_bairros.save() + + assert Analysis.objects.exists() diff --git a/basedosdados_api/api/v1/translation.py b/basedosdados_api/api/v1/translation.py index a9f54b6d..479ca9e4 100644 --- a/basedosdados_api/api/v1/translation.py +++ b/basedosdados_api/api/v1/translation.py @@ -2,11 +2,14 @@ from modeltranslation.translator import translator, TranslationOptions from .models import ( + Analysis, AnalysisType, + Area, Availability, Column, Dataset, Entity, + EntityCategory, InformationRequest, Language, License, @@ -16,14 +19,20 @@ Table, Tag, Theme, - Area, EntityCategory, + QualityCheck, ) +class AnalysisTranslationOptions(TranslationOptions): + fields = ( + "name", + "description", + ) + + class AnalysisTypeTranslationOptions(TranslationOptions): fields = ( "name", - "tag", ) @@ -67,6 +76,13 @@ class OrganizationTranslationOptions(TranslationOptions): fields = ("name", "description") +class QualityCheckTranslationOptions(TranslationOptions): + fields = ( + "name", + "description", + ) + + class RawDataSourceTranslationOptions(TranslationOptions): fields = ( "name", @@ -93,6 +109,7 @@ class ThemeTranslationOptions(TranslationOptions): fields = ("name",) +translator.register(Analysis, AnalysisTranslationOptions) translator.register(AnalysisType, AnalysisTypeTranslationOptions) translator.register(Area, AreaTranslationOptions) translator.register(Availability, AvailabilityTranslationOptions) @@ -104,6 +121,7 @@ class ThemeTranslationOptions(TranslationOptions): translator.register(Language, LanguageTranslationOptions) translator.register(License, LicenseTranslationOptions) translator.register(Organization, OrganizationTranslationOptions) +translator.register(QualityCheck, QualityCheckTranslationOptions) translator.register(RawDataSource, RawDataSourceTranslationOptions) translator.register(Status, StatusTranslationOptions) translator.register(Table, TableTranslationOptions) diff --git a/basedosdados_api/conftest.py b/basedosdados_api/conftest.py index 56cfec66..06396b1f 100644 --- a/basedosdados_api/conftest.py +++ b/basedosdados_api/conftest.py @@ -2,14 +2,13 @@ import pytest import uuid -from django.contrib.auth.models import User from basedosdados_api.account.models import Account # from django.core.exceptions import ValidationError from basedosdados_api.api.v1.models import ( - # AnalysisType, + AnalysisType, Table, Dataset, Organization, @@ -26,7 +25,12 @@ Availability, InformationRequest, Status, - Coverage, EntityCategory, + Coverage, + EntityCategory, + Analysis, + Dictionary, + Key, + QualityCheck, ) @@ -136,18 +140,15 @@ def fixture_entity_anual(): @pytest.mark.django_db def fixture_entity_escola(): """Fixture for Entity.""" + entity_education = EntityCategory.objects.create( + slug="education", + name="Educação", + ) + return Entity.objects.create( slug="escola", name="Escola", - ) - - -@pytest.fixture(name="frequencia_anual") -def fixture_frequencia_anual(entity_anual): - """Fixture for UpdateFrequency.""" - return UpdateFrequency.objects.create( - entity=entity_anual, - number=1, + category=entity_education, ) @@ -245,16 +246,13 @@ def fixture_tabela_bairros( dataset_dados_mestres, licenca_mit, organizacao_parceira, - frequencia_anual, pipeline, - observation_level_anual, ): """Fixture for Table.""" return Table.objects.create( dataset=dataset_dados_mestres, license=licenca_mit, partner_organization=organizacao_parceira, - update_frequency=frequencia_anual, pipeline=pipeline, slug="bairros", name="Tabela de bairros do Rio de Janeiro", @@ -279,7 +277,6 @@ def fixture_tabela_diretorios_brasil_uf( dataset_dados_mestres, licenca_mit, organizacao_parceira, - frequencia_anual, pipeline, observation_level_anual, ): @@ -288,7 +285,6 @@ def fixture_tabela_diretorios_brasil_uf( dataset=dataset_dados_mestres, license=licenca_mit, partner_organization=organizacao_parceira, - update_frequency=frequencia_anual, pipeline=pipeline, slug="brasil_uf", name="Tabela de estados do Brasil", @@ -391,14 +387,12 @@ def fixture_raw_data_source( dataset_dados_mestres, disponibilidade_online, licenca_mit, - frequencia_anual, ): """Fixture for RawData.""" return RawDataSource.objects.create( dataset=dataset_dados_mestres, availability=disponibilidade_online, license=licenca_mit, - update_frequency=frequencia_anual, name="Fonte de dados", ) @@ -429,13 +423,92 @@ def fixture_pedido_informacao( coluna_nome_bairros, coluna_populacao_bairros, status_em_processamento, - frequencia_anual, usuario_inicio, ): """Fixture for InformationRequest.""" return InformationRequest.objects.create( dataset=dataset_dados_mestres, status=status_em_processamento, - update_frequency=frequencia_anual, started_by=usuario_inicio, ) + + +############################################################################################# +# Analysis fixtures +############################################################################################# + + +@pytest.fixture(name="analise_tipo1") +@pytest.mark.django_db +def fixture_analise_tipo1(): + return AnalysisType.objects.create( + name="Análise tipo 1", + slug="analise-tipo-1", + ) + + +@pytest.fixture(name="analise_bairros") +@pytest.mark.django_db +def fixture_analise_bairros( + analise_tipo1, + dataset_dados_mestres, + tema_saude, + tema_educacao, + tag_aborto, + tag_covid, +): + """Fixture for Analysis.""" + analysis = Analysis.objects.create( + name="Análise de bairros", + description="Descrição da análise de bairros", + analysis_type=analise_tipo1, + url="https://analise.com/bairros", + ) + return analysis + + +@pytest.fixture(name="dicionario_1") +@pytest.mark.django_db +def test_dictionary( + coluna_nome_bairros, +): + """Fixture for Dictionary.""" + return Dictionary.objects.create( + column=coluna_nome_bairros, + ) + + +@pytest.fixture(name="chave_1") +@pytest.mark.django_db +def fixture_chave_1(dicionario_1): + chave = Key.objects.create(dictionary=dicionario_1, name="Chave 1", value="Valor 1") + + return chave + + +@pytest.fixture(name="teste_qualidade") +@pytest.mark.django_db +def fixture_teste_qualidade( + pipeline, + analise_bairros, + dataset_dados_mestres, + tabela_bairros, + coluna_nome_bairros, + chave_1, + raw_data_source, + pedido_informacao, +): + teste_qualidade = QualityCheck.objects.create( + name="Teste de qualidade", + description="Descrição do teste de qualidade", + passed=True, + pipeline=pipeline, + analysis=analise_bairros, + dataset=dataset_dados_mestres, + table=tabela_bairros, + column=coluna_nome_bairros, + key=chave_1, + raw_data_source=raw_data_source, + information_request=pedido_informacao, + ) + return teste_qualidade