Source code for geonode.geoapps.api.tests

#########################################################################
#
# Copyright (C) 2016 OSGeo
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#########################################################################
import json
import logging
from unittest.mock import MagicMock
from urllib.parse import urljoin

from django.contrib.auth import get_user_model
from django.urls import reverse
from rest_framework.test import APITestCase

from geonode.base.populate_test_data import create_models
from geonode.geoapps.api.exceptions import DuplicateGeoAppException, InvalidGeoAppException
from geonode.geoapps.api.serializers import GeoAppSerializer
from geonode.geoapps.models import GeoApp

[docs] logger = logging.getLogger(__name__)
[docs] class GeoAppsApiTests(APITestCase):
[docs] fixtures = ["initial_data.json", "group_test_data.json", "default_oauth_apps.json"]
[docs] def setUp(self): create_models(b"document") create_models(b"map") create_models(b"dataset") self.admin = get_user_model().objects.get(username="admin") self.bobby = get_user_model().objects.get(username="bobby") self.norman = get_user_model().objects.get(username="norman") self.gep_app = GeoApp.objects.create( title="Test GeoApp", owner=self.bobby, resource_type="geostory", blob='{"test_data": {"test": ["test_1","test_2","test_3"]}}', ) self.gep_app.set_default_permissions()
[docs] def test_geoapps_list(self): """ Ensure we can access the GeoApps list. """ url = reverse("geoapps-list") # Anonymous response = self.client.get(url, format="json") self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 5) self.assertEqual(response.data["total"], 1) # Pagination self.assertEqual(len(response.data["geoapps"]), 1) self.assertTrue("data" not in response.data["geoapps"][0]) response = self.client.get(f"{url}?include[]=data", format="json") self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 5) self.assertEqual(response.data["total"], 1) # Pagination self.assertEqual(len(response.data["geoapps"]), 1) self.assertTrue("data" in response.data["geoapps"][0]) self.assertEqual( json.loads(response.data["geoapps"][0]["data"]), {"test_data": {"test": ["test_1", "test_2", "test_3"]}} )
[docs] def test_extra_metadata_included_with_param(self): _app = GeoApp.objects.first() url = urljoin(f"{reverse('geoapps-list')}/", f"{_app.pk}") data = {"include[]": "metadata"} response = self.client.get(url, format="json", data=data) self.assertIsNotNone(response.data["geoapp"].get("metadata")) response = self.client.get(url, format="json") self.assertNotIn("metadata", response.data["geoapp"])
[docs] def test_geoapps_crud(self): """ Ensure we can create/update GeoApps. """ # Bobby self.assertTrue(self.client.login(username="bobby", password="bob")) # Create url = f"{reverse('geoapps-list')}?include[]=data" data = { "name": "Test Create", "title": "Test Create", "resource_type": "geostory", "owner": "bobby", "extent": {"coords": [1123692.0, 5338214.0, 1339852.0, 5482615.0], "srid": "EPSG:3857"}, } response = self.client.post(url, data=data, format="json") self.assertEqual(response.status_code, 201) # 201 - Created x = GeoApp.objects.filter(title="Test Create").first() self.assertEqual(x.srid, "EPSG:3857") self.assertEqual(response.json()["geoapp"].get("extent")["srid"], "EPSG:4326") self.assertEqual( response.json()["geoapp"].get("extent")["coords"], [10.094296982428332, 43.1721654049465, 12.03609530058109, 44.11086592050112], ) response = self.client.get(url, format="json") self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 5) self.assertEqual(response.data["total"], 2) # Pagination self.assertEqual(len(response.data["geoapps"]), 2) # Update: PATCH url = reverse("geoapps-detail", kwargs={"pk": self.gep_app.pk}) data = {"blob": {"test_data": {"test": ["test_4", "test_5", "test_6"]}}} response = self.client.patch(url, data=json.dumps(data), content_type="application/json") self.assertEqual(response.status_code, 200) response = self.client.get(f"{url}?include[]=data", format="json") self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 1) # Pagination self.assertTrue("data" in response.data["geoapp"]) self.assertEqual(response.data["geoapp"]["resource_type"], "geostory") self.assertEqual(response.data["geoapp"]["data"], {"test_data": {"test": ["test_4", "test_5", "test_6"]}}) # Update: POST data = {"test_data": {"test": ["test_1", "test_2", "test_3"]}} _app = GeoApp.objects.first() _app.set_permissions({"users": {self.bobby: ["base.add_resourcebase", "base.delete_resourcebase"]}}) response = self.client.post(url, data=json.dumps(data), format="json") self.assertEqual(response.status_code, 405) # 405 – Method not allowed # Delete response = self.client.delete(url, format="json") self.assertEqual(response.status_code, 405) # 405 - Method Not Allowed response = self.client.get(f"{url}?include[]=data", format="json") self.assertEqual(response.status_code, 200)
[docs] def test_extra_create_checks_with_no_owner(self): serializer = GeoAppSerializer() data = {"name": "fakename"} with self.assertRaises(InvalidGeoAppException) as exp: serializer.extra_create_checks(data) self.assertEqual(exp.exception.category, "geoapp_api") self.assertEqual(exp.exception.default_code, "geoapp_exception") self.assertEqual(str(exp.exception.detail), "No valid data: 'name' and 'owner' are mandatory fields!")
[docs] def test_extra_create_checks_duplicated(self): serializer = GeoAppSerializer() _geoapp = GeoApp.objects.first() data = {"name": _geoapp.name, "owner": _geoapp.owner} with self.assertRaises(DuplicateGeoAppException) as exp: serializer.extra_create_checks(data) self.assertEqual(exp.exception.category, "geoapp_api") self.assertEqual(exp.exception.default_code, "geoapp_exception") self.assertEqual(str(exp.exception.detail), "A GeoApp with the same 'name' already exists!")
[docs] def test_create_with_no_owner(self): serializer = GeoAppSerializer() data = {"name": "fakename"} with self.assertRaises(InvalidGeoAppException) as exp: serializer.create(data) self.assertEqual(exp.exception.category, "geoapp_api") self.assertEqual(exp.exception.default_code, "geoapp_exception") self.assertEqual( str(exp.exception.detail), "No valid data: ['name', 'owner', 'resource_type'] are mandatory fields!" )
[docs] def test_update_with_no_owner(self): serializer = GeoAppSerializer() data = {"name": "fakename"} _geoapp = MagicMock() _geoapp.resource_type = None with self.assertRaises(InvalidGeoAppException) as exp: serializer.update(_geoapp, data) self.assertEqual(exp.exception.category, "geoapp_api") self.assertEqual(exp.exception.default_code, "geoapp_exception") self.assertEqual(str(exp.exception.detail), "No valid data: ['resource_type'] are mandatory fields!")
[docs] def test_create_checks_duplicated(self): serializer = GeoAppSerializer() _geoapp = GeoApp.objects.first() data = {"name": _geoapp.name, "owner": _geoapp.owner, "resource_type": _geoapp.resource_type} with self.assertRaises(DuplicateGeoAppException) as exp: serializer.create(data) self.assertEqual(exp.exception.category, "geoapp_api") self.assertEqual(exp.exception.default_code, "geoapp_exception") self.assertEqual(str(exp.exception.detail), "A GeoApp with the same 'name' already exists!")