From 7e1cc07cbb625c931cca1d629953b4d87a2f4184 Mon Sep 17 00:00:00 2001 From: Pauliina Ilmanen Date: Mon, 23 Oct 2023 10:31:37 +0300 Subject: [PATCH 1/4] Fix service search results order Fix a bug in `services_qs` ordering in search api and add tests for it. --- services/search/api.py | 2 +- services/search/tests/conftest.py | 35 ++++++++++++++++++++++++++++++- services/search/tests/test_api.py | 20 ++++++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/services/search/api.py b/services/search/api.py index e31f1678a..eac67b522 100644 --- a/services/search/api.py +++ b/services/search/api.py @@ -362,7 +362,7 @@ def get(self, request): ) services_qs = services_qs.annotate(num_units=Count("units")).order_by( - "-units__count" + "-num_units" ) # order_by() call makes duplicate rows appear distinct. This is solved by # fetching the ids and filtering a new queryset using them diff --git a/services/search/tests/conftest.py b/services/search/tests/conftest.py index 1eb44cca9..07bcbc16b 100644 --- a/services/search/tests/conftest.py +++ b/services/search/tests/conftest.py @@ -85,11 +85,34 @@ def units( ) unit.services.add(3) unit.save() + + unit = Unit.objects.create( + id=4, + name="Jäähalli", + last_modified_time=now(), + municipality=municipality, + department=department, + ) + # Add service Halli + unit.services.add(4) + unit.save() + + unit = Unit.objects.create( + id=5, + name="Palloiluhalli", + last_modified_time=now(), + municipality=municipality, + department=department, + ) + # Add service Halli + unit.services.add(4) + unit.save() + update_service_root_service_nodes() update_service_counts() update_service_node_counts() Unit.objects.update(search_column_fi=get_search_column(Unit, "fi")) - return Unit.objects.all() + return Unit.objects.all().order_by("id") @pytest.mark.django_db @@ -132,6 +155,16 @@ def services(): name_sv="Simhall", last_modified_time=now(), ) + Service.objects.create( + id=4, + name="Halli", + last_modified_time=now(), + ) + Service.objects.create( + id=5, + name="Hallinto", + last_modified_time=now(), + ) Service.objects.update(search_column_fi=get_search_column(Service, "fi")) return Service.objects.all() diff --git a/services/search/tests/test_api.py b/services/search/tests/test_api.py index efd6688ca..7b5637f9f 100644 --- a/services/search/tests/test_api.py +++ b/services/search/tests/test_api.py @@ -133,3 +133,23 @@ def test_search( results = response.json()["results"] assert results[0]["object_type"] == "administrativedivision" assert results[0]["name"]["fi"] == "Helsinki" + + +@pytest.mark.django_db +def test_search_service_order(api_client, units, services): + """ + Test that services are ordered descending by unit count. + """ + url = reverse("search") + "?q=halli&type=service" + response = api_client.get(url) + results = response.json()["results"] + assert len(results) == 3 + + assert results[0]["name"]["fi"] == "Halli" + assert results[0]["unit_count"]["total"] == 2 + + assert results[1]["name"]["fi"] == "Uimahalli" + assert results[1]["unit_count"]["total"] == 1 + + assert results[2]["name"]["fi"] == "Hallinto" + assert results[2]["unit_count"]["total"] == 0 From 65dc891205184d7984a979908eeab91d66603ea2 Mon Sep 17 00:00:00 2001 From: Pauliina Ilmanen Date: Mon, 23 Oct 2023 10:43:21 +0300 Subject: [PATCH 2/4] Upgrade requirements --- requirements-dev.txt | 24 +++++----- requirements.txt | 110 ++++++++++++++++++++++++------------------- 2 files changed, 73 insertions(+), 61 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 83472a561..d02cbb27c 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,22 +1,20 @@ # -# This file is autogenerated by pip-compile with Python 3.10 +# This file is autogenerated by pip-compile with Python 3.8 # by the following command: # # pip-compile requirements-dev.in # -appnope==0.1.3 - # via ipython -asttokens==2.2.1 +asttokens==2.4.0 # via stack-data backcall==0.2.0 # via ipython decorator==5.1.1 # via ipython -executing==1.2.0 +executing==2.0.0 # via stack-data -ipython==8.11.0 +ipython==8.12.3 # via -r requirements-dev.in -jedi==0.18.2 +jedi==0.19.1 # via ipython matplotlib-inline==0.1.6 # via ipython @@ -26,21 +24,23 @@ pexpect==4.8.0 # via ipython pickleshare==0.7.5 # via ipython -prompt-toolkit==3.0.38 +prompt-toolkit==3.0.39 # via ipython ptyprocess==0.7.0 # via pexpect pure-eval==0.2.2 # via stack-data -pygments==2.14.0 +pygments==2.16.1 # via ipython six==1.16.0 # via asttokens -stack-data==0.6.2 +stack-data==0.6.3 # via ipython -traitlets==5.9.0 +traitlets==5.11.2 # via # ipython # matplotlib-inline -wcwidth==0.2.6 +typing-extensions==4.8.0 + # via ipython +wcwidth==0.2.8 # via prompt-toolkit diff --git a/requirements.txt b/requirements.txt index d18b600bf..e81c70670 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,37 +1,40 @@ # -# This file is autogenerated by pip-compile with Python 3.10 +# This file is autogenerated by pip-compile with Python 3.8 # by the following command: # # pip-compile requirements.in # -asgiref==3.6.0 +asgiref==3.7.2 # via django -attrs==22.2.0 +attrs==23.1.0 # via # cattrs - # pytest # requests-cache -black==23.1.0 +backports-zoneinfo==0.2.1 + # via django +black==23.10.0 # via -r requirements.in -bmi-arcgis-restapi==2.3.1 +bmi-arcgis-restapi==2.4.5 # via -r requirements.in -build==0.10.0 +build==1.0.3 # via pip-tools -cattrs==22.2.0 +cattrs==23.1.2 # via requests-cache -certifi==2022.12.7 +certifi==2023.7.22 # via # requests # sentry-sdk -charset-normalizer==3.1.0 +charset-normalizer==3.3.0 # via requests -click==8.1.3 +click==8.1.7 # via # black # pip-tools -coverage[toml]==7.2.2 - # via pytest-cov -django==4.1.7 +coverage[toml]==7.3.2 + # via + # coverage + # pytest-cov +django==4.2.6 # via # -r requirements.in # django-cors-headers @@ -42,17 +45,17 @@ django==4.1.7 # django-munigeo # django-polymorphic # djangorestframework -django-cors-headers==3.14.0 +django-cors-headers==4.3.0 # via -r requirements.in -django-environ==0.10.0 +django-environ==0.11.2 # via -r requirements.in -django-extensions==3.2.1 +django-extensions==3.2.3 # via -r requirements.in -django-filter==22.1 +django-filter==23.3 # via -r requirements.in -django-js-asset==2.0.0 +django-js-asset==2.1.0 # via django-mptt -django-modeltranslation==0.18.9 +django-modeltranslation==0.18.11 # via # -r requirements.in # django-munigeo @@ -68,33 +71,35 @@ djangorestframework==3.14.0 # via -r requirements.in djangorestframework-jsonp==1.0.2 # via -r requirements.in -exceptiongroup==1.1.1 +exceptiongroup==1.1.3 # via # cattrs # pytest -flake8==6.0.0 +flake8==6.1.0 # via # -r requirements.in # pep8-naming idna==3.4 # via requests +importlib-metadata==6.8.0 + # via build iniconfig==2.0.0 # via pytest isort==5.12.0 # via -r requirements.in -jedi==0.18.2 +jedi==0.19.1 # via -r requirements.in libvoikko==4.3 # via -r requirements.in -lxml==4.9.2 +lxml==4.9.3 # via -r requirements.in mccabe==0.7.0 # via flake8 -munch==2.5.0 +munch==4.0.0 # via bmi-arcgis-restapi mypy-extensions==1.0.0 # via black -packaging==23.0 +packaging==23.2 # via # black # build @@ -103,86 +108,93 @@ parso==0.8.3 # via # -r requirements.in # jedi -pathspec==0.11.1 +pathspec==0.11.2 # via black pep8-naming==0.13.3 # via -r requirements.in -pip-tools==6.12.3 +pip-tools==7.3.0 # via -r requirements.in -platformdirs==3.1.1 +platformdirs==3.11.0 # via # black # requests-cache -pluggy==1.0.0 +pluggy==1.3.0 # via pytest -psycopg2==2.9.6 +psycopg2==2.9.9 # via -r requirements.in -pycodestyle==2.10.0 +pycodestyle==2.11.1 # via flake8 -pyflakes==3.0.1 +pyflakes==3.1.0 # via flake8 pyproject-hooks==1.0.0 # via build -pytest==7.2.2 +pytest==7.4.2 # via # pytest-cov # pytest-django -pytest-cov==4.0.0 +pytest-cov==4.1.0 # via -r requirements.in pytest-django==4.5.2 # via -r requirements.in python-dateutil==2.8.2 # via -r requirements.in -pytz==2022.7.1 +pytz==2023.3.post1 # via # -r requirements.in # djangorestframework -pyyaml==6.0 +pyyaml==6.0.1 # via django-munigeo -requests==2.28.2 +requests==2.31.0 # via # -r requirements.in # bmi-arcgis-restapi # django-munigeo # requests-cache # requests-mock -requests-cache==1.0.0 +requests-cache==1.1.0 # via -r requirements.in -requests-mock==1.10.0 +requests-mock==1.11.0 # via -r requirements.in -sentry-sdk==1.17.0 +sentry-sdk==1.32.0 # via -r requirements.in six==1.16.0 # via # django-munigeo - # munch # python-dateutil # requests-mock # url-normalize -sqlparse==0.4.3 +sqlparse==0.4.4 # via django tomli==2.0.1 # via # black # build # coverage + # pip-tools + # pyproject-hooks # pytest -tqdm==4.65.0 +tqdm==4.66.1 # via -r requirements.in -typing-extensions==4.5.0 - # via django-modeltranslation +typing-extensions==4.8.0 + # via + # asgiref + # black + # cattrs + # django-modeltranslation url-normalize==1.4.3 # via requests-cache -urllib3==1.26.15 +urllib3==2.0.7 # via # bmi-arcgis-restapi # requests # requests-cache # sentry-sdk -wheel==0.40.0 +wheel==0.41.2 # via pip-tools -whitenoise==6.4.0 +whitenoise==6.6.0 # via -r requirements.in +zipp==3.17.0 + # via importlib-metadata # The following packages are considered to be unsafe in a requirements file: # pip From 2166e5a72c58634082e76e9c6de422c2df4d69d2 Mon Sep 17 00:00:00 2001 From: Pauliina Ilmanen Date: Tue, 24 Oct 2023 10:22:01 +0300 Subject: [PATCH 3/4] Change CI configuration Python version to 3.8 Change CI configuration Python version to match the Dockerized environment Python version. --- .github/workflows/ci.yml | 2 +- sonar-project.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5280b8805..24207e8dd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python: [ "3.10" ] + python: [ "3.8" ] env: DATABASE_URL: postgis://postgres:postgres@localhost/smbackend SECRET_KEY: test-secret diff --git a/sonar-project.properties b/sonar-project.properties index d8375327f..787569695 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -3,7 +3,7 @@ sonar.organization=city-of-helsinki sonar.projectName=smbackend sonar.projectVersion=1.0 sonar.sourceEncoding=UTF-8 -sonar.python.version=3.10 +sonar.python.version=3.8 sonar.python.coverage.reportPaths=coverage.xml sonar.test.inclusions=**/tests/**/* sonar.exclusions=**/tests/**/* From dce98a7311717f72b80bf58188581ef08a6495e2 Mon Sep 17 00:00:00 2001 From: Pauliina Ilmanen Date: Tue, 24 Oct 2023 10:53:19 +0300 Subject: [PATCH 4/4] Refactor code to use 'isinstance' for string type check This change was prompted by Flake8 check. --- observations/serializers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/observations/serializers.py b/observations/serializers.py index 37ee9b4b9..3da6d2553 100644 --- a/observations/serializers.py +++ b/observations/serializers.py @@ -87,7 +87,7 @@ def to_internal_value(self, data): if val is None: return result default_language = settings.LANGUAGES[0][0] - if type(val) == str: + if isinstance(val, str): val = {default_language: val} serializer = AllowedValueSerializer( data={"description": val, "property_id": result["property_id"]}