Skip to content

Commit

Permalink
[Backport to 3.2.x][Fixes: #6925] Thesauri improvements (#7055)
Browse files Browse the repository at this point in the history
* [Fixes: #7033] Mandatory fields in editor

* [Fixes #6925] Add new thesaurus behaviour for documents and maps

* [Fixes #6925] Facet endpoint changed to serve default label if translated one does not exists

* [Fixes #6925] Facet endpoint changed to serve default label if translated one does not exists
  • Loading branch information
mattiagiupponi authored Mar 10, 2021
1 parent de25c1d commit caebde3
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 14 deletions.
34 changes: 21 additions & 13 deletions geonode/api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
from guardian.shortcuts import get_objects_for_user
from tastypie.bundle import Bundle

from geonode.base.models import ResourceBase
from geonode.base.models import ResourceBase, ThesaurusKeyword
from geonode.base.models import TopicCategory
from geonode.base.models import Region
from geonode.base.models import HierarchicalKeyword
Expand Down Expand Up @@ -201,12 +201,10 @@ def build_filters(self, filters={}, ignore_bad_filters=False):
orm_filters = super(ThesaurusKeywordResource, self).build_filters(_filters)

if id is not None:
orm_filters['keyword__id'] = id

orm_filters['lang'] = _filters['lang'] if 'lang' in _filters else get_language()
orm_filters['id__in'] = id

if 'thesaurus' in _filters:
orm_filters['keyword__thesaurus__identifier'] = _filters['thesaurus']
orm_filters['thesaurus__identifier'] = _filters['thesaurus']

return orm_filters

Expand All @@ -216,27 +214,37 @@ def serialize(self, request, data, format, options={}):
return super(ThesaurusKeywordResource, self).serialize(request, data, format, options)

def dehydrate_id(self, bundle):
return bundle.obj.keyword.id
return bundle.obj.id

def dehydrate_label_id(self, bundle):
return bundle.obj.id

def dehydrate_thesaurus_identifier(self, bundle):
return bundle.obj.keyword.thesaurus.identifier
return bundle.obj.thesaurus.identifier

def dehydrate(self, bundle):
lang = get_language()
label = ThesaurusKeywordLabel.objects.filter(keyword=bundle.data['id']).filter(lang=lang)
if label.exists():
bundle.data['label_id'] = label.get().id
bundle.data['label'] = label.get().label
bundle.data['alt_label'] = label.get().label
else:
bundle.data['label'] = bundle.data['alt_label']

return bundle

class Meta:
queryset = ThesaurusKeywordLabel.objects \
queryset = ThesaurusKeyword.objects \
.all() \
.order_by('label') \
.select_related('keyword') \
.select_related('keyword__thesaurus')
.order_by('alt_label') \
.select_related('thesaurus')

resource_name = 'thesaurus/keywords'
allowed_methods = ['get']
filtering = {
'id': ALL,
'label': ALL,
'lang': ALL,
'alt_label': ALL,
'thesaurus': ALL,
}
serializer = CountJSONSerializer()
Expand Down
79 changes: 79 additions & 0 deletions geonode/api/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#########################################################################
from unittest.case import TestCase
from unittest.mock import patch
from django.conf import settings

from datetime import datetime, timedelta
Expand Down Expand Up @@ -526,3 +528,80 @@ def test_tags_lockdown(self):
resp = self.api_client.get(filter_url)
self.assertValidJSONResponse(resp)
self.assertEqual(len(self.deserialize(resp)['objects']), 5)


class ThesaurusKeywordResourceTests(ResourceTestCaseMixin, TestCase):
# loading test thesausurs
fixtures = ["test_thesaurus.json"]

def setUp(self):
super(ThesaurusKeywordResourceTests, self).setUp()

self.list_url = reverse("api_dispatch_list", kwargs={"api_name": "api", "resource_name": "thesaurus/keywords"})

def test_api_will_return_a_valid_json_response(self):
resp = self.api_client.get(self.list_url)
self.assertValidJSONResponse(resp)

def test_will_return_empty_if_the_thesaurus_does_not_exists(self):
url = f"{self.list_url}?thesaurus=invalid-identifier"
resp = self.api_client.get(url)
self.assertValidJSONResponse(resp)
self.assertEqual(resp.json()["meta"]["total_count"], 0)

def test_will_return_keywords_for_the_selected_thesaurus_if_exists(self):
url = f"{self.list_url}?thesaurus=inspire-theme"
resp = self.api_client.get(url)
self.assertValidJSONResponse(resp)
self.assertEqual(resp.json()["meta"]["total_count"], 34)

def test_will_return_empty_if_the_alt_label_does_not_exists(self):
url = f"{self.list_url}?alt_label=invalid-alt_label"
resp = self.api_client.get(url)
self.assertValidJSONResponse(resp)
self.assertEqual(resp.json()["meta"]["total_count"], 0)

def test_will_return_keywords_for_the_selected_alt_label_if_exists(self):
url = f"{self.list_url}?alt_label=ac"
resp = self.api_client.get(url)
self.assertValidJSONResponse(resp)
self.assertEqual(resp.json()["meta"]["total_count"], 1)

def test_will_return_empty_if_the_kaywordId_does_not_exists(self):
url = f"{self.list_url}?id=12365478954862"
resp = self.api_client.get(url)
print(self.deserialize(resp))
self.assertValidJSONResponse(resp)
self.assertEqual(resp.json()["meta"]["total_count"], 0)

@patch("geonode.api.api.get_language")
def test_will_return_expected_keyword_label_for_existing_lang(self, lang):
lang.return_value = "de"
url = f"{self.list_url}?thesaurus=inspire-theme"
resp = self.api_client.get(url)
# the german translations exists, for the other labels, the alt_label will be used
expected_labels = [
"ac", "Adressen", "af", "am", "au", "br", "bu",
"cp", "ef", "el", "er", "ge", "gg", "gn", "hb", "hh",
"hy", "lc", "lu", "mf", "mr", "nz", "of", "oi", "pd",
"pf", "ps", "rs", "sd", "so", "sr", "su", "tn", "us"
]
actual_labels = [x["alt_label"] for x in self.deserialize(resp)["objects"]]
self.assertValidJSONResponse(resp)
self.assertListEqual(expected_labels, actual_labels)

@patch("geonode.api.api.get_language")
def test_will_return_default_keyword_label_for_not_existing_lang(self, lang):
lang.return_value = "ke"
url = f"{self.list_url}?thesaurus=inspire-theme"
resp = self.api_client.get(url)
# no translations exists, the alt_label will be used for all keywords
expected_labels = [
"ac", "ad", "af", "am", "au", "br", "bu",
"cp", "ef", "el", "er", "ge", "gg", "gn", "hb", "hh",
"hy", "lc", "lu", "mf", "mr", "nz", "of", "oi", "pd",
"pf", "ps", "rs", "sd", "so", "sr", "su", "tn", "us"
]
actual_labels = [x["alt_label"] for x in self.deserialize(resp)["objects"]]
self.assertValidJSONResponse(resp)
self.assertListEqual(expected_labels, actual_labels)
2 changes: 1 addition & 1 deletion geonode/templates/search/_t_keywords_filter.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
{% for tname in THESAURI_FILTERS %}

<nav class="filter">
<h4><a href="#" class="toggle toggle-nav"><i class="fa fa-chevron-right"></i> {% trans "Thesaurus" %}: {{ tname|get_name_translation }}</a></h4>
<h4><a href="#" class="toggle toggle-nav"><i class="fa fa-chevron-right"></i>{{ tname|get_name_translation }}</a></h4>
<ul class="nav closed" id="tkeywords_{{ tname }}">
<li ng-repeat="tk in tkeywords" ng-if="tk.count > 0 && tk.thesaurus_identifier == '{{ tname }}'">
{% verbatim %}
Expand Down

0 comments on commit caebde3

Please sign in to comment.